@@ -4803,7 +4803,7 @@ sub git_blame {
48034803 git_print_page_path($file_name , $ftype , $hash_base );
48044804
48054805 # page body
4806- my @rev_color = qw( light2 dark2 ) ;
4806+ my @rev_color = qw( light dark ) ;
48074807 my $num_colors = scalar (@rev_color );
48084808 my $current_color = 0;
48094809 my %metainfo = ();
@@ -4821,15 +4821,18 @@ sub git_blame {
48214821 my ($full_rev , $orig_lineno , $lineno , $group_size ) =
48224822 ($line =~ / ^([0-9a-f]{40}) (\d +) (\d +)(?: (\d +))?$ / );
48234823 if (!exists $metainfo {$full_rev }) {
4824- $metainfo {$full_rev } = {};
4824+ $metainfo {$full_rev } = { ' nprevious ' => 0 };
48254825 }
48264826 my $meta = $metainfo {$full_rev };
48274827 my $data ;
48284828 while ($data = <$fd >) {
48294829 chomp $data ;
48304830 last if ($data =~ s / ^\t // ); # contents of line
4831- if ($data =~ / ^(\S +) (.*)$ / ) {
4832- $meta -> {$1 } = $2 ;
4831+ if ($data =~ / ^(\S +)(?: (.*))?$ / ) {
4832+ $meta -> {$1 } = $2 unless exists $meta -> {$1 };
4833+ }
4834+ if ($data =~ / ^previous / ) {
4835+ $meta -> {' nprevious' }++;
48334836 }
48344837 }
48354838 my $short_rev = substr ($full_rev , 0, 8);
@@ -4840,7 +4843,11 @@ sub git_blame {
48404843 if ($group_size ) {
48414844 $current_color = ($current_color + 1) % $num_colors ;
48424845 }
4843- print " <tr id=\" l$lineno \" class=\" $rev_color [$current_color ]\" >\n " ;
4846+ my $tr_class = $rev_color [$current_color ];
4847+ $tr_class .= ' boundary' if (exists $meta -> {' boundary' });
4848+ $tr_class .= ' no-previous' if ($meta -> {' nprevious' } == 0);
4849+ $tr_class .= ' multiple-previous' if ($meta -> {' nprevious' } > 1);
4850+ print " <tr id=\" l$lineno \" class=\" $tr_class \" >\n " ;
48444851 if ($group_size ) {
48454852 print " <td class=\" sha1\" " ;
48464853 print " title=\" " . esc_html($author ) . " , $date \" " ;
@@ -4850,22 +4857,31 @@ sub git_blame {
48504857 hash => $full_rev ,
48514858 file_name => $file_name )},
48524859 esc_html($short_rev ));
4860+ if ($group_size >= 2) {
4861+ my @author_initials = ($author =~ / \b ([[:upper:]])\B /g );
4862+ if (@author_initials ) {
4863+ print " <br />" .
4864+ esc_html(join (' ' , @author_initials ));
4865+ # or join('.', ...)
4866+ }
4867+ }
48534868 print " </td>\n " ;
48544869 }
4855- my $parent_commit ;
4856- if (!exists $meta -> {' parent' }) {
4857- open (my $dd , " -|" , git_cmd(), " rev-parse" , " $full_rev ^" )
4858- or die_error(500, " Open git-rev-parse failed" );
4859- $parent_commit = <$dd >;
4860- close $dd ;
4861- chomp ($parent_commit );
4862- $meta -> {' parent' } = $parent_commit ;
4863- } else {
4864- $parent_commit = $meta -> {' parent' };
4865- }
4870+ # 'previous' <sha1 of parent commit> <filename at commit>
4871+ if (exists $meta -> {' previous' } &&
4872+ $meta -> {' previous' } =~ / ^([a-fA-F0-9]{40}) (.*)$ / ) {
4873+ $meta -> {' parent' } = $1 ;
4874+ $meta -> {' file_parent' } = unquote($2 );
4875+ }
4876+ my $linenr_commit =
4877+ exists ($meta -> {' parent' }) ?
4878+ $meta -> {' parent' } : $full_rev ;
4879+ my $linenr_filename =
4880+ exists ($meta -> {' file_parent' }) ?
4881+ $meta -> {' file_parent' } : unquote($meta -> {' filename' });
48664882 my $blamed = href(action => ' blame' ,
4867- file_name => $meta -> { ' filename ' } ,
4868- hash_base => $parent_commit );
4883+ file_name => $linenr_filename ,
4884+ hash_base => $linenr_commit );
48694885 print " <td class=\" linenr\" >" ;
48704886 print $cgi -> a({ -href => " $blamed #l$orig_lineno " ,
48714887 -class => " linenr" },
0 commit comments