X-Git-Url: https://git.ladys.computer/Gitweb/blobdiff_plain/31fa693948b9e688aef8adaae5c6dc8487287c6dee3f868e5de71452c0b4df83..5ca6347a26ce3cd988a527f9624d3463e4850d568df6ea9b85d972fdd4bf4d5c:/gitweb.cgi diff --git a/gitweb.cgi b/gitweb.cgi index f6d1d97..0698b74 100755 --- a/gitweb.cgi +++ b/gitweb.cgi @@ -15,7 +15,7 @@ use CGI::Carp qw(fatalsToBrowser); use Fcntl ':mode'; my $cgi = new CGI; -my $version = "220"; +my $version = "234"; my $my_url = $cgi->url(); my $my_uri = $cgi->url(-absolute => 1); my $rss_link = ""; @@ -53,8 +53,6 @@ if (defined $action) { git_opml(); exit; } -} else { - $action = "summary"; } my $project = $cgi->param('p'); @@ -76,7 +74,7 @@ if (defined $project) { die_error(undef, "No such project."); } $rss_link = ""; - $ENV{'GIT_OBJECT_DIRECTORY'} = "$projectroot/$project/objects"; + $ENV{'GIT_DIR'} = "$projectroot/$project"; } else { git_project_list(); exit; @@ -95,9 +93,26 @@ if (defined $file_name) { } my $hash = $cgi->param('h'); -if (defined $hash && !($hash =~ m/^[0-9a-fA-F]{40}$/)) { - undef $hash; - die_error(undef, "Invalid hash parameter."); +if (defined $hash) { + if (!($hash =~ m/^[0-9a-fA-F]{40}$/)) { + if ($hash =~ m/(^|\/)(|\.|\.\.)($|\/)/) { + undef $hash; + die_error(undef, "Non-canonical hash parameter."); + } + if ($hash =~ m/[^a-zA-Z0-9_\.\/\-\+\#\~\:\!]/) { + undef $hash; + die_error(undef, "Invalid character in hash parameter."); + } + # replace branch-name with hash + my $branchlist = git_read_refs("refs/heads"); + foreach my $entry (@$branchlist) { + my %branch = %$entry; + if ($branch{'name'} eq $hash) { + $hash = $branch{'id'}; + last; + } + } + } } my $hash_parent = $cgi->param('hp'); @@ -120,7 +135,6 @@ if (defined $page) { } } - my $searchtext = $cgi->param('s'); if (defined $searchtext) { if ($searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) { @@ -130,7 +144,7 @@ if (defined $searchtext) { $searchtext = quotemeta $searchtext; } -if ($action eq "summary") { +if (!defined $action || $action eq "summary") { git_summary(); exit; } elsif ($action eq "branches") { @@ -245,6 +259,7 @@ div.pre { font-family:monospace; font-size:12px; white-space:pre; } div.diff_info { font-family:monospace; color:#000099; background-color:#edece6; font-style:italic; } div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; padding:12px 8px; } div.search { margin:4px 8px; position:absolute; top:56px; right:12px } +a.linenr { color:#999999; text-decoration:none } a.rss_logo { float:right; padding:3px 0px; width:35px; line-height:10px; border:1px solid; border-color:#fcc7a5 #7d3302 #3e1a01 #ff954e; @@ -463,6 +478,14 @@ sub git_read_commit { } else { $co{'age_string'} .= " right now"; } + my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($co{'committer_epoch'}); + if ($age > 60*60*24*7*2) { + $co{'age_string_date'} = sprintf "%4i-%02u-%02i", 1900 + $year, $mon+1, $mday; + $co{'age_string_age'} = $co{'age_string'}; + } else { + $co{'age_string_date'} = $co{'age_string'}; + $co{'age_string_age'} = sprintf "%4i-%02u-%02i", 1900 + $year, $mon+1, $mday; + } return %co; } @@ -584,6 +607,21 @@ sub file_type { } } +sub format_log_line_html { + my $line = shift; + + $line = escapeHTML($line); + $line =~ s/ / /g; + if ($line =~ m/([0-9a-fA-F]{40})/) { + my $hash_text = $1; + if (git_get_type($hash_text) eq "commit") { + my $link = $cgi->a({-class => "list", -href => "$my_uri?p=$project;a=commit;h=$hash_text"}, $hash_text); + $line =~ s/$hash_text/$link/; + } + } + return $line; +} + sub date_str { my $epoch = shift; my $tz = shift || "-0000"; @@ -713,7 +751,7 @@ sub git_project_list { if (!defined $head) { next; } - $ENV{'GIT_OBJECT_DIRECTORY'} = "$projectroot/$proj{'path'}/objects"; + $ENV{'GIT_DIR'} = "$projectroot/$proj{'path'}"; my %co = git_read_commit($head); if (!%co) { next; @@ -757,8 +795,23 @@ sub git_read_refs { my $ref_dir = shift; my @reflist; + my @refs; opendir my $dh, "$projectroot/$project/$ref_dir"; - my @refs = grep !m/^\./, readdir $dh; + while (my $dir = readdir($dh)) { + if ($dir =~ m/^\./) { + next; + } + if (-d "$projectroot/$project/$ref_dir/$dir") { + opendir my $dh2, "$projectroot/$project/$ref_dir/$dir"; + my @subdirs = grep !m/^\./, readdir $dh2; + closedir($dh2); + foreach my $subdir (@subdirs) { + push @refs, "$dir/$subdir" + } + next; + } + push @refs, $dir; + } closedir($dh); foreach my $ref_file (@refs) { my $ref_id = git_read_hash("$project/$ref_dir/$ref_file"); @@ -927,12 +980,12 @@ sub git_summary { if ($i-- > 0) { print "$tag{'age'}\n" . "" . - $cgi->a({-href => "$my_uri?p=$project;a=shortlog;h=$tag{'id'}", -class => "list"}, + $cgi->a({-href => "$my_uri?p=$project;a=shortlog;h=$tag{'name'}", -class => "list"}, "" . escapeHTML($tag{'name'}) . "") . "\n" . "" . - $cgi->a({-href => "$my_uri?p=$project;a=shortlog;h=$tag{'id'}"}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?p=$project;a=log;h=$tag{'id'}"}, "log") . + $cgi->a({-href => "$my_uri?p=$project;a=shortlog;h=$tag{'name'}"}, "shortlog") . + " | " . $cgi->a({-href => "$my_uri?p=$project;a=log;h=$tag{'name'}"}, "log") . "\n" . ""; } else { @@ -975,13 +1028,13 @@ sub git_tags { $alternate ^= 1; print "$tag{'age'}\n" . "" . - $cgi->a({-href => "$my_uri?p=$project;a=log;h=$tag{'id'}", -class => "list"}, + $cgi->a({-href => "$my_uri?p=$project;a=shortlog;h=$tag{'id'}", -class => "list"}, "" . escapeHTML($tag{'name'}) . "") . "\n" . "" . $cgi->a({-href => "$my_uri?p=$project;a=$tag{'type'};h=$tag{'id'}"}, $tag{'type'}); if ($tag{'type'} eq "commit") { - print " | " . $cgi->a({-href => "$my_uri?p=$project;a=shortlog;h=$tag{'id'}"}, "shortlog") . + print " | " . $cgi->a({-href => "$my_uri?p=$project;a=shortlog;h=$tag{'name'}"}, "shortlog") . " | " . $cgi->a({-href => "$my_uri?p=$project;a=log;h=$tag{'id'}"}, "log"); } print "\n" . @@ -1021,11 +1074,11 @@ sub git_branches { $alternate ^= 1; print "$tag{'age'}\n" . "" . - $cgi->a({-href => "$my_uri?p=$project;a=log;h=$tag{'id'}", -class => "list"}, "" . escapeHTML($tag{'name'}) . "") . + $cgi->a({-href => "$my_uri?p=$project;a=shortlog;h=$tag{'name'}", -class => "list"}, "" . escapeHTML($tag{'name'}) . "") . "\n" . "" . - $cgi->a({-href => "$my_uri?p=$project;a=shortlog;h=$tag{'id'}"}, "shortog") . - " | " . $cgi->a({-href => "$my_uri?p=$project;a=log;h=$tag{'id'}"}, "log") . + $cgi->a({-href => "$my_uri?p=$project;a=shortlog;h=$tag{'name'}"}, "shortlog") . + " | " . $cgi->a({-href => "$my_uri?p=$project;a=log;h=$tag{'name'}"}, "log") . "\n" . ""; } @@ -1104,7 +1157,7 @@ sub git_blob { $line =~ s/\t/$spaces/; } } - printf "
%4i %s
\n", $nr, escapeHTML($line); + printf "
%4i %s
\n", $nr, $nr, $nr, escapeHTML($line); } close $fd or print "Reading blob failed.\n"; print ""; @@ -1216,7 +1269,7 @@ sub git_rss { "\n"; print "\n"; print "$project\n". - "" . escapeHTML("$my_url/$project/log") . "\n". + "" . escapeHTML("$my_url?p=$project;a=summary") . "\n". "$project log\n". "en\n"; @@ -1261,7 +1314,7 @@ sub git_opml { if (!defined $head) { next; } - $ENV{'GIT_OBJECT_DIRECTORY'} = "$projectroot/$proj{'path'}/objects"; + $ENV{'GIT_DIR'} = "$projectroot/$proj{'path'}"; my %co = git_read_commit($head); if (!%co) { next; @@ -1269,7 +1322,7 @@ sub git_opml { my $path = escapeHTML(chop_str($proj{'path'}, 25, 5)); my $rss = "$my_url?p=$proj{'path'};a=rss"; - my $html = "$my_url?p=$proj{'path'};a=log"; + my $html = "$my_url?p=$proj{'path'};a=summary"; print "\n"; } print "\n". @@ -1357,7 +1410,7 @@ sub git_log { } else { $empty = 0; } - print escapeHTML($line) . "
\n"; + print format_log_line_html($line) . "
\n"; } if (!$empty) { print "
\n"; @@ -1458,7 +1511,7 @@ sub git_commit { print "" . escapeHTML($line) . "
\n"; } else { $signed = 0; - print escapeHTML($line) . "
\n"; + print format_log_line_html($line) . "
\n"; } } print "\n"; @@ -1487,7 +1540,7 @@ sub git_commit { print "\n"; } $alternate ^= 1; - if ($status eq "N") { + if ($status eq "A") { my $mode_chng = ""; if (S_ISREG(oct $to_mode)) { $mode_chng = sprintf(" with mode: %04o", (oct $to_mode) & 0777); @@ -1649,7 +1702,7 @@ sub git_commitdiff { } else { $empty = 0; } - print escapeHTML($line) . "
\n"; + print format_log_line_html($line) . "
\n"; } print "
\n"; foreach my $line (@difftree) { @@ -1662,7 +1715,7 @@ sub git_commitdiff { my $to_id = $4; my $status = $5; my $file = $6; - if ($status eq "N") { + if ($status eq "A") { print "
" . file_type($to_mode) . ":" . $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$to_id;hb=$hash;f=$file"}, $to_id) . "(new)" . "
\n"; @@ -1694,25 +1747,51 @@ sub git_commitdiff_plain { my (@difftree) = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading diff-tree failed."); + # try to figure out the next tag after this commit + my $tagname; + my %taghash; + my $tags = git_read_refs("refs/tags"); + foreach my $entry (@$tags) { + my %tag = %$entry; + $taghash{$tag{'id'}} = $tag{'name'}; + } + open $fd, "-|", "$gitbin/git-rev-list HEAD"; + while (my $commit = <$fd>) { + chomp $commit; + if ($taghash{$commit}) { + $tagname = $taghash{$commit}; + } + if ($commit eq $hash) { + last; + } + } + close $fd; + + print $cgi->header(-type => "text/plain", -charset => 'utf-8'); my %co = git_read_commit($hash); my %ad = date_str($co{'author_epoch'}, $co{'author_tz'}); - print $cgi->header(-type => "text/plain", -charset => 'utf-8'); my $comment = $co{'comment'}; - print "Author: $co{'author'}\n" . + print "From: $co{'author'}\n" . "Date: $ad{'rfc2822'} ($ad{'tz_local'})\n". - "Source: $my_url?p=$project;a=commitdiff;h=$hash\n" . + "Subject: $co{'title'}\n"; + if (defined $tagname) { + print "X-Git-Tag: $tagname\n"; + } + print "X-Git-Url: $my_url?p=$project;a=commitdiff;h=$hash\n" . "\n"; + foreach my $line (@$comment) {; print " $line\n"; } - print "\n"; + 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(.*)$/; my $from_id = $3; my $to_id = $4; my $status = $5; my $file = $6; - if ($status eq "N") { + if ($status eq "A") { git_diff_print(undef, "/dev/null", $to_id, "b/$file", "plain"); } elsif ($status eq "D") { git_diff_print($from_id, "a/$file", undef, "/dev/null", "plain"); @@ -1750,7 +1829,7 @@ sub git_history { print "\n"; my $alternate = 0; while (my $line = <$fd>) { - if ($line =~ m/^([0-9a-fA-F]{40}) /){ + if ($line =~ m/^([0-9a-fA-F]{40})/){ $commit = $1; next; } @@ -1765,7 +1844,7 @@ sub git_history { print "\n"; } $alternate ^= 1; - print "\n" . + print "\n" . "\n" . "\n" . @@ -1855,7 +1934,7 @@ sub git_search { print "\n"; } $alternate ^= 1; - print "\n" . + print "\n" . "\n" . "\n"; } $alternate ^= 1; - print "\n" . + print "\n" . "\n" . "\n"; } $alternate ^= 1; - print "\n" . + print "\n" . "\n" . "\n" .
$co{'age_string'}$co{'age_string_date'}" . escapeHTML(chop_str($co{'author_name'}, 15, 3)) . "" . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"}, "" . escapeHTML(chop_str($co{'title'}, 50)) . "") . "
$co{'age_string'}$co{'age_string_date'}" . escapeHTML(chop_str($co{'author_name'}, 15, 5)) . "" . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"}, "" . escapeHTML(chop_str($co{'title'}, 50)) . "
"); @@ -1908,7 +1987,7 @@ sub git_search { print "
$co{'age_string'}$co{'age_string_date'}" . escapeHTML(chop_str($co{'author_name'}, 15, 5)) . "" . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$co{'id'}", -class => "list"}, "" . @@ -1991,7 +2070,7 @@ sub git_shortlog { print "
$co{'age_string'}$co{'age_string_date'}" . escapeHTML(chop_str($co{'author_name'}, 10)) . "" . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"}, "" . escapeHTML($co{'title_short'}) . "") . "