}
sub get_blame {
- my ($commits, $source, $start, $len, $from) = @_;
+ my ($commits, $source, $from, $ranges) = @_;
+ return unless @$ranges;
open my $f, '-|',
- qw(git blame --porcelain -C), '-L', "$start,+$len",
+ qw(git blame --porcelain -C),
+ map({"-L$_->[0],+$_->[1]"} @$ranges),
'--since', $since, "$from^", '--', $source or die;
while (<$f>) {
if (/^([0-9a-f]{40}) \d+ \d+ \d+$/) {
my ($sources, $commits) = @_;
for my $s (keys %$sources) {
for my $id (keys %{$sources->{$s}}) {
- for my $range (@{$sources->{$s}{$id}}) {
- get_blame($commits, $s,
- $range->[0], $range->[1], $id);
- }
+ get_blame($commits, $s, $id, $sources->{$s}{$id});
}
}
}
next unless $id;
if (m{^--- (?:a/(.+)|/dev/null)$}) {
$source = $1;
- } elsif (/^--- /) {
- die "Cannot parse hunk source: $_\n";
} elsif (/^@@ -(\d+)(?:,(\d+))?/ && $source) {
my $len = defined($2) ? $2 : 1;
push @{$sources->{$source}{$id}}, [$1, $len] if $len;
scan_rev_args(\%sources, \@rev_args)
}
+my $toplevel = `git rev-parse --show-toplevel`;
+chomp $toplevel;
+chdir($toplevel) or die "chdir failure: $toplevel: $!\n";
+
my %commits;
blame_sources(\%sources, \%commits);
import_commits(\%commits);