From eb6a2f2b895c2a946815755eddf543a6d3755126 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Fri, 25 Sep 2020 17:24:51 +0300 Subject: [PATCH] Git: Enable Show for file in a specified revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTCREATORBUG-24689 Change-Id: Ic4ceb1c59f39009c28be7f34ee62f65fd41506c1 Reviewed-by: André Hartmann --- src/plugins/git/gitclient.cpp | 49 ++++++++++++++++++++++++++++++++++- src/plugins/git/gitclient.h | 6 ++++- src/plugins/git/giteditor.cpp | 9 ++----- src/plugins/git/gitgrep.cpp | 20 ++------------ src/plugins/git/gitplugin.cpp | 8 +++++- 5 files changed, 64 insertions(+), 28 deletions(-) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 5014f9afe6e..2352c81f126 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -3714,9 +3714,10 @@ QString GitClient::suggestedLocalBranchName( return suggestedName; } -void GitClient::addChangeActions(QMenu *menu, const QString &workingDir, const QString &change) +void GitClient::addChangeActions(QMenu *menu, const QString &source, const QString &change) { QTC_ASSERT(!change.isEmpty(), return); + const QString &workingDir = fileWorkingDirectory(source); menu->addAction(tr("Cherr&y-Pick Change %1").arg(change), [workingDir, change] { m_instance->synchronousCherryPick(workingDir, change); }); @@ -3733,6 +3734,13 @@ void GitClient::addChangeActions(QMenu *menu, const QString &workingDir, const Q QAction *logAction = menu->addAction(tr("&Log for Change %1").arg(change), [workingDir, change] { m_instance->log(workingDir, QString(), false, {change}); }); + const FilePath filePath = FilePath::fromString(source); + if (!filePath.isDir()) { + menu->addAction(tr("Sh&ow file \"%1\" on revision %2").arg(filePath.fileName()).arg(change), + [workingDir, change, source] { + m_instance->openShowEditor(workingDir, change, source); + }); + } if (change.contains("..")) menu->setDefaultAction(logAction); menu->addAction(tr("Add &Tag for Change %1...").arg(change), [workingDir, change] { @@ -3781,6 +3789,45 @@ void GitClient::addChangeActions(QMenu *menu, const QString &workingDir, const Q }); } +QString GitClient::fileWorkingDirectory(const QString &file) +{ + Utils::FilePath path = Utils::FilePath::fromString(file); + if (!path.isEmpty() && !path.isDir()) + path = path.parentDir(); + while (!path.isEmpty() && !path.exists()) + path = path.parentDir(); + return path.toString(); +} + +IEditor *GitClient::openShowEditor(const QString &workingDirectory, const QString &ref, + const QString &path, ShowEditor showSetting) +{ + QString topLevel; + VcsManager::findVersionControlForDirectory(workingDirectory, &topLevel); + const QString relativePath = QDir(topLevel).relativeFilePath(path); + const QByteArray content = synchronousShow(topLevel, ref + ":" + relativePath); + if (showSetting == ShowEditor::OnlyIfDifferent) { + if (content.isEmpty()) + return nullptr; + QByteArray fileContent; + if (TextFileFormat::readFileUTF8(path, nullptr, &fileContent, nullptr) + == TextFileFormat::ReadSuccess) { + if (fileContent == content) + return nullptr; // open the file for read/write + } + } + + const QString documentId = QLatin1String(Git::Constants::GIT_PLUGIN) + + QLatin1String(".GitShow.") + topLevel + + QLatin1String(".") + relativePath; + QString title = tr("Git Show %1:%2").arg(ref).arg(relativePath); + IEditor *editor = EditorManager::openEditorWithContents(Id(), &title, content, documentId, + EditorManager::DoNotSwitchToDesignMode); + editor->document()->setTemporary(true); + VcsBase::setSource(editor->document(), path); + return editor; +} + } // namespace Internal } // namespace Git diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 293f6f4a273..ce4638d38e7 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -366,7 +366,11 @@ public: static QString suggestedLocalBranchName( const QString &workingDirectory, const QStringList &existingLocalNames, const QString &target, BranchTargetType targetType); - static void addChangeActions(QMenu *menu, const QString &workingDir, const QString &change); + static void addChangeActions(QMenu *menu, const QString &source, const QString &change); + static QString fileWorkingDirectory(const QString &file); + enum class ShowEditor { OnlyIfDifferent, Always }; + Core::IEditor *openShowEditor(const QString &workingDirectory, const QString &ref, + const QString &path, ShowEditor showSetting = ShowEditor::Always); private: void finishSubmoduleUpdate(); diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp index 6b25e3afaa6..7a220bae8b8 100644 --- a/src/plugins/git/giteditor.cpp +++ b/src/plugins/git/giteditor.cpp @@ -325,7 +325,7 @@ bool GitEditorWidget::isValidRevision(const QString &revision) const void GitEditorWidget::addChangeActions(QMenu *menu, const QString &change) { if (contentType() != OtherContent) - GitClient::addChangeActions(menu, sourceWorkingDirectory(), change); + GitClient::addChangeActions(menu, source(), change); } QString GitEditorWidget::revisionSubject(const QTextBlock &inBlock) const @@ -364,12 +364,7 @@ QString GitEditorWidget::fileNameForLine(int line) const QString GitEditorWidget::sourceWorkingDirectory() const { - Utils::FilePath path = Utils::FilePath::fromString(source()); - if (!path.isEmpty() && !path.isDir()) - path = path.parentDir(); - while (!path.isEmpty() && !path.exists()) - path = path.parentDir(); - return path.toString(); + return GitClient::fileWorkingDirectory(source()); } void GitEditorWidget::refresh() diff --git a/src/plugins/git/gitgrep.cpp b/src/plugins/git/gitgrep.cpp index 4a47d808993..033915bfa45 100644 --- a/src/plugins/git/gitgrep.cpp +++ b/src/plugins/git/gitgrep.cpp @@ -316,25 +316,9 @@ IEditor *GitGrep::openEditor(const SearchResultItem &item, return nullptr; const QString path = QDir::fromNativeSeparators(item.path.first()); const QString topLevel = parameters.additionalParameters.toString(); - const QString relativePath = QDir(topLevel).relativeFilePath(path); - const QByteArray content = m_client->synchronousShow(topLevel, params.ref + ":./" + relativePath); - if (content.isEmpty()) - return nullptr; - QByteArray fileContent; - if (TextFileFormat::readFileUTF8(path, nullptr, &fileContent, nullptr) - == TextFileFormat::ReadSuccess) { - if (fileContent == content) - return nullptr; // open the file for read/write - } - - const QString documentId = QLatin1String(Git::Constants::GIT_PLUGIN) - + QLatin1String(".GitShow.") + params.id() - + QLatin1String(".") + relativePath; - QString title = tr("Git Show %1:%2").arg(params.ref).arg(relativePath); - IEditor *editor = EditorManager::openEditorWithContents(Id(), &title, content, documentId, - EditorManager::DoNotSwitchToDesignMode); + IEditor *editor = m_client->openShowEditor( + topLevel, params.ref, path, GitClient::ShowEditor::OnlyIfDifferent); editor->gotoLine(item.mainRange.begin.line, item.mainRange.begin.column); - editor->document()->setTemporary(true); return editor; } diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 7a41ba16393..f2ac006bba3 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -1220,7 +1220,13 @@ void GitPluginPrivate::startChangeRelatedAction(const Id &id) return; if (dialog.command() == Show) { - m_gitClient.show(workingDirectory, change); + const int colon = change.indexOf(':'); + if (colon > 0) { + const QString path = QDir(workingDirectory).absoluteFilePath(change.mid(colon + 1)); + m_gitClient.openShowEditor(workingDirectory, change.left(colon), path); + } else { + m_gitClient.show(workingDirectory, change); + } return; }