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; }