# target of the home link on top of all pages
our $home_link = $my_uri;
+# string of the home link on top of all pages
+our $home_link_str = "++GITWEB_HOME_LINK_STR++";
+
# name of your site or organization to appear in page titles
# replace this with something more descriptive for clearer bookmarks
our $site_name = "++GITWEB_SITENAME++" || $ENV{'SERVER_NAME'} || "Untitled";
# format marker of refs pointing to given object
sub format_ref_marker {
my ($refs, $id) = @_;
+ my $markers = '';
if (defined $refs->{$id}) {
- return ' <span class="tag">' . esc_html($refs->{$id}) . '</span>';
+ foreach my $ref (@{$refs->{$id}}) {
+ my ($type, $name) = qw();
+ # e.g. tags/v2.6.11 or heads/next
+ if ($ref =~ m!^(.*?)s?/(.*)$!) {
+ $type = $1;
+ $name = $2;
+ } else {
+ $type = "ref";
+ $name = $ref;
+ }
+
+ $markers .= " <span class=\"$type\">" . esc_html($name) . "</span>";
+ }
+ }
+
+ if ($markers) {
+ return ' <span class="refs">'. $markers . '</span>';
} else {
return "";
}
return @list;
}
+sub git_get_project_owner {
+ my $project = shift;
+ my $owner;
+
+ return undef unless $project;
+
+ # read from file (url-encoded):
+ # 'git%2Fgit.git Linus+Torvalds'
+ # 'libs%2Fklibc%2Fklibc.git H.+Peter+Anvin'
+ # 'linux%2Fhotplug%2Fudev.git Greg+Kroah-Hartman'
+ if (-f $projects_list) {
+ open (my $fd , $projects_list);
+ while (my $line = <$fd>) {
+ chomp $line;
+ my ($pr, $ow) = split ' ', $line;
+ $pr = unescape($pr);
+ $ow = unescape($ow);
+ if ($pr eq $project) {
+ $owner = decode("utf8", $ow, Encode::FB_DEFAULT);
+ last;
+ }
+ }
+ close $fd;
+ }
+ if (!defined $owner) {
+ $owner = get_file_owner("$projectroot/$project");
+ }
+
+ return $owner;
+}
+
sub git_get_references {
my $type = shift || "";
my %refs;
+ my $fd;
# 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c refs/tags/v2.6.11
# c39ae07f393806ccf406ef966e9a15afc43cc36a refs/tags/v2.6.11^{}
- open my $fd, "$projectroot/$project/info/refs" or return;
+ if (-f "$projectroot/$project/info/refs") {
+ open $fd, "$projectroot/$project/info/refs"
+ or return;
+ } else {
+ open $fd, "-|", $GIT, "ls-remote", "."
+ or return;
+ }
+
while (my $line = <$fd>) {
chomp $line;
- # attention: for $type == "" it saves only last path part of ref name
- # e.g. from 'refs/heads/jn/gitweb' it would leave only 'gitweb'
- if ($line =~ m/^([0-9a-fA-F]{40})\t.*$type\/([^\^]+)/) {
+ if ($line =~ m/^([0-9a-fA-F]{40})\trefs\/($type\/?[^\^]+)/) {
if (defined $refs{$1}) {
- $refs{$1} .= " / $2";
+ push @{$refs{$1}}, $2;
} else {
- $refs{$1} = $2;
+ $refs{$1} = [ $2 ];
}
}
}
my %mimemap;
open(MIME, $mimemap) or return undef;
while (<MIME>) {
+ next if m/^#/; # skip comments
my ($mime, $exts) = split(/\t+/);
if (defined $exts) {
my @exts = split(/\s+/, $exts);
if ($mimetypes_file) {
my $file = $mimetypes_file;
- #$file =~ m#^/# or $file = "$projectroot/$path/$file";
+ if ($file !~ m!^/!) { # if it is relative path
+ # it is relative to project
+ $file = "$projectroot/$project/$file";
+ }
$mime = mimetype_guess_file($filename, $file);
}
$mime ||= mimetype_guess_file($filename, '/etc/mime.types');
"<a href=\"http://www.kernel.org/pub/software/scm/git/docs/\" title=\"git documentation\">" .
"<img src=\"$logo\" width=\"72\" height=\"27\" alt=\"git\" style=\"float:right; border-width:0px;\"/>" .
"</a>\n";
- print $cgi->a({-href => esc_param($home_link)}, "projects") . " / ";
+ print $cgi->a({-href => esc_param($home_link)}, $home_link_str) . " / ";
if (defined $project) {
print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, esc_html($project));
if (defined $action) {
## ......................................................................
## functions printing large fragments of HTML
+sub git_difftree_body {
+ my ($difftree, $parent) = @_;
+
+ print "<div class=\"list_head\">\n";
+ if ($#{$difftree} > 10) {
+ print(($#{$difftree} + 1) . " files changed:\n");
+ }
+ print "</div>\n";
+
+ print "<table class=\"diff_tree\">\n";
+ my $alternate = 0;
+ 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(.*)$/) {
+ next;
+ }
+ my $from_mode = $1;
+ my $to_mode = $2;
+ my $from_id = $3;
+ my $to_id = $4;
+ my $status = $5;
+ my $similarity = $6; # score
+ my $file = validate_input(unquote($7));
+
+ if ($alternate) {
+ print "<tr class=\"dark\">\n";
+ } else {
+ print "<tr class=\"light\">\n";
+ }
+ $alternate ^= 1;
+
+ if ($status eq "A") { # created
+ my $mode_chng = "";
+ if (S_ISREG(oct $to_mode)) {
+ $mode_chng = sprintf(" with mode: %04o", (oct $to_mode) & 0777);
+ }
+ print "<td>" .
+ $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file"),
+ -class => "list"}, esc_html($file)) .
+ "</td>\n" .
+ "<td><span class=\"file_status new\">[new " . file_type($to_mode) . "$mode_chng]</span></td>\n" .
+ "<td class=\"link\">" .
+ $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, "blob") .
+ "</td>\n";
+
+ } elsif ($status eq "D") { # deleted
+ print "<td>" .
+ $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$file"),
+ -class => "list"}, esc_html($file)) . "</td>\n" .
+ "<td><span class=\"file_status deleted\">[deleted " . file_type($from_mode). "]</span></td>\n" .
+ "<td class=\"link\">" .
+ $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") .
+ "</td>\n"
+
+ } elsif ($status eq "M" || $status eq "T") { # modified, or type changed
+ my $mode_chnge = "";
+ if ($from_mode != $to_mode) {
+ $mode_chnge = " <span class=\"file_status mode_chnge\">[changed";
+ if (((oct $from_mode) & S_IFMT) != ((oct $to_mode) & S_IFMT)) {
+ $mode_chnge .= " from " . file_type($from_mode) . " to " . file_type($to_mode);
+ }
+ if (((oct $from_mode) & 0777) != ((oct $to_mode) & 0777)) {
+ if (S_ISREG($from_mode) && S_ISREG($to_mode)) {
+ $mode_chnge .= sprintf(" mode: %04o->%04o", (oct $from_mode) & 0777, (oct $to_mode) & 0777);
+ } elsif (S_ISREG($to_mode)) {
+ $mode_chnge .= sprintf(" mode: %04o", (oct $to_mode) & 0777);
+ }
+ }
+ $mode_chnge .= "]</span>\n";
+ }
+ print "<td>";
+ if ($to_id ne $from_id) { # modified
+ print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file"),
+ -class => "list"}, esc_html($file));
+ } else { # mode changed
+ print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file"),
+ -class => "list"}, esc_html($file));
+ }
+ print "</td>\n" .
+ "<td>$mode_chnge</td>\n" .
+ "<td class=\"link\">" .
+ $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, "blob");
+ if ($to_id ne $from_id) { # modified
+ print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file")}, "diff");
+ }
+ print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$hash;f=$file")}, "history") . "\n";
+ print "</td>\n";
+
+ } elsif ($status eq "R") { # renamed
+ my ($from_file, $to_file) = split "\t", $file;
+ my $mode_chng = "";
+ if ($from_mode != $to_mode) {
+ $mode_chng = sprintf(", mode: %04o", (oct $to_mode) & 0777);
+ }
+ print "<td>" .
+ $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)) . "</td>\n" .
+ "<td><span class=\"file_status moved\">[moved from " .
+ $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]</span></td>\n" .
+ "<td class=\"link\">" .
+ $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file")}, "blob");
+ if ($to_id ne $from_id) {
+ print " | " .
+ $cgi->a({-href => "$my_uri?" .
+ esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$to_file;fp=$from_file")}, "diff");
+ }
+ print "</td>\n";
+
+ } elsif ($status eq "C") { # copied
+ my ($from_file, $to_file) = split "\t", $file;
+ my $mode_chng = "";
+ if ($from_mode != $to_mode) {
+ $mode_chng = sprintf(", mode: %04o", (oct $to_mode) & 0777);
+ }
+ print "<td>" .
+ $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)) . "</td>\n" .
+ "<td><span class=\"file_status copied\">[copied from " .
+ $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]</span></td>\n" .
+ "<td class=\"link\">" .
+ $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file")}, "blob");
+ if ($to_id ne $from_id) {
+ print " | " .
+ $cgi->a({-href => "$my_uri?" .
+ esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$to_file;fp=$from_file")}, "diff");
+ }
+ print "</td>\n";
+ } # we should not encounter Unmerged (U) or Unknown (X) status
+ print "</tr>\n";
+ }
+ print "</table>\n";
+}
+
sub git_shortlog_body {
# uses global variable $project
my ($revlist, $from, $to, $refs, $extra) = @_;
my %co = parse_commit($head);
my %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'});
- my $owner;
- if (-f $projects_list) {
- open (my $fd , $projects_list);
- while (my $line = <$fd>) {
- chomp $line;
- my ($pr, $ow) = split ' ', $line;
- $pr = unescape($pr);
- $ow = unescape($ow);
- if ($pr eq $project) {
- $owner = decode("utf8", $ow, Encode::FB_DEFAULT);
- last;
- }
- }
- close $fd;
- }
- if (!defined $owner) {
- $owner = get_file_owner("$projectroot/$project");
- }
+ my $owner = git_get_project_owner($project);
my $refs = git_get_references();
git_header_html();
}
}
print "</div>\n";
- print "<div class=\"list_head\">\n";
- if ($#difftree > 10) {
- print(($#difftree + 1) . " files changed:\n");
- }
- print "</div>\n";
- print "<table class=\"diff_tree\">\n";
- my $alternate = 0;
- 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(.*)$/) {
- next;
- }
- my $from_mode = $1;
- my $to_mode = $2;
- my $from_id = $3;
- my $to_id = $4;
- my $status = $5;
- my $similarity = $6;
- my $file = validate_input(unquote($7));
- if ($alternate) {
- print "<tr class=\"dark\">\n";
- } else {
- print "<tr class=\"light\">\n";
- }
- $alternate ^= 1;
- if ($status eq "A") {
- my $mode_chng = "";
- if (S_ISREG(oct $to_mode)) {
- $mode_chng = sprintf(" with mode: %04o", (oct $to_mode) & 0777);
- }
- print "<td>" .
- $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file"), -class => "list"}, esc_html($file)) . "</td>\n" .
- "<td><span class=\"file_status new\">[new " . file_type($to_mode) . "$mode_chng]</span></td>\n" .
- "<td class=\"link\">" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, "blob") . "</td>\n";
- } elsif ($status eq "D") {
- print "<td>" .
- $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$file"), -class => "list"}, esc_html($file)) . "</td>\n" .
- "<td><span class=\"file_status deleted\">[deleted " . file_type($from_mode). "]</span></td>\n" .
- "<td class=\"link\">" .
- $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") .
- "</td>\n"
- } elsif ($status eq "M" || $status eq "T") {
- my $mode_chnge = "";
- if ($from_mode != $to_mode) {
- $mode_chnge = " <span class=\"file_status mode_chnge\">[changed";
- if (((oct $from_mode) & S_IFMT) != ((oct $to_mode) & S_IFMT)) {
- $mode_chnge .= " from " . file_type($from_mode) . " to " . file_type($to_mode);
- }
- if (((oct $from_mode) & 0777) != ((oct $to_mode) & 0777)) {
- if (S_ISREG($from_mode) && S_ISREG($to_mode)) {
- $mode_chnge .= sprintf(" mode: %04o->%04o", (oct $from_mode) & 0777, (oct $to_mode) & 0777);
- } elsif (S_ISREG($to_mode)) {
- $mode_chnge .= sprintf(" mode: %04o", (oct $to_mode) & 0777);
- }
- }
- $mode_chnge .= "]</span>\n";
- }
- print "<td>";
- if ($to_id ne $from_id) {
- print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file"), -class => "list"}, esc_html($file));
- } else {
- print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file"), -class => "list"}, esc_html($file));
- }
- print "</td>\n" .
- "<td>$mode_chnge</td>\n" .
- "<td class=\"link\">";
- print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, "blob");
- if ($to_id ne $from_id) {
- print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file")}, "diff");
- }
- print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$hash;f=$file")}, "history") . "\n";
- print "</td>\n";
- } elsif ($status eq "R") {
- my ($from_file, $to_file) = split "\t", $file;
- my $mode_chng = "";
- if ($from_mode != $to_mode) {
- $mode_chng = sprintf(", mode: %04o", (oct $to_mode) & 0777);
- }
- print "<td>" .
- $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)) . "</td>\n" .
- "<td><span class=\"file_status moved\">[moved from " .
- $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]</span></td>\n" .
- "<td class=\"link\">" .
- $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file")}, "blob");
- if ($to_id ne $from_id) {
- print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$to_file")}, "diff");
- }
- print "</td>\n";
- }
- print "</tr>\n";
- }
- print "</table>\n";
+
+ git_difftree_body(\@difftree, $parent);
+
git_footer_html();
}