X-Git-Url: https://git.ladys.computer/Gitweb/blobdiff_plain/aff2acf1437fb10d6b390b236146736c4e8044d3cc1f34506ea2b4b4a82df65d..2eeb01a6441252a7c62233e35c2421d678874f176a713deeefc3977c2cf8ebe8:/gitweb.perl diff --git a/gitweb.perl b/gitweb.perl index 9af69af..eae51ba 100755 --- a/gitweb.perl +++ b/gitweb.perl @@ -21,7 +21,6 @@ our $cgi = new CGI; our $version = "++GIT_VERSION++"; our $my_url = $cgi->url(); our $my_uri = $cgi->url(-absolute => 1); -our $rss_link = ""; # core git executable to use # this can just be "git" if your webserver has a sensible PATH @@ -76,7 +75,7 @@ if (! -d $git_temp) { our $action = $cgi->param('a'); if (defined $action) { if ($action =~ m/[^0-9a-zA-Z\.\-_]/) { - die_error(undef, "Invalid action parameter."); + die_error(undef, "Invalid action parameter"); } # action which does not check rest of parameters if ($action eq "opml") { @@ -87,18 +86,19 @@ if (defined $action) { our $project = ($cgi->param('p') || $ENV{'PATH_INFO'}); if (defined $project) { - $project =~ s|^/||; $project =~ s|/$||; + $project =~ s|^/||; + $project =~ s|/$||; +} +if (defined $project && $project) { if (!validate_input($project)) { - die_error(undef, "Invalid project parameter."); + die_error(undef, "Invalid project parameter"); } if (!(-d "$projectroot/$project")) { - die_error(undef, "No such directory."); + die_error(undef, "No such directory"); } if (!(-e "$projectroot/$project/HEAD")) { - die_error(undef, "No such project."); + die_error(undef, "No such project"); } - $rss_link = ""; $ENV{'GIT_DIR'} = "$projectroot/$project"; } else { git_project_list(); @@ -108,42 +108,42 @@ if (defined $project) { our $file_name = $cgi->param('f'); if (defined $file_name) { if (!validate_input($file_name)) { - die_error(undef, "Invalid file parameter."); + die_error(undef, "Invalid file parameter"); } } our $hash = $cgi->param('h'); if (defined $hash) { if (!validate_input($hash)) { - die_error(undef, "Invalid hash parameter."); + die_error(undef, "Invalid hash parameter"); } } our $hash_parent = $cgi->param('hp'); if (defined $hash_parent) { if (!validate_input($hash_parent)) { - die_error(undef, "Invalid hash parent parameter."); + die_error(undef, "Invalid hash parent parameter"); } } our $hash_base = $cgi->param('hb'); if (defined $hash_base) { if (!validate_input($hash_base)) { - die_error(undef, "Invalid hash base parameter."); + die_error(undef, "Invalid hash base parameter"); } } our $page = $cgi->param('pg'); if (defined $page) { if ($page =~ m/[^0-9]$/) { - die_error(undef, "Invalid page parameter."); + die_error(undef, "Invalid page parameter"); } } our $searchtext = $cgi->param('s'); if (defined $searchtext) { if ($searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) { - die_error(undef, "Invalid search parameter."); + die_error(undef, "Invalid search parameter"); } $searchtext = quotemeta $searchtext; } @@ -172,7 +172,7 @@ my %actions = ( $action = 'summary' if (!defined($action)); if (!defined($actions{$action})) { - die_error(undef, "Unknown action."); + die_error(undef, "Unknown action"); } $actions{$action}->(); exit; @@ -224,6 +224,20 @@ sub unquote { return $str; } +# escape tabs (convert tabs to spaces) +sub untabify { + my $line = shift; + + while ((my $pos = index($line, "\t")) != -1) { + if (my $count = (8 - ($pos % 8))) { + my $spaces = ' ' x $count; + $line =~ s/\t/$spaces/; + } + } + + return $line; +} + ## ---------------------------------------------------------------------- ## HTML aware string manipulation @@ -348,7 +362,7 @@ sub format_log_line_html { } # format marker of refs pointing to given object -sub git_get_referencing { +sub format_ref_marker { my ($refs, $id) = @_; if (defined $refs->{$id}) { @@ -362,7 +376,7 @@ sub git_get_referencing { ## git utility subroutines, invoking git commands # get HEAD ref of given project as hash -sub git_read_head { +sub git_get_head_hash { my $project = shift; my $oENV = $ENV{'GIT_DIR'}; my $retval = undef; @@ -418,7 +432,7 @@ sub git_get_hash_by_path { my $tree = $base; open my $fd, "-|", $GIT, "ls-tree", $base, "--", $path - or die_error(undef, "Open git-ls-tree failed."); + or die_error(undef, "Open git-ls-tree failed"); my $line = <$fd>; close $fd or return undef; @@ -431,7 +445,7 @@ sub git_get_hash_by_path { ## git utility functions, directly accessing git repository # assumes that PATH is not symref -sub git_read_hash { +sub git_get_hash_by_ref { my $path = shift; open my $fd, "$projectroot/$path" or return undef; @@ -443,7 +457,7 @@ sub git_read_hash { } } -sub git_read_description { +sub git_get_project_description { my $path = shift; open my $fd, "$projectroot/$path/description" or return undef; @@ -453,7 +467,7 @@ sub git_read_description { return $descr; } -sub git_read_projects { +sub git_get_projects_list { my @list; if (-d $projects_list) { @@ -497,7 +511,7 @@ sub git_read_projects { return @list; } -sub read_info_ref { +sub git_get_references { my $type = shift || ""; my %refs; # 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c refs/tags/v2.6.11 @@ -522,7 +536,7 @@ sub read_info_ref { ## ---------------------------------------------------------------------- ## parse to hash functions -sub date_str { +sub parse_date { my $epoch = shift; my $tz = shift || "-0000"; @@ -547,7 +561,7 @@ sub date_str { return %date; } -sub git_read_tag { +sub parse_tag { my $tag_id = shift; my %tag; my @comment; @@ -582,7 +596,7 @@ sub git_read_tag { return %tag } -sub git_read_commit { +sub parse_commit { my $commit_id = shift; my $commit_text = shift; @@ -676,10 +690,53 @@ sub git_read_commit { return %co; } +# parse ref from ref_file, given by ref_id, with given type +sub parse_ref { + my $ref_file = shift; + my $ref_id = shift; + my $type = shift || git_get_type($ref_id); + my %ref_item; + + $ref_item{'type'} = $type; + $ref_item{'id'} = $ref_id; + $ref_item{'epoch'} = 0; + $ref_item{'age'} = "unknown"; + if ($type eq "tag") { + my %tag = parse_tag($ref_id); + $ref_item{'comment'} = $tag{'comment'}; + if ($tag{'type'} eq "commit") { + my %co = parse_commit($tag{'object'}); + $ref_item{'epoch'} = $co{'committer_epoch'}; + $ref_item{'age'} = $co{'age_string'}; + } elsif (defined($tag{'epoch'})) { + my $age = time - $tag{'epoch'}; + $ref_item{'epoch'} = $tag{'epoch'}; + $ref_item{'age'} = age_string($age); + } + $ref_item{'reftype'} = $tag{'type'}; + $ref_item{'name'} = $tag{'name'}; + $ref_item{'refid'} = $tag{'object'}; + } elsif ($type eq "commit"){ + my %co = parse_commit($ref_id); + $ref_item{'reftype'} = "commit"; + $ref_item{'name'} = $ref_file; + $ref_item{'title'} = $co{'title'}; + $ref_item{'refid'} = $ref_id; + $ref_item{'epoch'} = $co{'committer_epoch'}; + $ref_item{'age'} = $co{'age_string'}; + } else { + $ref_item{'reftype'} = $type; + $ref_item{'name'} = $ref_file; + $ref_item{'refid'} = $ref_id; + } + + return %ref_item; +} + ## ...................................................................... ## parse to array of hashes functions -sub git_read_refs { +sub git_get_refs_list { my $ref_dir = shift; my @reflist; @@ -693,46 +750,13 @@ sub git_read_refs { }, "$projectroot/$project/$ref_dir"); foreach my $ref_file (@refs) { - my $ref_id = git_read_hash("$project/$ref_dir/$ref_file"); + my $ref_id = git_get_hash_by_ref("$project/$ref_dir/$ref_file"); my $type = git_get_type($ref_id) || next; - my %ref_item; - my %co; - $ref_item{'type'} = $type; - $ref_item{'id'} = $ref_id; - $ref_item{'epoch'} = 0; - $ref_item{'age'} = "unknown"; - if ($type eq "tag") { - my %tag = git_read_tag($ref_id); - $ref_item{'comment'} = $tag{'comment'}; - if ($tag{'type'} eq "commit") { - %co = git_read_commit($tag{'object'}); - $ref_item{'epoch'} = $co{'committer_epoch'}; - $ref_item{'age'} = $co{'age_string'}; - } elsif (defined($tag{'epoch'})) { - my $age = time - $tag{'epoch'}; - $ref_item{'epoch'} = $tag{'epoch'}; - $ref_item{'age'} = age_string($age); - } - $ref_item{'reftype'} = $tag{'type'}; - $ref_item{'name'} = $tag{'name'}; - $ref_item{'refid'} = $tag{'object'}; - } elsif ($type eq "commit"){ - %co = git_read_commit($ref_id); - $ref_item{'reftype'} = "commit"; - $ref_item{'name'} = $ref_file; - $ref_item{'title'} = $co{'title'}; - $ref_item{'refid'} = $ref_id; - $ref_item{'epoch'} = $co{'committer_epoch'}; - $ref_item{'age'} = $co{'age_string'}; - } else { - $ref_item{'reftype'} = $type; - $ref_item{'name'} = $ref_file; - $ref_item{'refid'} = $ref_id; - } + my %ref_item = parse_ref($ref_file, $ref_id, $type); push @reflist, \%ref_item; } - # sort tags by age + # sort refs by age @reflist = sort {$b->{'epoch'} <=> $a->{'epoch'}} @reflist; return \@reflist; } @@ -792,7 +816,7 @@ sub mimetype_guess { return $mime; } -sub git_blob_plain_mimetype { +sub blob_mimetype { my $fd = shift; my $filename = shift; @@ -845,7 +869,7 @@ sub git_header_html { # 'application/xhtml+xml', otherwise send it as plain old 'text/html'. # we have to do this because MSIE sometimes globs '*/*', pretending to # support xhtml+xml but choking when it gets what it asked for. - if ($cgi->http('HTTP_ACCEPT') =~ m/(,|;|\s|^)application\/xhtml\+xml(,|;|\s|$)/ && $cgi->Accept('application/xhtml+xml') != 0) { + if (defined $cgi->http('HTTP_ACCEPT') && $cgi->http('HTTP_ACCEPT') =~ m/(,|;|\s|^)application\/xhtml\+xml(,|;|\s|$)/ && $cgi->Accept('application/xhtml+xml') != 0) { $content_type = 'application/xhtml+xml'; } else { $content_type = 'text/html'; @@ -862,11 +886,17 @@ sub git_header_html { $title -$rss_link - - EOF - print "
\n" . + if (defined $project) { + printf(''."\n", + esc_param($project), + esc_param("$my_uri?p=$project;a=rss")); + } + + print "\n" . + "\n" . + "
\n" . "" . "\"git\"" . "\n"; @@ -905,7 +935,7 @@ EOF sub git_footer_html { print "
\n"; if (defined $project) { - my $descr = git_read_description($project); + my $descr = git_get_project_description($project); if (defined $descr) { print "\n"; } @@ -935,7 +965,7 @@ sub die_error { ## ---------------------------------------------------------------------- ## functions printing or outputting HTML: navigation -sub git_page_nav { +sub git_print_page_nav { my ($current, $suppress, $head, $treehead, $treebase, $extra) = @_; $extra = '' if !defined $extra; # pager or formats @@ -969,7 +999,7 @@ sub git_page_nav { "
\n"; } -sub git_get_paging_nav { +sub format_paging_nav { my ($action, $hash, $head, $page, $nrevs) = @_; my $paging_nav; @@ -983,7 +1013,7 @@ sub git_get_paging_nav { if ($page > 0) { $paging_nav .= " ⋅ " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action;h=$hash;pg=" . ($page-1)), - -accesskey => "p", -title => "Alt-p"}, "prev"); + -accesskey => "p", -title => "Alt-p"}, "prev"); } else { $paging_nav .= " ⋅ prev"; } @@ -991,7 +1021,7 @@ sub git_get_paging_nav { if ($nrevs >= (100 * ($page+1)-1)) { $paging_nav .= " ⋅ " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action;h=$hash;pg=" . ($page+1)), - -accesskey => "n", -title => "Alt-n"}, "next"); + -accesskey => "n", -title => "Alt-n"}, "next"); } else { $paging_nav .= " ⋅ next"; } @@ -1002,7 +1032,7 @@ sub git_get_paging_nav { ## ...................................................................... ## functions printing or outputting HTML: div -sub git_header_div { +sub git_print_header_div { my ($action, $title, $hash, $hash_base) = @_; my $rest = ''; @@ -1042,10 +1072,9 @@ sub git_shortlog_body { my $alternate = 0; for (my $i = $from; $i <= $to; $i++) { my $commit = $revlist->[$i]; - #my $ref = defined $refs ? git_get_referencing($refs, $commit) : ''; - my $ref = git_get_referencing($refs, $commit); - my %co = git_read_commit($commit); - my %ad = date_str($co{'author_epoch'}); + #my $ref = defined $refs ? format_ref_marker($refs, $commit) : ''; + my $ref = format_ref_marker($refs, $commit); + my %co = parse_commit($commit); if ($alternate) { print "\n"; } else { @@ -1238,12 +1267,7 @@ sub git_diff_print { # skip errors next; } - while ((my $pos = index($line, "\t")) != -1) { - if (my $count = (8 - (($pos-1) % 8))) { - my $spaces = ' ' x $count; - $line =~ s/\t/$spaces/; - } - } + $line = untabify($line); print "
" . esc_html($line) . "
\n"; } } @@ -1265,27 +1289,27 @@ sub git_diff_print { sub git_project_list { my $order = $cgi->param('o'); if (defined $order && $order !~ m/project|descr|owner|age/) { - die_error(undef, "Invalid order parameter '$order'."); + die_error(undef, "Unknown order parameter"); } - my @list = git_read_projects(); + my @list = git_get_projects_list(); my @projects; if (!@list) { - die_error(undef, "No projects found."); + die_error(undef, "No projects found"); } foreach my $pr (@list) { - my $head = git_read_head($pr->{'path'}); + my $head = git_get_head_hash($pr->{'path'}); if (!defined $head) { next; } $ENV{'GIT_DIR'} = "$projectroot/$pr->{'path'}"; - my %co = git_read_commit($head); + my %co = parse_commit($head); if (!%co) { next; } $pr->{'commit'} = \%co; if (!defined $pr->{'descr'}) { - my $descr = git_read_description($pr->{'path'}) || ""; + my $descr = git_get_project_description($pr->{'path'}) || ""; $pr->{'descr'} = chop_str($descr, 25, 5); } if (!defined $pr->{'owner'}) { @@ -1369,10 +1393,10 @@ sub git_project_list { } sub git_summary { - my $descr = git_read_description($project) || "none"; - my $head = git_read_head($project); - my %co = git_read_commit($head); - my %cd = date_str($co{'committer_epoch'}, $co{'committer_tz'}); + my $descr = git_get_project_description($project) || "none"; + my $head = git_get_head_hash($project); + my %co = parse_commit($head); + my %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'}); my $owner; if (-f $projects_list) { @@ -1393,9 +1417,9 @@ sub git_summary { $owner = get_file_owner("$projectroot/$project"); } - my $refs = read_info_ref(); + my $refs = git_get_references(); git_header_html(); - git_page_nav('summary','', $head); + git_print_page_nav('summary','', $head); print "
 
\n"; print "\n" . @@ -1404,24 +1428,24 @@ sub git_summary { "\n" . "
last change$cd{'rfc2822'}
\n"; - open my $fd, "-|", $GIT, "rev-list", "--max-count=17", git_read_head($project) - or die_error(undef, "Open git-rev-list failed."); + open my $fd, "-|", $GIT, "rev-list", "--max-count=17", git_get_head_hash($project) + or die_error(undef, "Open git-rev-list failed"); my @revlist = map { chomp; $_ } <$fd>; close $fd; - git_header_div('shortlog'); + git_print_header_div('shortlog'); git_shortlog_body(\@revlist, 0, 15, $refs, $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "...")); - my $taglist = git_read_refs("refs/tags"); + my $taglist = git_get_refs_list("refs/tags"); if (defined @$taglist) { - git_header_div('tags'); + git_print_header_div('tags'); git_tags_body($taglist, 0, 15, $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tags")}, "...")); } - my $headlist = git_read_refs("refs/heads"); + my $headlist = git_get_refs_list("refs/heads"); if (defined @$headlist) { - git_header_div('heads'); + git_print_header_div('heads'); git_heads_body($headlist, $head, 0, 15, $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=heads")}, "...")); } @@ -1430,11 +1454,11 @@ sub git_summary { } sub git_tag { - my $head = git_read_head($project); + my $head = git_get_head_hash($project); git_header_html(); - git_page_nav('','', $head,undef,$head); - my %tag = git_read_tag($hash); - git_header_div('commit', esc_html($tag{'name'}), $hash); + git_print_page_nav('','', $head,undef,$head); + my %tag = parse_tag($hash); + git_print_header_div('commit', esc_html($tag{'name'}), $hash); print "
\n" . "\n" . "\n" . @@ -1443,7 +1467,7 @@ sub git_tag { "\n" . "\n"; if (defined($tag{'author'})) { - my %ad = date_str($tag{'epoch'}, $tag{'tz'}); + my %ad = parse_date($tag{'epoch'}, $tag{'tz'}); print "\n"; print "\n"; } @@ -1461,11 +1485,11 @@ sub git_tag { sub git_blame2 { my $fd; my $ftype; - die_error(undef, "Permission denied.") if (!git_get_project_config_bool ('blame')); + die_error(undef, "Permission denied") if (!git_get_project_config_bool ('blame')); die_error('404 Not Found', "File name not defined") if (!$file_name); - $hash_base ||= git_read_head($project); - die_error(undef, "Reading commit failed") unless ($hash_base); - my %co = git_read_commit($hash_base) + $hash_base ||= git_get_head_hash($project); + die_error(undef, "Couldn't find base commit") unless ($hash_base); + my %co = parse_commit($hash_base) or die_error(undef, "Reading commit failed"); if (!defined $hash) { $hash = git_get_hash_by_path($hash_base, $file_name, "blob") @@ -1473,18 +1497,18 @@ sub git_blame2 { } $ftype = git_get_type($hash); if ($ftype !~ "blob") { - die_error("400 Bad Request", "object is not a blob"); + die_error("400 Bad Request", "Object is not a blob"); } open ($fd, "-|", $GIT, "blame", '-l', $file_name, $hash_base) - or die_error(undef, "Open git-blame failed."); + or die_error(undef, "Open git-blame failed"); git_header_html(); my $formats_nav = $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head"); - git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); - git_header_div('commit', esc_html($co{'title'}), $hash_base); + git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); + git_print_header_div('commit', esc_html($co{'title'}), $hash_base); git_print_page_path($file_name, $ftype); - my @rev_color = (qw(light dark)); + my @rev_color = (qw(light2 dark2)); my $num_colors = scalar(@rev_color); my $current_color = 0; my $last_rev; @@ -1519,24 +1543,24 @@ sub git_blame2 { sub git_blame { my $fd; - die_error('403 Permission denied', "Permission denied.") if (!git_get_project_config_bool ('blame')); - die_error('404 Not Found', "What file will it be, master?") if (!$file_name); - $hash_base ||= git_read_head($project); - die_error(undef, "Reading commit failed.") unless ($hash_base); - my %co = git_read_commit($hash_base) - or die_error(undef, "Reading commit failed."); + die_error('403 Permission denied', "Permission denied") if (!git_get_project_config_bool ('blame')); + die_error('404 Not Found', "File name not defined") if (!$file_name); + $hash_base ||= git_get_head_hash($project); + die_error(undef, "Couldn't find base commit") unless ($hash_base); + my %co = parse_commit($hash_base) + or die_error(undef, "Reading commit failed"); if (!defined $hash) { $hash = git_get_hash_by_path($hash_base, $file_name, "blob") - or die_error(undef, "Error lookup file."); + or die_error(undef, "Error lookup file"); } open ($fd, "-|", $GIT, "annotate", '-l', '-t', '-r', $file_name, $hash_base) - or die_error(undef, "Open git-annotate failed."); + or die_error(undef, "Open git-annotate failed"); git_header_html(); my $formats_nav = $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head"); - git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); - git_header_div('commit', esc_html($co{'title'}), $hash_base); + git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); + git_print_header_div('commit', esc_html($co{'title'}), $hash_base); git_print_page_path($file_name, 'blob'); print "
\n"; print <a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$hash;hb=$hash_base;f=$file_name")}, "blame") . " | "; @@ -1699,8 +1717,8 @@ sub git_blob { } else { $formats_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash")}, "plain"); } - git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); - git_header_div('commit', esc_html($co{'title'}), $hash_base); + git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); + git_print_header_div('commit', esc_html($co{'title'}), $hash_base); } else { print "
\n" . "

\n" . @@ -1712,12 +1730,7 @@ sub git_blob { while (my $line = <$fd>) { chomp $line; $nr++; - while ((my $pos = index($line, "\t")) != -1) { - if (my $count = (8 - ($pos % 8))) { - my $spaces = ' ' x $count; - $line =~ s/\t/$spaces/; - } - } + $line = untabify($line); printf "
%4i %s
\n", $nr, $nr, $nr, esc_html($line); } close $fd or print "Reading blob failed.\n"; @@ -1727,7 +1740,7 @@ sub git_blob { sub git_tree { if (!defined $hash) { - $hash = git_read_head($project); + $hash = git_get_head_hash($project); if (defined $file_name) { my $base = $hash_base || $hash; $hash = git_get_hash_by_path($base, $file_name, "tree"); @@ -1738,21 +1751,21 @@ sub git_tree { } $/ = "\0"; open my $fd, "-|", $GIT, "ls-tree", '-z', $hash - or die_error(undef, "Open git-ls-tree failed."); + or die_error(undef, "Open git-ls-tree failed"); my @entries = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading tree failed."); + close $fd or die_error(undef, "Reading tree failed"); $/ = "\n"; - my $refs = read_info_ref(); - my $ref = git_get_referencing($refs, $hash_base); + my $refs = git_get_references(); + my $ref = format_ref_marker($refs, $hash_base); git_header_html(); my $base_key = ""; my $base = ""; my $have_blame = git_get_project_config_bool ('blame'); - if (defined $hash_base && (my %co = git_read_commit($hash_base))) { + if (defined $hash_base && (my %co = parse_commit($hash_base))) { $base_key = ";hb=$hash_base"; - git_page_nav('tree','', $hash_base); - git_header_div('commit', esc_html($co{'title'}) . $ref, $hash_base); + git_print_page_nav('tree','', $hash_base); + git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash_base); } else { print "
\n"; print "

\n"; @@ -1808,42 +1821,42 @@ sub git_tree { } sub git_log { - my $head = git_read_head($project); + my $head = git_get_head_hash($project); if (!defined $hash) { $hash = $head; } if (!defined $page) { $page = 0; } - my $refs = read_info_ref(); + my $refs = git_get_references(); my $limit = sprintf("--max-count=%i", (100 * ($page+1))); open my $fd, "-|", $GIT, "rev-list", $limit, $hash - or die_error(undef, "Open git-rev-list failed."); + or die_error(undef, "Open git-rev-list failed"); my @revlist = map { chomp; $_ } <$fd>; close $fd; - my $paging_nav = git_get_paging_nav('log', $hash, $head, $page, $#revlist); + my $paging_nav = format_paging_nav('log', $hash, $head, $page, $#revlist); git_header_html(); - git_page_nav('log','', $hash,undef,undef, $paging_nav); + git_print_page_nav('log','', $hash,undef,undef, $paging_nav); if (!@revlist) { - my %co = git_read_commit($hash); + my %co = parse_commit($hash); - git_header_div('summary', $project); + 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 = git_get_referencing($refs, $commit); - my %co = git_read_commit($commit); + my $ref = format_ref_marker($refs, $commit); + my %co = parse_commit($commit); next if !%co; - my %ad = date_str($co{'author_epoch'}); - git_header_div('commit', - "$co{'age_string'}" . - esc_html($co{'title'}) . $ref, - $commit); + my %ad = parse_date($co{'author_epoch'}); + git_print_header_div('commit', + "$co{'age_string'}" . + esc_html($co{'title'}) . $ref, + $commit); print "
\n" . "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") . @@ -1878,43 +1891,43 @@ sub git_log { } sub git_commit { - my %co = git_read_commit($hash); + my %co = parse_commit($hash); if (!%co) { - die_error(undef, "Unknown commit object."); + die_error(undef, "Unknown commit object"); } - my %ad = date_str($co{'author_epoch'}, $co{'author_tz'}); - my %cd = date_str($co{'committer_epoch'}, $co{'committer_tz'}); + my %ad = parse_date($co{'author_epoch'}, $co{'author_tz'}); + my %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'}); my $parent = $co{'parent'}; if (!defined $parent) { $parent = "--root"; } open my $fd, "-|", $GIT, "diff-tree", '-r', '-M', $parent, $hash - or die_error(undef, "Open git-diff-tree failed."); + or die_error(undef, "Open git-diff-tree failed"); my @difftree = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading git-diff-tree failed."); + close $fd or die_error(undef, "Reading git-diff-tree failed"); # non-textual hash id's can be cached my $expires; if ($hash =~ m/^[0-9a-fA-F]{40}$/) { $expires = "+1d"; } - my $refs = read_info_ref(); - my $ref = git_get_referencing($refs, $co{'id'}); + my $refs = git_get_references(); + my $ref = format_ref_marker($refs, $co{'id'}); my $formats_nav = ''; if (defined $file_name && defined $co{'parent'}) { my $parent = $co{'parent'}; $formats_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;hb=$parent;f=$file_name")}, "blame"); } git_header_html(undef, $expires); - git_page_nav('commit', defined $co{'parent'} ? '' : 'commitdiff', - $hash, $co{'tree'}, $hash, - $formats_nav); + git_print_page_nav('commit', defined $co{'parent'} ? '' : 'commitdiff', + $hash, $co{'tree'}, $hash, + $formats_nav); if (defined $co{'parent'}) { - git_header_div('commitdiff', esc_html($co{'title'}) . $ref, $hash); + git_print_header_div('commitdiff', esc_html($co{'title'}) . $ref, $hash); } else { - git_header_div('tree', esc_html($co{'title'}) . $ref, $co{'tree'}, $hash); + git_print_header_div('tree', esc_html($co{'title'}) . $ref, $co{'tree'}, $hash); } print "
\n" . "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'type'};h=$tag{'object'}")}, $tag{'type'}) . "
author" . esc_html($tag{'author'}) . "
" . $ad{'rfc2822'} . sprintf(" (%02d:%02d %s)", $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'}) . "
\n"; @@ -1985,7 +1998,7 @@ sub git_commit { foreach my $line (@difftree) { # ':100644 100644 03b218260e99b78c6df0ed378e59ed9205ccc96d 3b93d5e7cc7f7dd4ebed13a5cc1a4ad976fc94d8 M ls-files.c' # ':100644 100644 7f9281985086971d3877aca27704f2aaf9c448ce bc190ebc71bbd923f2b728e505408f5e54bd073a M rev-tree.c' - if (!($line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/)) { + if ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/) { next; } my $from_mode = $1; @@ -2012,11 +2025,11 @@ sub git_commit { "\n"; } elsif ($status eq "D") { print "\n" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$file"), -class => "list"}, esc_html($file)) . "\n" . "\n" . "\n" } elsif ($status eq "M" || $status eq "T") { my $mode_chnge = ""; @@ -2058,7 +2071,7 @@ sub git_commit { print "\n" . "\n" . "\n"; } else { @@ -2312,14 +2337,14 @@ sub git_history { sub git_search { if (!defined $searchtext) { - die_error(undef, "Text field empty."); + die_error(undef, "Text field empty"); } if (!defined $hash) { - $hash = git_read_head($project); + $hash = git_get_head_hash($project); } - my %co = git_read_commit($hash); + my %co = parse_commit($hash); if (!%co) { - die_error(undef, "Unknown commit object."); + die_error(undef, "Unknown commit object"); } # pickaxe may take all resources of your box and run for several minutes # with every query - so decide by yourself how public you make this feature :) @@ -2336,8 +2361,8 @@ sub git_search { $pickaxe_search = 1; } git_header_html(); - git_page_nav('','', $hash,$co{'tree'},$hash); - git_header_div('commit', esc_html($co{'title'}), $hash); + git_print_page_nav('','', $hash,$co{'tree'},$hash); + git_print_header_div('commit', esc_html($co{'title'}), $hash); print "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, "blob") . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash;f=$file"), -class => "list"}, esc_html($file)) . "[deleted " . file_type($from_mode). "]" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash;f=$file")}, "blob") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$hash;f=$file")}, "history") . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$file")}, "blob") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$parent;f=$file")}, "history") . "" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file"), -class => "list"}, esc_html($to_file)) . "[moved from " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash;f=$from_file"), -class => "list"}, esc_html($from_file)) . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$from_file"), -class => "list"}, esc_html($from_file)) . " with " . (int $similarity) . "% similarity$mode_chng]" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file")}, "blob"); @@ -2076,11 +2089,11 @@ sub git_commit { sub git_blobdiff { mkdir($git_temp, 0700); git_header_html(); - if (defined $hash_base && (my %co = git_read_commit($hash_base))) { + if (defined $hash_base && (my %co = parse_commit($hash_base))) { my $formats_nav = $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff_plain;h=$hash;hp=$hash_parent")}, "plain"); - git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); - git_header_div('commit', esc_html($co{'title'}), $hash_base); + git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); + git_print_header_div('commit', esc_html($co{'title'}), $hash_base); } else { print "
\n" . "

\n" . @@ -2106,30 +2119,30 @@ sub git_blobdiff_plain { sub git_commitdiff { mkdir($git_temp, 0700); - my %co = git_read_commit($hash); + my %co = parse_commit($hash); if (!%co) { - die_error(undef, "Unknown commit object."); + die_error(undef, "Unknown commit object"); } if (!defined $hash_parent) { - $hash_parent = $co{'parent'}; + $hash_parent = $co{'parent'} || '--root'; } open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash - or die_error(undef, "Open git-diff-tree failed."); + or die_error(undef, "Open git-diff-tree failed"); my @difftree = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading diff-tree failed."); + close $fd or die_error(undef, "Reading git-diff-tree failed"); # non-textual hash id's can be cached my $expires; if ($hash =~ m/^[0-9a-fA-F]{40}$/) { $expires = "+1d"; } - my $refs = read_info_ref(); - my $ref = git_get_referencing($refs, $co{'id'}); + my $refs = git_get_references(); + my $ref = format_ref_marker($refs, $co{'id'}); my $formats_nav = $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff_plain;h=$hash;hp=$hash_parent")}, "plain"); git_header_html(undef, $expires); - git_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav); - git_header_div('commit', esc_html($co{'title'}) . $ref, $hash); + git_print_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav); + git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash); print "
\n"; my $comment = $co{'comment'}; my $empty = 0; @@ -2158,7 +2171,9 @@ sub git_commitdiff { foreach my $line (@difftree) { # ':100644 100644 03b218260e99b78c6df0ed378e59ed9205ccc96d 3b93d5e7cc7f7dd4ebed13a5cc1a4ad976fc94d8 M ls-files.c' # ':100644 100644 7f9281985086971d3877aca27704f2aaf9c448ce bc190ebc71bbd923f2b728e505408f5e54bd073a M rev-tree.c' - $line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/; + if ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/) { + next; + } my $from_mode = $1; my $to_mode = $2; my $from_id = $3; @@ -2172,15 +2187,17 @@ sub git_commitdiff { git_diff_print(undef, "/dev/null", $to_id, "b/$file"); } elsif ($status eq "D") { print "
" . file_type($from_mode) . ":" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash;f=$file")}, $from_id) . "(deleted)" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash_parent;f=$file")}, $from_id) . "(deleted)" . "
\n"; git_diff_print($from_id, "a/$file", undef, "/dev/null"); } elsif ($status eq "M") { if ($from_id ne $to_id) { print "
" . - file_type($from_mode) . ":" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash;f=$file")}, $from_id) . + file_type($from_mode) . ":" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash_parent;f=$file")}, $from_id) . " -> " . - file_type($to_mode) . ":" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, $to_id); + file_type($to_mode) . ":" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, $to_id); print "
\n"; git_diff_print($from_id, "a/$file", $to_id, "b/$file"); } @@ -2193,14 +2210,21 @@ sub git_commitdiff { sub git_commitdiff_plain { mkdir($git_temp, 0700); + my %co = parse_commit($hash); + if (!%co) { + die_error(undef, "Unknown commit object"); + } + if (!defined $hash_parent) { + $hash_parent = $co{'parent'} || '--root'; + } open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash - or die_error(undef, "Open git-diff-tree failed."); + or die_error(undef, "Open git-diff-tree failed"); my @difftree = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading diff-tree failed."); + close $fd or die_error(undef, "Reading diff-tree failed"); # try to figure out the next tag after this commit my $tagname; - my $refs = read_info_ref("tags"); + my $refs = git_get_references("tags"); open $fd, "-|", $GIT, "rev-list", "HEAD"; my @commits = map { chomp; $_ } <$fd>; close $fd; @@ -2214,8 +2238,7 @@ sub git_commitdiff_plain { } print $cgi->header(-type => "text/plain", -charset => 'utf-8', '-content-disposition' => "inline; filename=\"git-$hash.patch\""); - my %co = git_read_commit($hash); - my %ad = date_str($co{'author_epoch'}, $co{'author_tz'}); + my %ad = parse_date($co{'author_epoch'}, $co{'author_tz'}); my $comment = $co{'comment'}; print "From: $co{'author'}\n" . "Date: $ad{'rfc2822'} ($ad{'tz_local'})\n". @@ -2232,7 +2255,9 @@ sub git_commitdiff_plain { print "---\n\n"; foreach my $line (@difftree) { - $line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/; + if ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/) { + next; + } my $from_id = $3; my $to_id = $4; my $status = $5; @@ -2249,17 +2274,17 @@ sub git_commitdiff_plain { sub git_history { if (!defined $hash_base) { - $hash_base = git_read_head($project); + $hash_base = git_get_head_hash($project); } my $ftype; - my %co = git_read_commit($hash_base); + my %co = parse_commit($hash_base); if (!%co) { - die_error(undef, "Unknown commit object."); + die_error(undef, "Unknown commit object"); } - my $refs = read_info_ref(); + my $refs = git_get_references(); git_header_html(); - git_page_nav('','', $hash_base,$co{'tree'},$hash_base); - git_header_div('commit', esc_html($co{'title'}), $hash_base); + git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base); + git_print_header_div('commit', esc_html($co{'title'}), $hash_base); if (!defined $hash && defined $file_name) { $hash = git_get_hash_by_path($hash_base, $file_name); } @@ -2275,11 +2300,11 @@ sub git_history { while (my $line = <$fd>) { if ($line =~ m/^([0-9a-fA-F]{40})/){ my $commit = $1; - my %co = git_read_commit($commit); + my %co = parse_commit($commit); if (!%co) { next; } - my $ref = git_get_referencing($refs, $commit); + my $ref = format_ref_marker($refs, $commit); if ($alternate) { print "
\n"; my $alternate = 0; @@ -2355,7 +2380,7 @@ sub git_search { next; } my @commit_lines = split "\n", $commit_text; - my %co = git_read_commit(undef, \@commit_lines); + my %co = parse_commit(undef, \@commit_lines); if (!%co) { next; } @@ -2436,7 +2461,7 @@ sub git_search { print "\n" . "\n"; } - %co = git_read_commit($1); + %co = parse_commit($1); } } close $fd; @@ -2446,22 +2471,22 @@ sub git_search { } sub git_shortlog { - my $head = git_read_head($project); + my $head = git_get_head_hash($project); if (!defined $hash) { $hash = $head; } if (!defined $page) { $page = 0; } - my $refs = read_info_ref(); + my $refs = git_get_references(); my $limit = sprintf("--max-count=%i", (100 * ($page+1))); open my $fd, "-|", $GIT, "rev-list", $limit, $hash - or die_error(undef, "Open git-rev-list failed."); + or die_error(undef, "Open git-rev-list failed"); my @revlist = map { chomp; $_ } <$fd>; close $fd; - my $paging_nav = git_get_paging_nav('shortlog', $hash, $head, $page, $#revlist); + my $paging_nav = format_paging_nav('shortlog', $hash, $head, $page, $#revlist); my $next_link = ''; if ($#revlist >= (100 * ($page+1)-1)) { $next_link = @@ -2471,8 +2496,8 @@ sub git_shortlog { git_header_html(); - git_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav); - git_header_div('summary', $project); + 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); @@ -2484,10 +2509,10 @@ sub git_shortlog { sub git_rss { # http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ - open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_read_head($project) - or die_error(undef, "Open git-rev-list failed."); + open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_get_head_hash($project) + or die_error(undef, "Open git-rev-list failed"); my @revlist = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading rev-list failed."); + close $fd or die_error(undef, "Reading git-rev-list failed"); print $cgi->header(-type => 'text/xml', -charset => 'utf-8'); print "\n". "\n"; @@ -2499,12 +2524,12 @@ sub git_rss { for (my $i = 0; $i <= $#revlist; $i++) { my $commit = $revlist[$i]; - my %co = git_read_commit($commit); + my %co = parse_commit($commit); # we read 150, we always show 30 and the ones more recent than 48 hours if (($i >= 20) && ((time - $co{'committer_epoch'}) > 48*60*60)) { last; } - my %cd = date_str($co{'committer_epoch'}); + my %cd = parse_date($co{'committer_epoch'}); open $fd, "-|", $GIT, "diff-tree", '-r', $co{'parent'}, $co{'id'} or next; my @difftree = map { chomp; $_ } <$fd>; close $fd or next; @@ -2541,7 +2566,7 @@ sub git_rss { } sub git_opml { - my @list = git_read_projects(); + my @list = git_get_projects_list(); print $cgi->header(-type => 'text/xml', -charset => 'utf-8'); print "\n". @@ -2554,12 +2579,12 @@ sub git_opml { foreach my $pr (@list) { my %proj = %$pr; - my $head = git_read_head($proj{'path'}); + my $head = git_get_head_hash($proj{'path'}); if (!defined $head) { next; } $ENV{'GIT_DIR'} = "$projectroot/$proj{'path'}"; - my %co = git_read_commit($head); + my %co = parse_commit($head); if (!%co) { next; }