X-Git-Url: https://git.ladys.computer/Gitweb/blobdiff_plain/431bc06790d449565cd34ba163218fb3af2e560fcfa3ab04c10acbe421f1ea36..43df38478e9f80496637e24e000a0bbe3ba6f81b14a9867eadf587c816e0a0f0:/gitweb.perl diff --git a/gitweb.perl b/gitweb.perl index 0f82439..766aa55 100755 --- a/gitweb.perl +++ b/gitweb.perl @@ -18,6 +18,10 @@ use File::Find qw(); use File::Basename qw(basename); binmode STDOUT, ':utf8'; +BEGIN { + CGI->compile() if $ENV{MOD_PERL}; +} + our $cgi = new CGI; our $version = "++GIT_VERSION++"; our $my_url = $cgi->url(); @@ -1272,7 +1276,7 @@ sub parse_tag { } sub parse_commit_text { - my ($commit_text) = @_; + my ($commit_text, $withparents) = @_; my @commit_lines = split '\n', $commit_text; my %co; @@ -1283,12 +1287,12 @@ sub parse_commit_text { return; } ($co{'id'}, my @parents) = split ' ', $header; - $co{'parents'} = \@parents; - $co{'parent'} = $parents[0]; while (my $line = shift @commit_lines) { last if $line eq "\n"; if ($line =~ m/^tree ([0-9a-fA-F]{40})$/) { $co{'tree'} = $1; + } elsif ((!defined $withparents) && ($line =~ m/^parent ([0-9a-fA-F]{40})$/)) { + push @parents, $1; } elsif ($line =~ m/^author (.*) ([0-9]+) (.*)$/) { $co{'author'} = $1; $co{'author_epoch'} = $2; @@ -1315,6 +1319,8 @@ sub parse_commit_text { if (!defined $co{'tree'}) { return; }; + $co{'parents'} = \@parents; + $co{'parent'} = $parents[0]; foreach my $title (@commit_lines) { $title =~ s/^ //; @@ -1371,13 +1377,13 @@ sub parse_commit { local $/ = "\0"; open my $fd, "-|", git_cmd(), "rev-list", - "--header", "--parents", + "--header", "--max-count=1", $commit_id, "--", or die_error(undef, "Open git-rev-list failed"); - %co = parse_commit_text(<$fd>); + %co = parse_commit_text(<$fd>, 1); close $fd; return %co; @@ -1390,36 +1396,13 @@ sub parse_commits { $maxcount ||= 1; $skip ||= 0; - # Delete once rev-list supports the --skip option - if ($skip > 0) { - open my $fd, "-|", git_cmd(), "rev-list", - ($arg ? ($arg) : ()), - ("--max-count=" . ($maxcount + $skip)), - $commit_id, - "--", - ($filename ? ($filename) : ()) - or die_error(undef, "Open git-rev-list failed"); - while (my $line = <$fd>) { - if ($skip-- <= 0) { - chomp $line; - my %co = parse_commit($line); - push @cos, \%co; - } - } - close $fd; - - return wantarray ? @cos : \@cos; - } - local $/ = "\0"; open my $fd, "-|", git_cmd(), "rev-list", "--header", - "--parents", ($arg ? ($arg) : ()), ("--max-count=" . $maxcount), - # Add once rev-list supports the --skip option - # ("--skip=" . $skip), + ("--skip=" . $skip), $commit_id, "--", ($filename ? ($filename) : ()) @@ -1733,6 +1716,7 @@ sub git_header_html { } print $cgi->header(-type=>$content_type, -charset => 'utf-8', -status=> $status, -expires => $expires); + my $mod_perl_version = $ENV{'MOD_PERL'} ? " $ENV{'MOD_PERL'}" : ''; print < @@ -1741,7 +1725,7 @@ sub git_header_html { - + $title EOF @@ -2704,20 +2688,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 "\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 "\n"; } else { @@ -2751,23 +2734,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 "
\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); @@ -2911,18 +2890,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 "
\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 "\n"; } else { @@ -3017,7 +2996,7 @@ sub git_project_index { foreach my $pr (@projects) { if (!exists $pr->{'owner'}) { - $pr->{'owner'} = get_file_owner("$projectroot/$project"); + $pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}"); } my ($path, $owner) = ($pr->{'path'}, $pr->{'owner'}); @@ -3081,14 +3060,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) { @@ -3650,28 +3625,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 "
Last change $co{'age_string'}.

\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', "$co{'age_string'}" . @@ -3693,6 +3665,12 @@ sub git_log { git_print_log($co{'comment'}, -final_empty_line=> 1); print "\n"; } + if ($#commitlist >= 100) { + print "
\n"; + print $cgi->a({-href => href(action=>"log", hash=>$hash, page=>$page+1), + -accesskey => "n", -title => "Alt-n"}, "next"); + print "
\n"; + } git_footer_html(); } @@ -4221,12 +4199,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) { @@ -4242,7 +4215,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), @@ -4251,11 +4224,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(); @@ -4263,7 +4236,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(); @@ -4309,13 +4282,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) { @@ -4332,7 +4300,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, @@ -4342,7 +4310,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, @@ -4352,7 +4320,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') { @@ -4456,26 +4424,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(); } @@ -4495,11 +4458,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; @@ -4509,8 +4468,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, @@ -4600,9 +4559,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; @@ -4610,7 +4569,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>;