aboutsummaryrefslogtreecommitdiff
path: root/gitweb
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-10-01 02:16:11 -0700
committerJunio C Hamano <junkio@cox.net>2006-10-03 01:10:03 -0700
commit954a6183756a073723a7c9fd8d2feb13132876b0 (patch)
tree8d50d2793045c6e8e0176e571936a7be4180c406 /gitweb
parent128eead19821ba18e2912ebf30e5621d08735e79 (diff)
downloadgit-954a6183756a073723a7c9fd8d2feb13132876b0.tar.gz
git-954a6183756a073723a7c9fd8d2feb13132876b0.tar.xz
gitweb: make leftmost column of blame less cluttered.
Instead of labelling each and every line with clickable commit object name, this makes the blame output to show them only on the first line of each group of lines from the same revision. Placing too many lines in one group would make the commit object name to appear too widely separated and also makes it consume more memory, the number of lines in one group is capped to 20 lines or so. Also it makes mouse-over to show the minimum authorship and authordate information for extra cuteness ;-). Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'gitweb')
-rw-r--r--[-rwxr-xr-x]gitweb/gitweb.perl99
1 files changed, 86 insertions, 13 deletions
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 3e9d4a005..55d1b2c35 100755..100644
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -2430,9 +2430,64 @@ sub git_tag {
git_footer_html();
}
+sub git_blame_flush_chunk {
+ my ($name, $revdata, $color, $rev, @line) = @_;
+ my $label = substr($rev, 0, 8);
+ my $line = scalar(@line);
+ my $cnt = 0;
+ my $pop = '';
+
+ if ($revdata->{$rev} ne '') {
+ $pop = ' title="' . esc_html($revdata->{$rev}) . '"';
+ }
+
+ for (@line) {
+ my ($lineno, $data) = @$_;
+ $cnt++;
+ print "<tr class=\"$color\">\n";
+ if ($cnt == 1) {
+ print "<td class=\"sha1\"$pop";
+ if ($line > 1) {
+ print " rowspan=\"$line\"";
+ }
+ print ">";
+ print $cgi->a({-href => href(action=>"commit",
+ hash=>$rev,
+ file_name=>$name)},
+ $label);
+ print "</td>\n";
+ }
+ print "<td class=\"linenr\">".
+ "<a id=\"l$lineno\" href=\"#l$lineno\" class=\"linenr\">" .
+ esc_html($lineno) . "</a></td>\n";
+ print "<td class=\"pre\">" . esc_html($data) . "</td>\n";
+ print "</tr>\n";
+ }
+}
+
+# We can have up to N*2 lines. If it is more than N lines, split it
+# into two to avoid orphans.
+sub git_blame_flush_chunk_1 {
+ my ($chunk_cap, $name, $revdata, $color, $rev, @chunk) = @_;
+ if ($chunk_cap < @chunk) {
+ my @first = splice(@chunk, 0, @chunk/2);
+ git_blame_flush_chunk($name,
+ $revdata,
+ $color,
+ $rev,
+ @first);
+ }
+ git_blame_flush_chunk($name,
+ $revdata,
+ $color,
+ $rev,
+ @chunk);
+}
+
sub git_blame2 {
my $fd;
my $ftype;
+ my $chunk_cap = 20;
my ($have_blame) = gitweb_check_feature('blame');
if (!$have_blame) {
@@ -2475,27 +2530,45 @@ sub git_blame2 {
<table class="blame">
<tr><th>Commit</th><th>Line</th><th>Data</th></tr>
HTML
+ my @chunk = ();
+ my %revdata = ();
while (<$fd>) {
/^([0-9a-fA-F]{40}).*?(\d+)\)\s{1}(\s*.*)/;
- my $full_rev = $1;
- my $rev = substr($full_rev, 0, 8);
- my $lineno = $2;
- my $data = $3;
-
+ my ($full_rev, $author, $date, $lineno, $data) =
+ /^([0-9a-f]{40}).*?\s\((.*?)\s+([-\d]+ [:\d]+ [-+\d]+)\s+(\d+)\)\s(.*)/;
+ if (!exists $revdata{$full_rev}) {
+ $revdata{$full_rev} = "$author, $date";
+ }
if (!defined $last_rev) {
$last_rev = $full_rev;
} elsif ($last_rev ne $full_rev) {
+ git_blame_flush_chunk_1($chunk_cap,
+ $file_name,
+ \%revdata,
+ $rev_color[$current_color],
+ $last_rev, @chunk);
+ @chunk = ();
$last_rev = $full_rev;
$current_color = ++$current_color % $num_colors;
}
- print "<tr class=\"$rev_color[$current_color]\">\n";
- print "<td class=\"sha1\">" .
- $cgi->a({-href => href(action=>"commit", hash=>$full_rev, file_name=>$file_name)},
- esc_html($rev)) . "</td>\n";
- print "<td class=\"linenr\"><a id=\"l$lineno\" href=\"#l$lineno\" class=\"linenr\">" .
- esc_html($lineno) . "</a></td>\n";
- print "<td class=\"pre\">" . esc_html($data) . "</td>\n";
- print "</tr>\n";
+ elsif ($chunk_cap * 2 < @chunk) {
+ # We have more than N*2 lines from the same
+ # revision. Flush N lines and leave N lines
+ # in @chunk to avoid orphaned lines.
+ my @first = splice(@chunk, 0, $chunk_cap);
+ git_blame_flush_chunk($file_name,
+ \%revdata,
+ $rev_color[$current_color],
+ $last_rev, @first);
+ }
+ push @chunk, [$lineno, $data];
+ }
+ if (@chunk) {
+ git_blame_flush_chunk_1($chunk_cap,
+ $file_name,
+ \%revdata,
+ $rev_color[$current_color],
+ $last_rev, @chunk);
}
print "</table>\n";
print "</div>";