X-Git-Url: https://git.ladys.computer/Gitweb/blobdiff_plain/31fa693948b9e688aef8adaae5c6dc8487287c6dee3f868e5de71452c0b4df83..c8781675934a3002fb72e8eead8230c06902a3561390dfaaf9a4a3016717f216:/gitweb.cgi diff --git a/gitweb.cgi b/gitweb.cgi index f6d1d97..ffe4620 100755 --- a/gitweb.cgi +++ b/gitweb.cgi @@ -15,13 +15,14 @@ use CGI::Carp qw(fatalsToBrowser); use Fcntl ':mode'; my $cgi = new CGI; -my $version = "220"; +my $version = "236"; my $my_url = $cgi->url(); my $my_uri = $cgi->url(-absolute => 1); my $rss_link = ""; # absolute fs-path which will be prepended to the project path my $projectroot = "/pub/scm"; +$projectroot = "/home/kay/public_html/pub/scm"; # location of the git-core binaries my $gitbin = "/usr/bin"; @@ -53,8 +54,6 @@ if (defined $action) { git_opml(); exit; } -} else { - $action = "summary"; } my $project = $cgi->param('p'); @@ -76,7 +75,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 +94,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 +136,6 @@ if (defined $page) { } } - my $searchtext = $cgi->param('s'); if (defined $searchtext) { if ($searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) { @@ -130,7 +145,7 @@ if (defined $searchtext) { $searchtext = quotemeta $searchtext; } -if ($action eq "summary") { +if (!defined $action || $action eq "summary") { git_summary(); exit; } elsif ($action eq "branches") { @@ -178,6 +193,9 @@ if ($action eq "summary") { } elsif ($action eq "shortlog") { git_shortlog(); exit; +} elsif ($action eq "tag") { + git_tag(); + exit; } else { undef $action; die_error(undef, "Unknown action."); @@ -234,6 +252,9 @@ div.log_link { div.list_head { padding:6px 8px 4px; border:solid #d9d8d1; border-width:1px 0px 0px; font-style:italic; } a.list { text-decoration:none; color:#000000; } a.list:hover { text-decoration:underline; color:#880000; } +a.text { text-decoration:none; color:#0000cc; } +a.text:visited { text-decoration:none; color:#880000; } +a.text:hover { text-decoration:underline; color:#880000; } table { padding:8px 4px; } th { padding:2px 5px; font-size:12px; text-align:left; } tr.light:hover { background-color:#edece6; } @@ -245,6 +266,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; @@ -318,7 +340,7 @@ sub git_get_type { open my $fd, "-|", "$gitbin/git-cat-file -t $hash" or return; my $type = <$fd>; - close $fd; + close $fd or return; chomp $type; return $type; } @@ -348,8 +370,10 @@ sub git_read_description { sub git_read_tag { my $tag_id = shift; my %tag; + my @comment; open my $fd, "-|", "$gitbin/git-cat-file tag $tag_id" or return; + $tag{'id'} = $tag_id; while (my $line = <$fd>) { chomp $line; if ($line =~ m/^object ([0-9a-fA-F]{40})$/) { @@ -358,8 +382,19 @@ sub git_read_tag { $tag{'type'} = $1; } elsif ($line =~ m/^tag (.+)$/) { $tag{'name'} = $1; + } elsif ($line =~ m/^tagger (.*) ([0-9]+) (.*)$/) { + $tag{'author'} = $1; + $tag{'epoch'} = $2; + $tag{'tz'} = $3; + } elsif ($line =~ m/--BEGIN/) { + push @comment, $line; + last; + } elsif ($line eq "") { + last; } } + push @comment, <$fd>; + $tag{'comment'} = \@comment; close $fd or return; if (!defined $tag{'name'}) { return @@ -367,6 +402,37 @@ sub git_read_tag { return %tag } +sub age_string { + my $age = shift; + my $age_str; + + if ($age > 60*60*24*365*2) { + $age_str = (int $age/60/60/24/365); + $age_str .= " years ago"; + } elsif ($age > 60*60*24*(365/12)*2) { + $age_str = int $age/60/60/24/(365/12); + $age_str .= " months ago"; + } elsif ($age > 60*60*24*7*2) { + $age_str = int $age/60/60/24/7; + $age_str .= " weeks ago"; + } elsif ($age > 60*60*24*2) { + $age_str = int $age/60/60/24; + $age_str .= " days ago"; + } elsif ($age > 60*60*2) { + $age_str = int $age/60/60; + $age_str .= " hours ago"; + } elsif ($age > 60*2) { + $age_str = int $age/60; + $age_str .= " min ago"; + } elsif ($age > 2) { + $age_str = int $age; + $age_str .= " sec ago"; + } else { + $age_str .= " right now"; + } + return $age_str; +} + sub git_read_commit { my $commit_id = shift; my $commit_text = shift; @@ -439,29 +505,14 @@ sub git_read_commit { my $age = time - $co{'committer_epoch'}; $co{'age'} = $age; - if ($age > 60*60*24*365*2) { - $co{'age_string'} = (int $age/60/60/24/365); - $co{'age_string'} .= " years ago"; - } elsif ($age > 60*60*24*(365/12)*2) { - $co{'age_string'} = int $age/60/60/24/(365/12); - $co{'age_string'} .= " months ago"; - } elsif ($age > 60*60*24*7*2) { - $co{'age_string'} = int $age/60/60/24/7; - $co{'age_string'} .= " weeks ago"; - } elsif ($age > 60*60*24*2) { - $co{'age_string'} = int $age/60/60/24; - $co{'age_string'} .= " days ago"; - } elsif ($age > 60*60*2) { - $co{'age_string'} = int $age/60/60; - $co{'age_string'} .= " hours ago"; - } elsif ($age > 60*2) { - $co{'age_string'} = int $age/60; - $co{'age_string'} .= " min ago"; - } elsif ($age > 2) { - $co{'age_string'} = int $age; - $co{'age_string'} .= " sec ago"; + $co{'age_string'} = age_string($age); + 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'} .= " right now"; + $co{'age_string_date'} = $co{'age_string'}; + $co{'age_string_age'} = sprintf "%4i-%02u-%02i", 1900 + $year, $mon+1, $mday; } return %co; } @@ -584,6 +635,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 => "text", -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 +779,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,31 +823,57 @@ 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"); 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{'type'} = $tag{'type'}; + $ref_item{'reftype'} = $tag{'type'}; $ref_item{'name'} = $tag{'name'}; - $ref_item{'id'} = $tag{'object'}; + $ref_item{'refid'} = $tag{'object'}; } elsif ($type eq "commit"){ %co = git_read_commit($ref_id); - $ref_item{'type'} = "commit"; + $ref_item{'reftype'} = "commit"; $ref_item{'name'} = $ref_file; $ref_item{'title'} = $co{'title'}; - $ref_item{'id'} = $ref_id; + $ref_item{'refid'} = $ref_id; + $ref_item{'epoch'} = $co{'committer_epoch'}; + $ref_item{'age'} = $co{'age_string'}; } - $ref_item{'epoch'} = $co{'committer_epoch'} || 0; - $ref_item{'age'} = $co{'age_string'} || "unknown"; push @reflist, \%ref_item; } @@ -879,6 +971,11 @@ sub git_summary { my $alternate = 0; foreach my $entry (@$taglist) { my %tag = %$entry; + my $comment_lines = $tag{'comment'}; + my $comment = shift @$comment_lines; + if (defined($comment)) { + $comment = chop_str($comment, 30, 5); + } if ($alternate) { print "
| $tag{'type'} | " . $cgi->a({-class => "text", -href => "$my_uri?p=$project;a=$tag{'type'};h=$tag{'object'}"}, $tag{'object'}) . " |
| author | " . escapeHTML($tag{'author'}) . " |
| " . $ad{'rfc2822'} . sprintf(" (%02d:%02d %s)", $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'}) . " |
| $co{'age_string'} | \n" . + print "$co{'age_string_date'} | \n" . "" . escapeHTML(chop_str($co{'author_name'}, 15, 3)) . " | \n" . "" . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"}, "" . escapeHTML(chop_str($co{'title'}, 50)) . "") . " | \n" . @@ -1855,7 +2037,7 @@ sub git_search { print "||||
| $co{'age_string'} | \n" . + print "$co{'age_string_date'} | \n" . "" . escapeHTML(chop_str($co{'author_name'}, 15, 5)) . " | \n" . "" .
$cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"}, "" . escapeHTML(chop_str($co{'title'}, 50)) . " "); @@ -1908,7 +2090,7 @@ sub git_search { print " | ||||
| $co{'age_string'} | \n" . + print "$co{'age_string_date'} | \n" . "" . escapeHTML(chop_str($co{'author_name'}, 15, 5)) . " | \n" . "" .
$cgi->a({-href => "$my_uri?p=$project;a=commit;h=$co{'id'}", -class => "list"}, "" .
@@ -1991,7 +2173,7 @@ sub git_shortlog {
print "| $co{'age_string'} | \n" .
+ print "$co{'age_string_date'} | \n" .
"" . escapeHTML(chop_str($co{'author_name'}, 10)) . " | \n" .
"" . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"}, "" .
escapeHTML($co{'title_short'}) . "") . " | \n" .
|