diff options
| author | Johannes Altmanninger <aclopte@gmail.com> | 2024-02-03 00:26:56 +0100 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2024-02-05 21:42:02 +1100 |
| commit | 86d940c225d4d1e316efebf6d915feaa1aa49f63 (patch) | |
| tree | ecba59b0d5f79b7618fcd698fa32cd64cb7ffa61 /rc/filetype/diff-parse.pl | |
| parent | 36efbf4cbfe70c7fb8ca8ac6171cd5d8b134fdc0 (diff) | |
rc tools git: command for easy recursive blaming
Our ":git blame" annotates each line with the most recent commit.
However often a line has been modified by several commits.
Introduce ":git blame-jump" which shows the commit that added the
line at cursor. Crucially, it works also in Git diff buffers, so it
can be used recursively to find the full history of a line.
To do the recursive blame from a diff, I need to navigate to the
old (deleted) version of a line. Since old and new line are usually
neighbors. Speed up the common scenario of finding the old version
by making ":git blame-jump" jump to the new version. This means the
initial diff view might not include the commit message etc. Compensate
this by showing the commit's date+author+subject in the status line.
Here are some test cases.
- run blame-jump after "git blame"
- create an uncommitted or unsaved line, run "git blame" and
"blame-jump" on the uncommitted line
- run blame-jump without running "git blame"
- run blame-jump in "git show"
- run blame-jump in "git diff HEAD"
- run blame-jump in "git diff --cached"
- run blame-jump in "git diff" (YMMV if there are cached changes,
could fix that)
Naming: there are some similar commands in the wild [1];
they are usually called "show-blamed" or similar, but they
don't jump to the corresponding line. Also our list of git
commands is getting a bit messy (especially the undocumented
show-diff/hide-diff/next-hunk/prev-hunk; subject first naming seems
better).
[1]: https://github.com/robertmeta/kak/blob/f6e78ec4c0eeccd091e6275828234d98e6aa3a7f/kakrc#L423
Future work: to go back to the previously-blamed commit we need to
have had the foresight to use "rename-buffer". Perhaps we want to
add some kind of buffer stack (like Magit does for example).
Diffstat (limited to 'rc/filetype/diff-parse.pl')
| -rwxr-xr-x | rc/filetype/diff-parse.pl | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/rc/filetype/diff-parse.pl b/rc/filetype/diff-parse.pl index f7858eb7..203e9b19 100755 --- a/rc/filetype/diff-parse.pl +++ b/rc/filetype/diff-parse.pl @@ -39,11 +39,17 @@ while (defined $ARGV[0]) { # Inputs our $directory = $ENV{PWD}; our $strip; +our $in_file; +our $in_file_line; our $version = "+"; eval $begin if defined $begin; +$in_file = "$directory/$in_file" if defined $in_file; + # Outputs +our $diff_line = 0; +our $commit; our $file; our $file_line; our $diff_line_text; @@ -83,8 +89,13 @@ sub strip { } while (<STDIN>) { + $diff_line++; s/^(> )*//g; $diff_line_text = $_; + if (m{^commit (\w+)}) { + $commit = $1; + next; + } if (m{^diff\b}) { $state = "header"; $is_recursive_diff = 1; @@ -116,6 +127,11 @@ while (<STDIN>) { $other_file_line++ if defined $other_file_line; } } + if (defined $in_file and defined $file and $file eq $in_file) { + if (defined $in_file_line and defined $file_line and $file_line >= $in_file_line) { + last; + } + } } if (not defined $file) { $file = ($fallback_file or $other_file); |
