Skip to content

Commit d9befc8

Browse files
committed
Merge branch 'jn/gitweb-blame'
* jn/gitweb-blame: gitweb: cache $parent_commit info in git_blame() gitweb: A bit of code cleanup in git_blame() gitweb: Move 'lineno' id from link to row element in git_blame
2 parents 3400537 + 39c19ce commit d9befc8

1 file changed

Lines changed: 51 additions & 35 deletions

File tree

gitweb/gitweb.perl

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4576,28 +4576,33 @@ sub git_tag {
45764576
}
45774577

45784578
sub git_blame {
4579-
my $fd;
4580-
my $ftype;
4581-
4579+
# permissions
45824580
gitweb_check_feature('blame')
4583-
or die_error(403, "Blame view not allowed");
4581+
or die_error(403, "Blame view not allowed");
45844582

4583+
# error checking
45854584
die_error(400, "No file name given") unless $file_name;
45864585
$hash_base ||= git_get_head_hash($project);
4587-
die_error(404, "Couldn't find base commit") unless ($hash_base);
4586+
die_error(404, "Couldn't find base commit") unless $hash_base;
45884587
my %co = parse_commit($hash_base)
45894588
or die_error(404, "Commit not found");
4589+
my $ftype = "blob";
45904590
if (!defined $hash) {
45914591
$hash = git_get_hash_by_path($hash_base, $file_name, "blob")
45924592
or die_error(404, "Error looking up file");
4593+
} else {
4594+
$ftype = git_get_type($hash);
4595+
if ($ftype !~ "blob") {
4596+
die_error(400, "Object is not a blob");
4597+
}
45934598
}
4594-
$ftype = git_get_type($hash);
4595-
if ($ftype !~ "blob") {
4596-
die_error(400, "Object is not a blob");
4597-
}
4598-
open ($fd, "-|", git_cmd(), "blame", '-p', '--',
4599-
$file_name, $hash_base)
4599+
4600+
# run git-blame --porcelain
4601+
open my $fd, "-|", git_cmd(), "blame", '-p',
4602+
$hash_base, '--', $file_name
46004603
or die_error(500, "Open git-blame failed");
4604+
4605+
# page header
46014606
git_header_html();
46024607
my $formats_nav =
46034608
$cgi->a({-href => href(action=>"blob", -replay=>1)},
@@ -4611,42 +4616,46 @@ sub git_blame {
46114616
git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);
46124617
git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
46134618
git_print_page_path($file_name, $ftype, $hash_base);
4614-
my @rev_color = (qw(light2 dark2));
4619+
4620+
# page body
4621+
my @rev_color = qw(light2 dark2);
46154622
my $num_colors = scalar(@rev_color);
46164623
my $current_color = 0;
4617-
my $last_rev;
4624+
my %metainfo = ();
4625+
46184626
print <<HTML;
46194627
<div class="page_body">
46204628
<table class="blame">
46214629
<tr><th>Commit</th><th>Line</th><th>Data</th></tr>
46224630
HTML
4623-
my %metainfo = ();
4624-
while (1) {
4625-
$_ = <$fd>;
4626-
last unless defined $_;
4631+
LINE:
4632+
while (my $line = <$fd>) {
4633+
chomp $line;
4634+
# the header: <SHA-1> <src lineno> <dst lineno> [<lines in group>]
4635+
# no <lines in group> for subsequent lines in group of lines
46274636
my ($full_rev, $orig_lineno, $lineno, $group_size) =
4628-
/^([0-9a-f]{40}) (\d+) (\d+)(?: (\d+))?$/;
4637+
($line =~ /^([0-9a-f]{40}) (\d+) (\d+)(?: (\d+))?$/);
46294638
if (!exists $metainfo{$full_rev}) {
46304639
$metainfo{$full_rev} = {};
46314640
}
46324641
my $meta = $metainfo{$full_rev};
4633-
while (<$fd>) {
4634-
last if (s/^\t//);
4635-
if (/^(\S+) (.*)$/) {
4642+
my $data;
4643+
while ($data = <$fd>) {
4644+
chomp $data;
4645+
last if ($data =~ s/^\t//); # contents of line
4646+
if ($data =~ /^(\S+) (.*)$/) {
46364647
$meta->{$1} = $2;
46374648
}
46384649
}
4639-
my $data = $_;
4640-
chomp $data;
4641-
my $rev = substr($full_rev, 0, 8);
4650+
my $short_rev = substr($full_rev, 0, 8);
46424651
my $author = $meta->{'author'};
4643-
my %date = parse_date($meta->{'author-time'},
4644-
$meta->{'author-tz'});
4652+
my %date =
4653+
parse_date($meta->{'author-time'}, $meta->{'author-tz'});
46454654
my $date = $date{'iso-tz'};
46464655
if ($group_size) {
4647-
$current_color = ++$current_color % $num_colors;
4656+
$current_color = ($current_color + 1) % $num_colors;
46484657
}
4649-
print "<tr class=\"$rev_color[$current_color]\">\n";
4658+
print "<tr id=\"l$lineno\" class=\"$rev_color[$current_color]\">\n";
46504659
if ($group_size) {
46514660
print "<td class=\"sha1\"";
46524661
print " title=\"". esc_html($author) . ", $date\"";
@@ -4655,20 +4664,25 @@ sub git_blame {
46554664
print $cgi->a({-href => href(action=>"commit",
46564665
hash=>$full_rev,
46574666
file_name=>$file_name)},
4658-
esc_html($rev));
4667+
esc_html($short_rev));
46594668
print "</td>\n";
46604669
}
4661-
open (my $dd, "-|", git_cmd(), "rev-parse", "$full_rev^")
4662-
or die_error(500, "Open git-rev-parse failed");
4663-
my $parent_commit = <$dd>;
4664-
close $dd;
4665-
chomp($parent_commit);
4670+
my $parent_commit;
4671+
if (!exists $meta->{'parent'}) {
4672+
open (my $dd, "-|", git_cmd(), "rev-parse", "$full_rev^")
4673+
or die_error(500, "Open git-rev-parse failed");
4674+
$parent_commit = <$dd>;
4675+
close $dd;
4676+
chomp($parent_commit);
4677+
$meta->{'parent'} = $parent_commit;
4678+
} else {
4679+
$parent_commit = $meta->{'parent'};
4680+
}
46664681
my $blamed = href(action => 'blame',
46674682
file_name => $meta->{'filename'},
46684683
hash_base => $parent_commit);
46694684
print "<td class=\"linenr\">";
46704685
print $cgi->a({ -href => "$blamed#l$orig_lineno",
4671-
-id => "l$lineno",
46724686
-class => "linenr" },
46734687
esc_html($lineno));
46744688
print "</td>";
@@ -4679,6 +4693,8 @@ sub git_blame {
46794693
print "</div>";
46804694
close $fd
46814695
or print "Reading blob failed\n";
4696+
4697+
# page footer
46824698
git_footer_html();
46834699
}
46844700

0 commit comments

Comments
 (0)