@@ -59,11 +59,11 @@ sub import_commits {
5959}
6060
6161sub get_blame {
62- my ($commits , $source , $start , $len , $from ) = @_ ;
63- $len = 1 unless defined ($len );
64- return if $len == 0;
62+ my ($commits , $source , $from , $ranges ) = @_ ;
63+ return unless @$ranges ;
6564 open my $f , ' -|' ,
66- qw( git blame --porcelain -C) , ' -L' , " $start ,+$len " ,
65+ qw( git blame --porcelain -C) ,
66+ map ({" -L$_ ->[0],+$_ ->[1]" } @$ranges ),
6767 ' --since' , $since , " $from ^" , ' --' , $source or die ;
6868 while (<$f >) {
6969 if (/ ^([0-9a-f]{40}) \d + \d + \d +$ / ) {
@@ -76,8 +76,17 @@ sub get_blame {
7676 close $f ;
7777}
7878
79+ sub blame_sources {
80+ my ($sources , $commits ) = @_ ;
81+ for my $s (keys %$sources ) {
82+ for my $id (keys %{$sources -> {$s }}) {
83+ get_blame($commits , $s , $id , $sources -> {$s }{$id });
84+ }
85+ }
86+ }
87+
7988sub scan_patches {
80- my ($commits , $id , $f ) = @_ ;
89+ my ($sources , $id , $f ) = @_ ;
8190 my $source ;
8291 while (<$f >) {
8392 if (/ ^From ([0-9a-f]{40}) Mon Sep 17 00:00:00 2001$ / ) {
@@ -90,7 +99,8 @@ sub scan_patches {
9099 } elsif (/ ^--- / ) {
91100 die " Cannot parse hunk source: $_ \n " ;
92101 } elsif (/ ^@@ -(\d +)(?:,(\d +))?/ && $source ) {
93- get_blame($commits , $source , $1 , $2 , $id );
102+ my $len = defined ($2 ) ? $2 : 1;
103+ push @{$sources -> {$source }{$id }}, [$1 , $len ] if $len ;
94104 }
95105 }
96106}
@@ -163,13 +173,16 @@ for (@ARGV) {
163173 }
164174}
165175
166- my %commits ;
176+ my %sources ;
167177for (@files ) {
168- scan_patch_file(\%commits , $_ );
178+ scan_patch_file(\%sources , $_ );
169179}
170180if (@rev_args ) {
171- scan_rev_args(\%commits , \@rev_args )
181+ scan_rev_args(\%sources , \@rev_args )
172182}
183+
184+ my %commits ;
185+ blame_sources(\%sources , \%commits );
173186import_commits(\%commits );
174187
175188my $contacts = {};
0 commit comments