diff options
author | Junio C Hamano <junkio@cox.net> | 2006-12-25 18:02:39 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-12-25 18:02:39 -0800 |
commit | 6ec45f3bd180ed0404733d0f5c648691245cf571 (patch) | |
tree | 31d91661c1caa541f21d358a932fe60232bf1bcf | |
parent | git-add -f: allow adding otherwise ignored files. (diff) | |
parent | gitweb: Use rev-list --skip option. (diff) | |
download | tgif-6ec45f3bd180ed0404733d0f5c648691245cf571.tar.xz |
Merge branch 'rf/web'
* rf/web:
gitweb: Use rev-list --skip option.
gitweb: Change history action to use parse_commits.
gitweb: Change atom, rss actions to use parse_commits.
gitweb: Change header search action to use parse_commits.
gitweb: Change log action to use parse_commits.
gitweb: Change summary, shortlog actions to use parse_commits.
gitweb: We do longer need the --parents flag in rev-list.
gitweb: Add parse_commits, used to bulk load commit objects.
-rwxr-xr-x | gitweb/gitweb.perl | 203 |
1 files changed, 107 insertions, 96 deletions
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index d01d689348..65fcdb0f28 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1270,36 +1270,25 @@ sub parse_tag { return %tag } -sub parse_commit { - my $commit_id = shift; - my $commit_text = shift; - - my @commit_lines; +sub parse_commit_text { + my ($commit_text) = @_; + my @commit_lines = split '\n', $commit_text; my %co; - if (defined $commit_text) { - @commit_lines = @$commit_text; - } else { - local $/ = "\0"; - open my $fd, "-|", git_cmd(), "rev-list", - "--header", "--parents", "--max-count=1", - $commit_id, "--" - or return; - @commit_lines = split '\n', <$fd>; - close $fd or return; - pop @commit_lines; - } + pop @commit_lines; # Remove '\0' + my $header = shift @commit_lines; if (!($header =~ m/^[0-9a-fA-F]{40}/)) { return; } - ($co{'id'}, my @parents) = split ' ', $header; - $co{'parents'} = \@parents; - $co{'parent'} = $parents[0]; + $co{'id'} = $header; + my @parents; while (my $line = shift @commit_lines) { last if $line eq "\n"; if ($line =~ m/^tree ([0-9a-fA-F]{40})$/) { $co{'tree'} = $1; + } elsif ($line =~ m/^parent ([0-9a-fA-F]{40})$/) { + push @parents, $1; } elsif ($line =~ m/^author (.*) ([0-9]+) (.*)$/) { $co{'author'} = $1; $co{'author_epoch'} = $2; @@ -1326,6 +1315,8 @@ sub parse_commit { if (!defined $co{'tree'}) { return; }; + $co{'parents'} = \@parents; + $co{'parent'} = $parents[0]; foreach my $title (@commit_lines) { $title =~ s/^ //; @@ -1375,6 +1366,51 @@ sub parse_commit { return %co; } +sub parse_commit { + my ($commit_id) = @_; + my %co; + + local $/ = "\0"; + + open my $fd, "-|", git_cmd(), "rev-list", + "--header", + "--max-count=1", + $commit_id, + "--", + or die_error(undef, "Open git-rev-list failed"); + %co = parse_commit_text(<$fd>); + close $fd; + + return %co; +} + +sub parse_commits { + my ($commit_id, $maxcount, $skip, $arg, $filename) = @_; + my @cos; + + $maxcount ||= 1; + $skip ||= 0; + + local $/ = "\0"; + + open my $fd, "-|", git_cmd(), "rev-list", + "--header", + ($arg ? ($arg) : ()), + ("--max-count=" . $maxcount), + ("--skip=" . $skip), + $commit_id, + "--", + ($filename ? ($filename) : ()) + or die_error(undef, "Open git-rev-list failed"); + while (my $line = <$fd>) { + my %co = parse_commit_text($line); + push @cos, \%co; + } + close $fd; + + return wantarray ? @cos : \@cos; +} + # parse ref from ref_file, given by ref_id, with given type sub parse_ref { my $ref_file = shift; @@ -2646,20 +2682,19 @@ sub git_project_list_body { sub git_shortlog_body { # uses global variable $project - my ($revlist, $from, $to, $refs, $extra) = @_; + my ($commitlist, $from, $to, $refs, $extra) = @_; my $have_snapshot = gitweb_have_snapshot(); $from = 0 unless defined $from; - $to = $#{$revlist} if (!defined $to || $#{$revlist} < $to); + $to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to); print "<table class=\"shortlog\" cellspacing=\"0\">\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { - my $commit = $revlist->[$i]; - #my $ref = defined $refs ? format_ref_marker($refs, $commit) : ''; + my %co = %{$commitlist->[$i]}; + my $commit = $co{'id'}; my $ref = format_ref_marker($refs, $commit); - my %co = parse_commit($commit); if ($alternate) { print "<tr class=\"dark\">\n"; } else { @@ -2693,23 +2728,19 @@ sub git_shortlog_body { sub git_history_body { # Warning: assumes constant type (blob or tree) during history - my ($revlist, $from, $to, $refs, $hash_base, $ftype, $extra) = @_; + my ($commitlist, $from, $to, $refs, $hash_base, $ftype, $extra) = @_; $from = 0 unless defined $from; - $to = $#{$revlist} unless (defined $to && $to <= $#{$revlist}); + $to = $#{$commitlist} unless (defined $to && $to <= $#{$commitlist}); print "<table class=\"history\" cellspacing=\"0\">\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { - if ($revlist->[$i] !~ m/^([0-9a-fA-F]{40})/) { - next; - } - - my $commit = $1; - my %co = parse_commit($commit); + my %co = %{$commitlist->[$i]}; if (!%co) { next; } + my $commit = $co{'id'}; my $ref = format_ref_marker($refs, $commit); @@ -2853,18 +2884,18 @@ sub git_heads_body { } sub git_search_grep_body { - my ($greplist, $from, $to, $extra) = @_; + my ($commitlist, $from, $to, $extra) = @_; $from = 0 unless defined $from; - $to = $#{$greplist} if (!defined $to || $#{$greplist} < $to); + $to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to); print "<table class=\"grep\" cellspacing=\"0\">\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { - my $commit = $greplist->[$i]; - my %co = parse_commit($commit); + my %co = %{$commitlist->[$i]}; if (!%co) { next; } + my $commit = $co{'id'}; if ($alternate) { print "<tr class=\"dark\">\n"; } else { @@ -3023,14 +3054,10 @@ sub git_summary { # we need to request one more than 16 (0..15) to check if # those 16 are all - open my $fd, "-|", git_cmd(), "rev-list", "--max-count=17", - $head, "--" - or die_error(undef, "Open git-rev-list failed"); - my @revlist = map { chomp; $_ } <$fd>; - close $fd; + my @commitlist = parse_commits($head, 17); git_print_header_div('shortlog'); - git_shortlog_body(\@revlist, 0, 15, $refs, - $#revlist <= 15 ? undef : + git_shortlog_body(\@commitlist, 0, 15, $refs, + $#commitlist <= 15 ? undef : $cgi->a({-href => href(action=>"shortlog")}, "...")); if (@taglist) { @@ -3592,28 +3619,25 @@ sub git_log { } my $refs = git_get_references(); - my $limit = sprintf("--max-count=%i", (100 * ($page+1))); - open my $fd, "-|", git_cmd(), "rev-list", $limit, $hash, "--" - or die_error(undef, "Open git-rev-list failed"); - my @revlist = map { chomp; $_ } <$fd>; - close $fd; + my @commitlist = parse_commits($hash, 101, (100 * $page)); - my $paging_nav = format_paging_nav('log', $hash, $head, $page, $#revlist); + my $paging_nav = format_paging_nav('log', $hash, $head, $page, (100 * ($page+1))); git_header_html(); git_print_page_nav('log','', $hash,undef,undef, $paging_nav); - if (!@revlist) { + if (!@commitlist) { my %co = parse_commit($hash); git_print_header_div('summary', $project); print "<div class=\"page_body\"> Last change $co{'age_string'}.<br/><br/></div>\n"; } - for (my $i = ($page * 100); $i <= $#revlist; $i++) { - my $commit = $revlist[$i]; - my $ref = format_ref_marker($refs, $commit); - my %co = parse_commit($commit); + my $to = ($#commitlist >= 99) ? (99) : ($#commitlist); + for (my $i = 0; $i <= $to; $i++) { + my %co = %{$commitlist[$i]}; next if !%co; + my $commit = $co{'id'}; + my $ref = format_ref_marker($refs, $commit); my %ad = parse_date($co{'author_epoch'}); git_print_header_div('commit', "<span class=\"age\">$co{'age_string'}</span>" . @@ -3635,6 +3659,12 @@ sub git_log { git_print_log($co{'comment'}, -final_empty_line=> 1); print "</div>\n"; } + if ($#commitlist >= 100) { + print "<div class=\"page_nav\">\n"; + print $cgi->a({-href => href(action=>"log", hash=>$hash, page=>$page+1), + -accesskey => "n", -title => "Alt-n"}, "next"); + print "</div>\n"; + } git_footer_html(); } @@ -4163,12 +4193,7 @@ sub git_history { $ftype = git_get_type($hash); } - open my $fd, "-|", - git_cmd(), "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 - or die_error(undef, "Reading git-rev-list failed"); + my @commitlist = parse_commits($hash_base, 101, (100 * $page), "--full-history", $file_name); my $paging_nav = ''; if ($page > 0) { @@ -4184,7 +4209,7 @@ sub git_history { $paging_nav .= "first"; $paging_nav .= " ⋅ prev"; } - if ($#revlist >= (100 * ($page+1)-1)) { + if ($#commitlist >= 100) { $paging_nav .= " ⋅ " . $cgi->a({-href => href(action=>"history", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name, page=>$page+1), @@ -4193,11 +4218,11 @@ sub git_history { $paging_nav .= " ⋅ next"; } my $next_link = ''; - if ($#revlist >= (100 * ($page+1)-1)) { + if ($#commitlist >= 100) { $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"); + -accesskey => "n", -title => "Alt-n"}, "next"); } git_header_html(); @@ -4205,7 +4230,7 @@ sub git_history { git_print_header_div('commit', esc_html($co{'title'}), $hash_base); git_print_page_path($file_name, $ftype, $hash_base); - git_history_body(\@revlist, ($page * 100), $#revlist, + git_history_body(\@commitlist, 0, 99, $refs, $hash_base, $ftype, $next_link); git_footer_html(); @@ -4251,13 +4276,8 @@ sub git_search { } elsif ($searchtype eq 'committer') { $greptype = "--committer="; } - open my $fd, "-|", git_cmd(), "rev-list", - ("--max-count=" . (100 * ($page+1))), - ($greptype . $searchtext), - $hash, "--" - or next; - my @revlist = map { chomp; $_ } <$fd>; - close $fd; + $greptype .= $searchtext; + my @commitlist = parse_commits($hash, 101, (100 * $page), $greptype); my $paging_nav = ''; if ($page > 0) { @@ -4274,7 +4294,7 @@ sub git_search { $paging_nav .= "first"; $paging_nav .= " ⋅ prev"; } - if ($#revlist >= (100 * ($page+1)-1)) { + if ($#commitlist >= 100) { $paging_nav .= " ⋅ " . $cgi->a({-href => href(action=>"search", hash=>$hash, searchtext=>$searchtext, searchtype=>$searchtype, @@ -4284,7 +4304,7 @@ sub git_search { $paging_nav .= " ⋅ next"; } my $next_link = ''; - if ($#revlist >= (100 * ($page+1)-1)) { + if ($#commitlist >= 100) { $next_link = $cgi->a({-href => href(action=>"search", hash=>$hash, searchtext=>$searchtext, searchtype=>$searchtype, @@ -4294,7 +4314,7 @@ sub git_search { git_print_page_nav('','', $hash,$co{'tree'},$hash, $paging_nav); git_print_header_div('commit', esc_html($co{'title'}), $hash); - git_search_grep_body(\@revlist, ($page * 100), $#revlist, $next_link); + git_search_grep_body(\@commitlist, 0, 99, $next_link); } if ($searchtype eq 'pickaxe') { @@ -4398,26 +4418,21 @@ sub git_shortlog { } my $refs = git_get_references(); - my $limit = sprintf("--max-count=%i", (100 * ($page+1))); - open my $fd, "-|", git_cmd(), "rev-list", $limit, $hash, "--" - or die_error(undef, "Open git-rev-list failed"); - my @revlist = map { chomp; $_ } <$fd>; - close $fd; + my @commitlist = parse_commits($head, 101, (100 * $page)); - my $paging_nav = format_paging_nav('shortlog', $hash, $head, $page, $#revlist); + my $paging_nav = format_paging_nav('shortlog', $hash, $head, $page, (100 * ($page+1))); my $next_link = ''; - if ($#revlist >= (100 * ($page+1)-1)) { + if ($#commitlist >= 100) { $next_link = $cgi->a({-href => href(action=>"shortlog", hash=>$hash, page=>$page+1), - -title => "Alt-n"}, "next"); + -accesskey => "n", -title => "Alt-n"}, "next"); } - git_header_html(); git_print_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav); git_print_header_div('summary', $project); - git_shortlog_body(\@revlist, ($page * 100), $#revlist, $refs, $next_link); + git_shortlog_body(\@commitlist, 0, 99, $refs, $next_link); git_footer_html(); } @@ -4437,11 +4452,7 @@ sub git_feed { # log/feed of current (HEAD) branch, log of given branch, history of file/directory my $head = $hash || 'HEAD'; - open my $fd, "-|", git_cmd(), "rev-list", "--max-count=150", - $head, "--", (defined $file_name ? $file_name : ()) - or die_error(undef, "Open git-rev-list failed"); - my @revlist = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading git-rev-list failed"); + my @commitlist = parse_commits($head, 150); my %latest_commit; my %latest_date; @@ -4451,8 +4462,8 @@ sub git_feed { # browser (feed reader) prefers text/xml $content_type = 'text/xml'; } - if (defined($revlist[0])) { - %latest_commit = parse_commit($revlist[0]); + if (defined($commitlist[0])) { + %latest_commit = %{$commitlist[0]}; %latest_date = parse_date($latest_commit{'author_epoch'}); print $cgi->header( -type => $content_type, @@ -4542,9 +4553,9 @@ XML } # contents - for (my $i = 0; $i <= $#revlist; $i++) { - my $commit = $revlist[$i]; - my %co = parse_commit($commit); + for (my $i = 0; $i <= $#commitlist; $i++) { + my %co = %{$commitlist[$i]}; + my $commit = $co{'id'}; # we read 150, we always show 30 and the ones more recent than 48 hours if (($i >= 20) && ((time - $co{'author_epoch'}) > 48*60*60)) { last; @@ -4552,7 +4563,7 @@ XML my %cd = parse_date($co{'author_epoch'}); # get list of changed files - open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, + open my $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, $co{'parent'}, $co{'id'}, "--", (defined $file_name ? $file_name : ()) or next; my @difftree = map { chomp; $_ } <$fd>; |