gitweb: Paginate history output
PATCH 1/1 gitweb: Paginate history output
git_history output is now divided into pages, like git_shortlog, git_tags and git_heads output. As whole git-rev-list output is now read into array before writing anything, it allows for better signaling of errors.
---
Based on 'next' branch, but should apply to 'master as well.
gitweb/gitweb.perl | 59 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 52 insertions(+), 7 deletions(-)
gitweb/gitweb.perl +52 -7
@@ -1544,12 +1544,15 @@ sub git_shortlog_body { sub git_history_body { # Warning: assumes constant type (blob or tree) during history - my ($fd, $refs, $hash_base, $ftype, $extra) = @_; + my ($revlist, $from, $to, $refs, $hash_base, $ftype, $extra) = @_; + + $from = 0 unless defined $from; + $to = $#{$revlist} if (!defined $to || $#{$revlist} < $to); print "<table class=\"history\" cellspacing=\"0\">\n"; my $alternate = 0; - while (my $line = <$fd>) { - if ($line !~ m/^([0-9a-fA-F]{40})/) { + for (my $i = $from; $i <= $to; $i++) { + if ($revlist->[$i] !~ m/^([0-9a-fA-F]{40})/) { next; }
@@ -1559,6 +1562,7 @@ sub git_history_body { next; } + #my $ref = defined $refs ? format_ref_marker($refs, $commit) : ''; my $ref = format_ref_marker($refs, $commit); if ($alternate) {
@@ -2651,21 +2655,62 @@ sub git_history { if (!%co) { die_error(undef, "Unknown commit object"); } + my $refs = git_get_references(); - git_header_html(); - git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base); - git_print_header_div('commit', esc_html($co{'title'}), $hash_base); + my $limit = sprintf("--max-count=%i", (100 * ($page+1))); + if (!defined $hash && defined $file_name) { $hash = git_get_hash_by_path($hash_base, $file_name); } if (defined $hash) { $ftype = git_get_type($hash); } + + open my $fd, "-|", + $GIT, "rev-list", $limit, "--full-history", $hash_base, "--", $file_name + or die_error(undef, "Open git-rev-list-failed"); + my @revlist = map { chomp; $_ } <$fd>; + close $fd; + + my $paging_nav = ''; + if ($page > 0) { + $paging_nav .= + $cgi->a({-href => href(action=>"history", hash=>$hash, hash_base=>$hash_base, + file_name=>$file_name)}, + "first"); + $paging_nav .= " ⋅ " . + $cgi->a({-href => href(action=>"history", hash=>$hash, hash_base=>$hash_base, + file_name=>$file_name, page=>$page-1), + -accesskey => "p", -title => "Alt-p"}, "prev"); + } else { + $paging_nav .= "first"; + $paging_nav .= " ⋅ prev"; + } + if ($#revlist >= (100 * ($page+1)-1)) { + $paging_nav .= " ⋅ " . + $cgi->a({-href => href(action=>"history", hash=>$hash, hash_base=>$hash_base, + file_name=>$file_name, page=>$page+1), + -accesskey => "n", -title => "Alt-n"}, "next"); + } else { + $paging_nav .= " ⋅ next"; + } + my $next_link = ''; + if ($#revlist >= (100 * ($page+1)-1)) { + $next_link = + $cgi->a({-href => href(action=>"history", hash=>$hash, hash_base=>$hash_base, + file_name=>$file_name, page=>$page+1), + -title => "Alt-n"}, "next"); + } + + git_header_html(); + git_print_page_nav('history','', $hash_base,$co{'tree'},$hash_base, $paging_nav); + git_print_header_div('commit', esc_html($co{'title'}), $hash_base); git_print_page_path($file_name, $ftype, $hash_base); open my $fd, "-|", $GIT, "rev-list", "--full-history", $hash_base, "--", $file_name; - git_history_body($fd, $refs, $hash_base, $ftype); + git_history_body(\@revlist, ($page * 100), $#revlist, + $refs, $hash_base, $ftype, $next_link); close $fd; git_footer_html();
Signature · 1 line
1.4.1.1
gitweb/gitweb.perl sub git_history_body { · line 1568
Quoted 8 lines · Jakub Narebski
gitweb/gitweb.perl +1
-0@@ -1559,6 +1562,7 @@ sub git_history_body { next; } + #my $ref = defined $refs ? format_ref_marker($refs, $commit) : ''; my $ref = format_ref_marker($refs, $commit); if ($alternate) {
Do you want to change this or not? Make up your mind.
gitweb/gitweb.perl sub git_history { · line 2684
Quoted 4 lines
gitweb/gitweb.perl +4
-0+ $paging_nav .= " ⋅ " . + $cgi->a({-href => href(action=>"history", hash=>$hash, hash_base=>$hash_base, + file_name=>$file_name, page=>$page-1), + -accesskey => "p", -title => "Alt-p"}, "prev");
This is something you inherited from the original and not your fault, but I am not sure if these -title entries are of good taste (we have corresponding "Alt-n" for "next"). Something more descriptive like "<Alt-p> for 100 newer changes", perhaps?
Also, "first", "prev" and "next" have always confused me. Maybe "latest", "older" and "newer" are better labels for them?
Is 100 a good default? It feels a bit unbalanced compared to the height of the default summary page with descriptions, 16 shortlog entries, 16 tags and 12 heads.
Quoted 6 lines · Junio C Hamano
Quoted 4 lines · Jakub Narebski
(quoted diff) +0
-0@@ -1559,6 +1562,7 @@ sub git_history_body { next; }
Quoted 6 lines
gitweb/gitweb.perl sub git_history_body { · line 1568
Quoted 4 lines
gitweb/gitweb.perl +1
-0+ #my $ref = defined $refs ? format_ref_marker($refs, $commit) : ''; my $ref = format_ref_marker($refs, $commit); if ($alternate) {Do you want to change this or not? Make up your mind.
I'm not sure. This is an internal function, so $refs should be defined. I'm not sure checking here is worth it.
This whole hunk could be removed.
Quoted 9 lines
gitweb/gitweb.perl sub git_history { · line 2684
Quoted 4 lines
gitweb/gitweb.perl +4
-0+ $paging_nav .= " ⋅ " . + $cgi->a({-href => href(action=>"history", hash=>$hash, hash_base=>$hash_base, + file_name=>$file_name, page=>$page-1), + -accesskey => "p", -title => "Alt-p"}, "prev");This is something you inherited from the original and not your fault, but I am not sure if these -title entries are of good taste (we have corresponding "Alt-n" for "next"). Something more descriptive like "<Alt-p> for 100 newer changes", perhaps?
That would be better.
Quoted 2 lines
Also, "first", "prev" and "next" have always confused me. Maybe "latest", "older" and "newer" are better labels for them?
"first" is only for pagination of "history" action, "shortlog", "heads" and "tags" have "HEAD" there instead.
Quoted 3 lines
Is 100 a good default? It feels a bit unbalanced compared to the height of the default summary page with descriptions, 16 shortlog entries, 16 tags and 12 heads.
It's 16 heads (if you have that many), from what I remember from source.
The purpose of summary page is to have everything at glance (it means that it should be contained in one, two pages. The pagination of output is to not send too much at once.
Signature · 3 lines
Jakub Narebski Warsaw, Poland ShadeHawk on #git