From cfce3774e50b9d8024ad24e64332b087862a93c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20L=C3=B8vdal?= Date: Fri, 12 Nov 2021 13:15:41 +0100 Subject: [PATCH] Add support for passing options and specify filenames --- README.md | 14 ++++++++++++++ git-diff-blame | 45 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d007315..fc12beb 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,20 @@ Annotates each line in a diff hunk with author and commit information like blame. +## Usage + +```shell +git diff-blame [oldrev [newrev [options] [-- [file1] [file2] [file3] ...]]] +``` + +There is support for passing on options to `git diff` but they must be given +after `oldrev` and `newrev` if they are present. E.g. + +```shell +git diff-blame HEAD^ HEAD -w +git diff-blame --cached -- myfile.c +``` + ## Example: $ git diff-blame HEAD^ diff --git a/git-diff-blame b/git-diff-blame index faf7075..d766c30 100755 --- a/git-diff-blame +++ b/git-diff-blame @@ -7,6 +7,8 @@ # binary, for any purpose, commercial or non-commercial, and by any # means. +use List::Util qw(first); + sub parse_hunk_header { my ($line) = @_; my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) = @@ -27,12 +29,36 @@ $git_root =~ s/^\s+//; $git_root =~ s/\s+$//; chdir($git_root) or die "$!"; -my ($oldrev, $newrev) = @ARGV; -$oldrev ||= 'HEAD'; -if ($newrev) { - open($diff, '-|', 'git', '--no-pager', 'diff', $oldrev, $newrev) or die; +my ($oldrev, $newrev, @REST); + +# First check if file arguments are present. +my $index = first { $ARGV[$_] eq '--' } 0..$#ARGV; +if (defined $index) { + ($oldrev, $newrev) = @ARGV[0 .. $index-1]; + @REST = @ARGV[$index .. $#ARGV]; +} else { + ($oldrev, $newrev, @REST) = @ARGV; +} + +# Then check if any of the revisons accidentally were assigned git diff option values. +if (defined $newrev && $newrev =~ /^-/) { + unshift(@REST, $newrev); + $newrev = undef; +} + +if (defined $oldrev && $oldrev =~ /^-/) { + unshift(@REST, $oldrev); + $oldrev = undef; +} + +if (defined $oldrev) { + if (defined $newrev) { + open($diff, '-|', 'git', '--no-pager', 'diff', $oldrev, $newrev, @REST) or die; + } else { + open($diff, '-|', 'git', '--no-pager', 'diff', $oldrev, @REST) or die; + } } else { - open($diff, '-|', 'git', '--no-pager', 'diff', $oldrev) or die; + open($diff, '-|', 'git', '--no-pager', 'diff', @REST) or die; } my ($pre, $post); @@ -63,8 +89,13 @@ while (<$diff>) { my $o_end = $o_ofs + $o_cnt - 1; my $n_end = $n_ofs + $n_cnt - 1; if (!$create) { - open($pre, '-|', 'git', 'blame', '-M', "-L$o_ofs,$o_end", - $oldrev, '--', $prefilename) or die; + if ($oldrev) { + open($pre, '-|', 'git', 'blame', '-M', "-L$o_ofs,$o_end", + $oldrev, '--', $prefilename) or die; + } else { + open($pre, '-|', 'git', 'blame', '-M', "-L$o_ofs,$o_end", + 'HEAD', '--', $prefilename) or die; + } } if (!$delete) { if ($newrev) {