X-Git-Url: https://git.ladys.computer/Gitweb/blobdiff_plain/ab4615b634ee06a1df80a3c38086ebb64c5df329db6ecc76674b9ac891eed270..9f0379777eed690c9b9a097ddbfe300d8918dc019707d3395b53bdb7d3aa213b:/gitweb.perl
diff --git a/gitweb.perl b/gitweb.perl
index 50aca37..1a8e256 100755
--- a/gitweb.perl
+++ b/gitweb.perl
@@ -1074,6 +1074,24 @@ sub parse_tag {
return %tag
}
+sub git_get_last_activity {
+ my ($path) = @_;
+ my $fd;
+
+ $git_dir = "$projectroot/$path";
+ open($fd, "-|", git_cmd(), 'for-each-ref',
+ '--format=%(refname) %(committer)',
+ '--sort=-committerdate',
+ 'refs/heads') or return;
+ my $most_recent = <$fd>;
+ close $fd or return;
+ if ($most_recent =~ / (\d+) [-+][01]\d\d\d$/) {
+ my $timestamp = $1;
+ my $age = time - $timestamp;
+ return ($age, age_string($age));
+ }
+}
+
sub parse_commit {
my $commit_id = shift;
my $commit_text = shift;
@@ -1084,12 +1102,11 @@ sub parse_commit {
if (defined $commit_text) {
@commit_lines = @$commit_text;
} else {
- $/ = "\0";
+ local $/ = "\0";
open my $fd, "-|", git_cmd(), "rev-list", "--header", "--parents", "--max-count=1", $commit_id
or return;
@commit_lines = split '\n', <$fd>;
close $fd or return;
- $/ = "\n";
pop @commit_lines;
}
my $header = shift @commit_lines;
@@ -1663,17 +1680,16 @@ sub git_print_page_path {
my $type = shift;
my $hb = shift;
- if (!defined $name) {
- print "
/
\n";
- } else {
+
+ print "";
+ print $cgi->a({-href => href(action=>"tree", hash_base=>$hb),
+ -title => 'tree root'}, "[$project]");
+ print " / ";
+ if (defined $name) {
my @dirname = split '/', $name;
my $basename = pop @dirname;
my $fullname = '';
- print "
";
- print $cgi->a({-href => href(action=>"tree", hash_base=>$hb),
- -title => 'tree root'}, "[$project]");
- print " / ";
foreach my $dir (@dirname) {
$fullname .= ($fullname ? '/' : '') . $dir;
print $cgi->a({-href => href(action=>"tree", file_name=>$fullname,
@@ -1689,11 +1705,12 @@ sub git_print_page_path {
print $cgi->a({-href => href(action=>"tree", file_name=>$file_name,
hash_base=>$hb),
-title => $name}, esc_html($basename));
+ print " / ";
} else {
print esc_html($basename);
}
- print "
\n";
}
+ print "
\n";
}
# sub git_print_log (\@;%) {
@@ -1770,26 +1787,28 @@ sub git_print_tree_entry {
if ($t->{'type'} eq "blob") {
print "" .
$cgi->a({-href => href(action=>"blob", hash=>$t->{'hash'},
- file_name=>"$basedir$t->{'name'}", %base_key),
- -class => "list"}, esc_html($t->{'name'})) . " | \n";
+ file_name=>"$basedir$t->{'name'}", %base_key),
+ -class => "list"}, esc_html($t->{'name'})) . "\n";
print "";
+ print $cgi->a({-href => href(action=>"blob", hash=>$t->{'hash'},
+ file_name=>"$basedir$t->{'name'}", %base_key)},
+ "blob");
if ($have_blame) {
- print $cgi->a({-href => href(action=>"blame", hash=>$t->{'hash'},
- file_name=>"$basedir$t->{'name'}", %base_key)},
- "blame");
+ print " | " .
+ $cgi->a({-href => href(action=>"blame", hash=>$t->{'hash'},
+ file_name=>"$basedir$t->{'name'}", %base_key)},
+ "blame");
}
if (defined $hash_base) {
- if ($have_blame) {
- print " | ";
- }
- print $cgi->a({-href => href(action=>"history", hash_base=>$hash_base,
+ print " | " .
+ $cgi->a({-href => href(action=>"history", hash_base=>$hash_base,
hash=>$t->{'hash'}, file_name=>"$basedir$t->{'name'}")},
"history");
}
print " | " .
$cgi->a({-href => href(action=>"blob_plain", hash_base=>$hash_base,
- file_name=>"$basedir$t->{'name'}")},
- "raw");
+ file_name=>"$basedir$t->{'name'}")},
+ "raw");
print " | \n";
} elsif ($t->{'type'} eq "tree") {
@@ -1799,8 +1818,12 @@ sub git_print_tree_entry {
esc_html($t->{'name'}));
print "\n";
print "";
+ print $cgi->a({-href => href(action=>"tree", hash=>$t->{'hash'},
+ file_name=>"$basedir$t->{'name'}", %base_key)},
+ "tree");
if (defined $hash_base) {
- print $cgi->a({-href => href(action=>"history", hash_base=>$hash_base,
+ print " | " .
+ $cgi->a({-href => href(action=>"history", hash_base=>$hash_base,
file_name=>"$basedir$t->{'name'}")},
"history");
}
@@ -1857,7 +1880,7 @@ sub git_difftree_body {
print " | ";
print $cgi->a({-href => href(action=>"blob", hash=>$diff{'to_id'},
hash_base=>$hash, file_name=>$diff{'file'}),
- -class => "list"}, esc_html($diff{'file'}));
+ -class => "list"}, esc_html($diff{'file'}));
print " | \n";
print "$mode_chng | \n";
print "";
@@ -1883,12 +1906,15 @@ sub git_difftree_body {
print $cgi->a({-href => "#patch$patchno"}, "patch");
print " | ";
}
+ print $cgi->a({-href => href(action=>"blob", hash=>$diff{'from_id'},
+ hash_base=>$parent, file_name=>$diff{'file'})},
+ "blob") . " | ";
print $cgi->a({-href => href(action=>"blame", hash_base=>$parent,
- file_name=>$diff{'file'})},
- "blame") . " | ";
+ file_name=>$diff{'file'})},
+ "blame") . " | ";
print $cgi->a({-href => href(action=>"history", hash_base=>$parent,
- file_name=>$diff{'file'})},
- "history");
+ file_name=>$diff{'file'})},
+ "history");
print " | \n";
} elsif ($diff{'status'} eq "M" || $diff{'status'} eq "T") { # modified, or type changed
@@ -1909,8 +1935,8 @@ sub git_difftree_body {
}
print "";
print $cgi->a({-href => href(action=>"blob", hash=>$diff{'to_id'},
- hash_base=>$hash, file_name=>$diff{'file'}),
- -class => "list"}, esc_html($diff{'file'}));
+ hash_base=>$hash, file_name=>$diff{'file'}),
+ -class => "list"}, esc_html($diff{'file'}));
print " | \n";
print "$mode_chnge | \n";
print "";
@@ -1921,19 +1947,22 @@ sub git_difftree_body {
print $cgi->a({-href => "#patch$patchno"}, "patch");
} else {
print $cgi->a({-href => href(action=>"blobdiff",
- hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},
- hash_base=>$hash, hash_parent_base=>$parent,
- file_name=>$diff{'file'})},
- "diff");
+ hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},
+ hash_base=>$hash, hash_parent_base=>$parent,
+ file_name=>$diff{'file'})},
+ "diff");
}
print " | ";
}
+ print $cgi->a({-href => href(action=>"blob", hash=>$diff{'to_id'},
+ hash_base=>$hash, file_name=>$diff{'file'})},
+ "blob") . " | ";
print $cgi->a({-href => href(action=>"blame", hash_base=>$hash,
- file_name=>$diff{'file'})},
- "blame") . " | ";
+ file_name=>$diff{'file'})},
+ "blame") . " | ";
print $cgi->a({-href => href(action=>"history", hash_base=>$hash,
- file_name=>$diff{'file'})},
- "history");
+ file_name=>$diff{'file'})},
+ "history");
print " | \n";
} elsif ($diff{'status'} eq "R" || $diff{'status'} eq "C") { # renamed or copied
@@ -1961,19 +1990,22 @@ sub git_difftree_body {
print $cgi->a({-href => "#patch$patchno"}, "patch");
} else {
print $cgi->a({-href => href(action=>"blobdiff",
- hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},
- hash_base=>$hash, hash_parent_base=>$parent,
- file_name=>$diff{'to_file'}, file_parent=>$diff{'from_file'})},
- "diff");
+ hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},
+ hash_base=>$hash, hash_parent_base=>$parent,
+ file_name=>$diff{'to_file'}, file_parent=>$diff{'from_file'})},
+ "diff");
}
print " | ";
}
+ print $cgi->a({-href => href(action=>"blob", hash=>$diff{'from_id'},
+ hash_base=>$parent, file_name=>$diff{'from_file'})},
+ "blob") . " | ";
print $cgi->a({-href => href(action=>"blame", hash_base=>$parent,
- file_name=>$diff{'from_file'})},
- "blame") . " | ";
+ file_name=>$diff{'from_file'})},
+ "blame") . " | ";
print $cgi->a({-href => href(action=>"history", hash_base=>$parent,
- file_name=>$diff{'from_file'})},
- "history");
+ file_name=>$diff{'from_file'})},
+ "history");
print "\n";
} # we should not encounter Unmerged (U) or Unknown (X) status
@@ -2135,6 +2167,7 @@ sub git_shortlog_body {
href(action=>"commit", hash=>$commit), $ref);
print "\n" .
"" .
+ $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") . " | " .
$cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff") . " | " .
$cgi->a({-href => href(action=>"tree", hash=>$commit, hash_base=>$commit)}, "tree");
if (gitweb_have_snapshot()) {
@@ -2329,16 +2362,11 @@ sub git_project_list {
die_error(undef, "No projects found");
}
foreach my $pr (@list) {
- my $head = git_get_head_hash($pr->{'path'});
- if (!defined $head) {
- next;
- }
- $git_dir = "$projectroot/$pr->{'path'}";
- my %co = parse_commit($head);
- if (!%co) {
+ my (@aa) = git_get_last_activity($pr->{'path'});
+ unless (@aa) {
next;
}
- $pr->{'commit'} = \%co;
+ ($pr->{'age'}, $pr->{'age_string'}) = @aa;
if (!defined $pr->{'descr'}) {
my $descr = git_get_project_description($pr->{'path'}) || "";
$pr->{'descr'} = chop_str($descr, 25, 5);
@@ -2388,7 +2416,7 @@ sub git_project_list {
"\n";
}
if ($order eq "age") {
- @projects = sort {$a->{'commit'}{'age'} <=> $b->{'commit'}{'age'}} @projects;
+ @projects = sort {$a->{'age'} <=> $b->{'age'}} @projects;
print " | Last Change | \n";
} else {
print "" .
@@ -2410,8 +2438,8 @@ sub git_project_list {
-class => "list"}, esc_html($pr->{'path'})) . "\n" .
" | " . esc_html($pr->{'descr'}) . " | \n" .
"" . chop_str($pr->{'owner'}, 15) . " | \n";
- print "{'commit'}{'age'}) . "\">" .
- $pr->{'commit'}{'age_string'} . " | \n" .
+ print "{'age'}) . "\">" .
+ $pr->{'age_string'} . " | \n" .
"" .
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary")}, "summary") . " | " .
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"shortlog")}, "shortlog") . " | " .
@@ -2910,7 +2938,7 @@ sub git_tree {
my $refs = git_get_references();
my $ref = format_ref_marker($refs, $hash_base);
git_header_html();
- my $base = "";
+ my $basedir = '';
my ($have_blame) = gitweb_check_feature('blame');
if (defined $hash_base && (my %co = parse_commit($hash_base))) {
my @views_nav = ();
@@ -2927,7 +2955,7 @@ sub git_tree {
# FIXME: Should be available when we have no hash base as well.
push @views_nav,
$cgi->a({-href => href(action=>"snapshot", hash=>$hash)},
- "snapshot");
+ "snapshot");
}
git_print_page_nav('tree','', $hash_base, undef, undef, join(' | ', @views_nav));
git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash_base);
@@ -2938,12 +2966,39 @@ sub git_tree {
print " $hash \n";
}
if (defined $file_name) {
- $base = esc_html("$file_name/");
+ $basedir = $file_name;
+ if ($basedir ne '' && substr($basedir, -1) ne '/') {
+ $basedir .= '/';
+ }
}
git_print_page_path($file_name, 'tree', $hash_base);
print "\n";
print " \n";
my $alternate = 1;
+ # '..' (top directory) link if possible
+ if (defined $hash_base &&
+ defined $file_name && $file_name =~ m![^/]+$!) {
+ if ($alternate) {
+ print "\n";
+ } else {
+ print " \n";
+ }
+ $alternate ^= 1;
+
+ my $up = $file_name;
+ $up =~ s!/?[^/]+$!!;
+ undef $up unless $up;
+ # based on git_print_tree_entry
+ print '| ' . mode_str('040000') . " | \n";
+ print '';
+ print $cgi->a({-href => href(action=>"tree", hash_base=>$hash_base,
+ file_name=>$up)},
+ "..");
+ print " | \n";
+ print " | \n";
+
+ print " \n";
+ }
foreach my $line (@entries) {
my %t = parse_ls_tree_line($line, -z => 1);
@@ -2954,7 +3009,7 @@ sub git_tree {
}
$alternate ^= 1;
- git_print_tree_entry(\%t, $base, $hash_base, $have_blame);
+ git_print_tree_entry(\%t, $basedir, $hash_base, $have_blame);
print "\n";
}
|