Skip to content

Commit 275a5e3

Browse files
committed
Initial version from toddlipcon
File copied from: https://github.com/toddlipcon/tlipcon-bin/blob/master/git-diff-blame
0 parents  commit 275a5e3

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

git-diff-blame

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/perl -w
2+
3+
sub parse_hunk_header {
4+
my ($line) = @_;
5+
my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) =
6+
$line =~ /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
7+
$o_cnt = 1 unless defined $o_cnt;
8+
$n_cnt = 1 unless defined $n_cnt;
9+
return ($o_ofs, $o_cnt, $n_ofs, $n_cnt);
10+
}
11+
12+
sub get_blame_prefix {
13+
my ($line) = @_;
14+
$line =~ /^([0-9a-f]+\s+(\S+\s+)?\([^\)]+\))/ or die "bad blame output: $line";
15+
return $1;
16+
}
17+
18+
my ($oldrev, $newrev) = @ARGV;
19+
open($diff, '-|', 'git', '--no-pager', 'diff', $oldrev, $newrev) or die;
20+
21+
my ($pre, $post);
22+
my $filename;
23+
while (<$diff>) {
24+
if (m{^diff --git ./(.*) ./\1$}) {
25+
close $pre if defined $pre;
26+
close $post if defined $post;
27+
print;
28+
$prefilename = "./" . $1;
29+
$postfilename = "./" . $1;
30+
$delete = $create = 0;
31+
} elsif (m{^new file}) {
32+
$create = 1;
33+
$prefilename = '/dev/null';
34+
} elsif (m{^deleted file}) {
35+
$delete = 1;
36+
$postfilename = '/dev/null';
37+
} elsif (m{^--- $prefilename$}) {
38+
# ignore
39+
print;
40+
} elsif (m{^\+\+\+ $postfilename$}) {
41+
# ignore
42+
print;
43+
} elsif (m{^@@ }) {
44+
my ($o_ofs, $o_cnt, $n_ofs, $n_cnt)
45+
= parse_hunk_header($_);
46+
my $o_end = $o_ofs + $o_cnt - 1;
47+
my $n_end = $n_ofs + $n_cnt - 1;
48+
if (!$create) {
49+
open($pre, '-|', 'git', 'blame', '-M', "-L$o_ofs,$o_end",
50+
"-l",
51+
$oldrev, '--', $prefilename) or die;
52+
}
53+
if (!$delete) {
54+
open($post, '-|', 'git', 'blame', '-M', "-L$n_ofs,$n_end",
55+
"-l",
56+
$newrev, '--', $postfilename) or die;
57+
}
58+
} elsif (m{^ }) {
59+
print get_blame_prefix(scalar <$pre>), "\t", $_;
60+
scalar <$post>; # discard
61+
} elsif (m{^\-}) {
62+
print get_blame_prefix(scalar <$pre>), "\t", $_;
63+
} elsif (m{^\+}) {
64+
print get_blame_prefix(scalar <$post>), "\t", $_;
65+
}
66+
}

0 commit comments

Comments
 (0)