aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/git/gitplugin.cpp
diff options
context:
space:
mode:
authorAndre Hartmann <aha_1980@gmx.de>2024-07-16 23:02:09 +0200
committerAndré Hartmann <aha_1980@gmx.de>2024-08-29 12:43:57 +0000
commit8f240e84a0786508bc11f762dafe41cbbdb2ffbf (patch)
tree077ba257fc170b56dc151fd99e37577989f35be2 /src/plugins/git/gitplugin.cpp
parenta5064a20b8a63fbcabfa0150272580526b98f088 (diff)
Git: Add file log for selected lines
Limits the log to commits that touched the selection. Fixes: QTCREATORBUG-31146 Change-Id: I8e581ca113c9564e1484b0b7e17de7e95cdce0bc Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Diffstat (limited to 'src/plugins/git/gitplugin.cpp')
-rw-r--r--src/plugins/git/gitplugin.cpp64
1 files changed, 56 insertions, 8 deletions
diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp
index 044310d3862..a7240ffcaf3 100644
--- a/src/plugins/git/gitplugin.cpp
+++ b/src/plugins/git/gitplugin.cpp
@@ -88,6 +88,8 @@ using namespace std::placeholders;
namespace Git::Internal {
+static Q_LOGGING_CATEGORY(log, "qtc.vcs.git", QtWarningMsg);
+
using GitClientMemberFunc = void (GitClient::*)(const FilePath &) const;
class GitReflogEditorWidget : public GitEditorWidget
@@ -214,6 +216,7 @@ public:
void diffCurrentFile();
void diffProjectDirectory();
void logFile();
+ void logSelection();
void blameFile();
void logProjectDirectory();
void logRepository();
@@ -379,6 +382,9 @@ public:
[] { return new GitEditorWidget; },
std::bind(&GitPluginPrivate::vcsDescribe, this, _1, _2)
}};
+
+private:
+ QStringList lineRange(int &firstLine, bool allowSingleLine = false) const;
};
static GitPluginPrivate *dd = nullptr;
@@ -585,6 +591,11 @@ GitPluginPrivate::GitPluginPrivate()
"Git.Log", context, true, std::bind(&GitPluginPrivate::logFile, this),
QKeySequence(useMacShortcuts ? Tr::tr("Meta+G,Meta+L") : Tr::tr("Alt+G,Alt+L")));
+ createFileAction(currentFileMenu, Tr::tr("Log Current Selection", "Avoid translating \"Log\""),
+ Tr::tr("Log of \"%1\" Selection", "Avoid translating \"Log\""),
+ "Git.LogSelection", context, true, std::bind(&GitPluginPrivate::logSelection, this),
+ QKeySequence(useMacShortcuts ? Tr::tr("Meta+G,Meta+S") : Tr::tr("Alt+G,Alt+S")));
+
createFileAction(currentFileMenu, Tr::tr("Blame Current File", "Avoid translating \"Blame\""),
Tr::tr("Blame for \"%1\"", "Avoid translating \"Blame\""),
"Git.Blame", context, true, std::bind(&GitPluginPrivate::blameFile, this),
@@ -958,13 +969,17 @@ void GitPluginPrivate::logFile()
gitClient().log(state.currentFileTopLevel(), state.relativeCurrentFile(), true);
}
-void GitPluginPrivate::blameFile()
+/**
+ * Returns the current editors selected lines as string list suitable for git.
+ *
+ * The returned list has maximum one element in the following format: {"-L 1,2"}.
+ * An empty list is returned when no editor is open or @a allowSingleLine is false
+ * and there is no selection.
+ *
+ * @internal
+ */
+QStringList GitPluginPrivate::lineRange(int &firstLine, bool allowSingleLine) const
{
- const VcsBasePluginState state = currentState();
- QTC_ASSERT(state.hasFile(), return);
- const int lineNumber = VcsBaseEditor::lineNumberOfCurrentEditor(state.currentFile());
- QStringList extraOptions;
- int firstLine = -1;
if (BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor()) {
QTextCursor cursor = textEditor->textCursor();
if (cursor.hasSelection()) {
@@ -986,15 +1001,48 @@ void GitPluginPrivate::blameFile()
}
argument += QString::number(firstLine) + ',';
argument += QString::number(endBlock + firstLine - startBlock);
- extraOptions << argument;
+ return {argument};
}
+ } else if (allowSingleLine) {
+ firstLine = cursor.blockNumber() + 1;
+ return {"-L " + QString::number(firstLine) + ',' + QString::number(firstLine)};
}
}
+ return {};
+}
+
+void GitPluginPrivate::logSelection()
+{
+ const VcsBasePluginState state = currentState();
+ QTC_ASSERT(state.hasFile(), return);
+
+ int firstLine = -1;
+ QStringList lines = lineRange(firstLine, true);
+ if (lines.isEmpty())
+ return;
+
+ lines.first().append(":" + state.relativeCurrentFile());
+ lines.append("--no-patch");
+
+ qCDebug(log) << "logSelection" << lines;
+ gitClient().log(state.currentFileTopLevel(), {}, true, lines);
+}
+
+void GitPluginPrivate::blameFile()
+{
+ const VcsBasePluginState state = currentState();
+ QTC_ASSERT(state.hasFile(), return);
+ const int lineNumber = VcsBaseEditor::lineNumberOfCurrentEditor(state.currentFile());
+ int firstLine = -1;
+ const QStringList extraOptions = lineRange(firstLine);
const FilePath fileName = state.currentFile().canonicalPath();
FilePath topLevel;
VcsManager::findVersionControlForDirectory(fileName.parentDir(), &topLevel);
+ const QString filePath = fileName.relativeChildPath(topLevel).path();
+
+ qCDebug(log) << "blameFile" << topLevel << filePath << lineNumber << extraOptions << firstLine;
gitClient().annotate(topLevel,
- fileName.relativeChildPath(topLevel).path(),
+ filePath,
lineNumber,
{},
extraOptions,