Subject: Re: [PATCH 0/25] detecting &&-chain breakage

From: Jeff King <[email-masked]>
Date: Sat, 21 Mar 2015 04:19:09 -0400

On Fri, Mar 20, 2015 at 07:18:47PM -0400, Eric Sunshine wrote:

> Ironically, one of the broken here-doc &&-links you detected with
> --chain-lint and fixed in 4/25 was from a patch from me: 5a9830cb
> (t8001/t8002 (blame): add blame -L :funcname tests, 2013-07-17).

Heh. I was afraid to look at my own.

I wondered if we had a good way of finding who wrote the specific lines
that were changed in a patch.  I wrote the script below before realizing
that contrib/contacts does something similar (though I think it blames
whole hunks, including context, and I really want to care specifically
only about touched lines; I wonder if that is a distinction git-contacts
should make).

Running:

  git diff origin origin/jk/test-chain-lint |
  perl diff-blame.pl jk/test-chain-lint |
  grep EOF

was fun. At least I am not the only one. :)

Nor the worst in the "severe" category. I will leave using the script to
read the list of "severe" names as an exercise to the reader; reading
such output is probably not overly healthy (and besides, to be fair it
really should be normalized over the number of contributions).

-- >8 --
# diff-blame.pl
use warnings FATAL => 'all';
use strict;

my $head = shift
  or die "usage: git diff <start> <end> | $0 <start> [blame-opts]";

my $file;
my @lines;
my $line_nr;

while (<STDIN>) {
  if (m{^--- .*?/(.*)}) {
    flush();
    $file = $1;
    @lines = ();
  }
  elsif (m{^@@ -(\d+)}) {
    $line_nr = $1;
  }
  elsif (m{^ }) {
    $line_nr++;
  }
  elsif (m{^-}) {
    push @lines, $line_nr++;
  }
}
flush();
exit 0;

sub flush {
  return unless defined $file && @lines > 0;

  # XXX coalesce blocks of adjacent lines into ranges?
  system(qw(git --no-pager blame), @ARGV,
         (map { "-L$_,$_" } @lines), $head, $file);
}