X-Git-Url: https://git.ladys.computer/Gitweb/blobdiff_plain/85a65aae31d2f92f43bc9b714c55bac8c86db1801824462af22cb3104952d47b..5293f94aa5ef7e27b0820bee97e6f682ed73041bee040a36057d0b325db1e4e8:/gitweb.perl
diff --git a/gitweb.perl b/gitweb.perl
index d33068a..dd81a9e 100755
--- a/gitweb.perl
+++ b/gitweb.perl
@@ -35,6 +35,10 @@ our $GIT = "++GIT_BINDIR++/git";
#our $projectroot = "/pub/scm";
our $projectroot = "++GITWEB_PROJECTROOT++";
+# fs traversing limit for getting project list
+# the number is relative to the projectroot
+our $project_maxdepth = "++GITWEB_PROJECT_MAXDEPTH++";
+
# target of the home link on top of all pages
our $home_link = $my_uri || "/";
@@ -437,12 +441,11 @@ my %allowed_options = (
our @extra_options = $cgi->param('opt');
if (defined @extra_options) {
- foreach(@extra_options)
- {
- if (not grep(/^$_$/, keys %allowed_options)) {
+ foreach my $opt (@extra_options) {
+ if (not exists $allowed_options{$opt}) {
die_error(undef, "Invalid option parameter");
}
- if (not grep(/^$action$/, @{$allowed_options{$_}})) {
+ if (not grep(/^$action$/, @{$allowed_options{$opt}})) {
die_error(undef, "Invalid option parameter for this action");
}
}
@@ -473,9 +476,6 @@ if (defined $searchtype) {
our $searchtext = $cgi->param('s');
our $search_regexp;
if (defined $searchtext) {
- if ($searchtype ne 'grep' and $searchtype ne 'pickaxe' and $searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) {
- die_error(undef, "Invalid search parameter");
- }
if (length($searchtext) < 2) {
die_error(undef, "At least two characters are required for search parameter");
}
@@ -599,7 +599,6 @@ sub href(%) {
action => "a",
file_name => "f",
file_parent => "fp",
- extra_options => "opt",
hash => "h",
hash_parent => "hp",
hash_base => "hb",
@@ -609,6 +608,7 @@ sub href(%) {
searchtext => "s",
searchtype => "st",
snapshot_format => "sf",
+ extra_options => "opt",
);
my %mapping = @mapping;
@@ -631,7 +631,13 @@ sub href(%) {
for (my $i = 0; $i < @mapping; $i += 2) {
my ($name, $symbol) = ($mapping[$i], $mapping[$i+1]);
if (defined $params{$name}) {
- push @result, $symbol . "=" . esc_param($params{$name});
+ if (ref($params{$name}) eq "ARRAY") {
+ foreach my $par (@{$params{$name}}) {
+ push @result, $symbol . "=" . esc_param($par);
+ }
+ } else {
+ push @result, $symbol . "=" . esc_param($params{$name});
+ }
}
}
$href .= "?" . join(';', @result) if scalar @result;
@@ -841,6 +847,23 @@ sub chop_str {
return "$body$tail";
}
+# takes the same arguments as chop_str, but also wraps a around the
+# result with a title attribute if it does get chopped. Additionally, the
+# string is HTML-escaped.
+sub chop_and_escape_str {
+ my $str = shift;
+ my $len = shift;
+ my $add_len = shift || 10;
+
+ my $chopped = chop_str($str, $len, $add_len);
+ if ($chopped eq $str) {
+ return esc_html($chopped);
+ } else {
+ return qq{} .
+ esc_html($chopped) . qq{ };
+ }
+}
+
## ----------------------------------------------------------------------
## functions returning short strings
@@ -891,11 +914,25 @@ sub age_string {
return $age_str;
}
+use constant {
+ S_IFINVALID => 0030000,
+ S_IFGITLINK => 0160000,
+};
+
+# submodule/subproject, a commit object reference
+sub S_ISGITLINK($) {
+ my $mode = shift;
+
+ return (($mode & S_IFMT) == S_IFGITLINK)
+}
+
# convert file mode in octal to symbolic file mode string
sub mode_str {
my $mode = oct shift;
- if (S_ISDIR($mode & S_IFMT)) {
+ if (S_ISGITLINK($mode)) {
+ return 'm---------';
+ } elsif (S_ISDIR($mode & S_IFMT)) {
return 'drwxr-xr-x';
} elsif (S_ISLNK($mode)) {
return 'lrwxrwxrwx';
@@ -921,7 +958,9 @@ sub file_type {
$mode = oct $mode;
}
- if (S_ISDIR($mode & S_IFMT)) {
+ if (S_ISGITLINK($mode)) {
+ return "submodule";
+ } elsif (S_ISDIR($mode & S_IFMT)) {
return "directory";
} elsif (S_ISLNK($mode)) {
return "symlink";
@@ -942,7 +981,9 @@ sub file_type_long {
$mode = oct $mode;
}
- if (S_ISDIR($mode & S_IFMT)) {
+ if (S_ISGITLINK($mode)) {
+ return "submodule";
+ } elsif (S_ISDIR($mode & S_IFMT)) {
return "directory";
} elsif (S_ISLNK($mode)) {
return "symlink";
@@ -1490,15 +1531,22 @@ sub git_get_projects_list {
# remove the trailing "/"
$dir =~ s!/+$!!;
my $pfxlen = length("$dir");
+ my $pfxdepth = ($dir =~ tr!/!!);
File::Find::find({
follow_fast => 1, # follow symbolic links
+ follow_skip => 2, # ignore duplicates
dangling_symlinks => 0, # ignore dangling symlinks, silently
wanted => sub {
# skip project-list toplevel, if we get it.
return if (m!^[/.]$!);
# only directories can be git repositories
return unless (-d $_);
+ # don't traverse too deep (Find is super slow on os x)
+ if (($File::Find::name =~ tr!/!!) - $pfxdepth > $project_maxdepth) {
+ $File::Find::prune = 1;
+ return;
+ }
my $subdir = substr($File::Find::name, $pfxlen + 1);
# we check related file in $projectroot
@@ -1943,12 +1991,12 @@ sub parse_difftree_raw_line {
$res{'to_mode'} = $2;
$res{'from_id'} = $3;
$res{'to_id'} = $4;
- $res{'status'} = $5;
+ $res{'status'} = $res{'status_str'} = $5;
$res{'similarity'} = $6;
if ($res{'status'} eq 'R' || $res{'status'} eq 'C') { # renamed or copied
($res{'from_file'}, $res{'to_file'}) = map { unquote($_) } split("\t", $7);
} else {
- $res{'file'} = unquote($7);
+ $res{'from_file'} = $res{'to_file'} = $res{'file'} = unquote($7);
}
}
# '::100755 100755 100755 60e79ca1b01bc8b057abe17ddab484699a7f5fdb 94067cc5f73388f33722d52ae02f44692bc07490 94067cc5f73388f33722d52ae02f44692bc07490 MR git-gui/git-gui.sh'
@@ -1959,6 +2007,7 @@ sub parse_difftree_raw_line {
$res{'to_mode'} = pop @{$res{'from_mode'}};
$res{'from_id'} = [ split(' ', $3) ];
$res{'to_id'} = pop @{$res{'from_id'}};
+ $res{'status_str'} = $4;
$res{'status'} = [ split('', $4) ];
$res{'to_file'} = unquote($5);
}
@@ -1970,6 +2019,19 @@ sub parse_difftree_raw_line {
return wantarray ? %res : \%res;
}
+# wrapper: return parsed line of git-diff-tree "raw" output
+# (the argument might be raw line, or parsed info)
+sub parsed_difftree_line {
+ my $line_or_ref = shift;
+
+ if (ref($line_or_ref) eq "HASH") {
+ # pre-parsed (or generated by hand)
+ return $line_or_ref;
+ } else {
+ return parse_difftree_raw_line($line_or_ref);
+ }
+}
+
# parse line of git-ls-tree output
sub parse_ls_tree_line ($;%) {
my $line = shift;
@@ -2002,7 +2064,10 @@ sub parse_from_to_diffinfo {
fill_from_file_info($diffinfo, @parents)
unless exists $diffinfo->{'from_file'};
for (my $i = 0; $i < $diffinfo->{'nparents'}; $i++) {
- $from->{'file'}[$i] = $diffinfo->{'from_file'}[$i] || $diffinfo->{'to_file'};
+ $from->{'file'}[$i] =
+ defined $diffinfo->{'from_file'}[$i] ?
+ $diffinfo->{'from_file'}[$i] :
+ $diffinfo->{'to_file'};
if ($diffinfo->{'status'}[$i] ne "A") { # not new (added) file
$from->{'href'}[$i] = href(action=>"blob",
hash_base=>$parents[$i],
@@ -2013,7 +2078,8 @@ sub parse_from_to_diffinfo {
}
}
} else {
- $from->{'file'} = $diffinfo->{'from_file'} || $diffinfo->{'file'};
+ # ordinary (not combined) diff
+ $from->{'file'} = $diffinfo->{'from_file'};
if ($diffinfo->{'status'} ne "A") { # not new (added) file
$from->{'href'} = href(action=>"blob", hash_base=>$hash_parent,
hash=>$diffinfo->{'from_id'},
@@ -2023,7 +2089,7 @@ sub parse_from_to_diffinfo {
}
}
- $to->{'file'} = $diffinfo->{'to_file'} || $diffinfo->{'file'};
+ $to->{'file'} = $diffinfo->{'to_file'};
if (!is_deleted($diffinfo)) { # file exists in result
$to->{'href'} = href(action=>"blob", hash_base=>$hash,
hash=>$diffinfo->{'to_id'},
@@ -2268,9 +2334,17 @@ EOF
printf(' '."\n",
esc_param($project), href(action=>"rss"));
+ printf(' '."\n",
+ esc_param($project), href(action=>"rss",
+ extra_options=>"--no-merges"));
printf(' '."\n",
esc_param($project), href(action=>"atom"));
+ printf(' '."\n",
+ esc_param($project), href(action=>"atom",
+ extra_options=>"--no-merges"));
} else {
printf(' '."\n",
@@ -2708,12 +2782,27 @@ sub git_print_tree_entry {
"history");
}
print "\n";
+ } else {
+ # unknown object: we can only present history for it
+ # (this includes 'commit' object, i.e. submodule support)
+ print "
" .
+ esc_path($t->{'name'}) .
+ " \n";
+ print "";
+ if (defined $hash_base) {
+ print $cgi->a({-href => href(action=>"history",
+ hash_base=>$hash_base,
+ file_name=>"$basedir$t->{'name'}")},
+ "history");
+ }
+ print " \n";
}
}
## ......................................................................
## functions printing large fragments of HTML
+# get pre-image filenames for merge (combined) diff
sub fill_from_file_info {
my ($diff, @parents) = @_;
@@ -2730,28 +2819,25 @@ sub fill_from_file_info {
return $diff;
}
-# parameters can be strings, or references to arrays of strings
-sub from_ids_eq {
- my ($a, $b) = @_;
+# is current raw difftree line of file deletion
+sub is_deleted {
+ my $diffinfo = shift;
- if (ref($a) eq "ARRAY" && ref($b) eq "ARRAY" && @$a == @$b) {
- for (my $i = 0; $i < @$a; ++$i) {
- return 0 unless ($a->[$i] eq $b->[$i]);
- }
- return 1;
- } elsif (!ref($a) && !ref($b)) {
- return $a eq $b;
- } else {
- return 0;
- }
+ return $diffinfo->{'status_str'} =~ /D/;
}
-sub is_deleted {
- my $diffinfo = shift;
+# does patch correspond to [previous] difftree raw line
+# $diffinfo - hashref of parsed raw diff format
+# $patchinfo - hashref of parsed patch diff format
+# (the same keys as in $diffinfo)
+sub is_patch_split {
+ my ($diffinfo, $patchinfo) = @_;
- return $diffinfo->{'to_id'} eq ('0' x 40);
+ return defined $diffinfo && defined $patchinfo
+ && $diffinfo->{'to_file'} eq $patchinfo->{'to_file'};
}
+
sub git_difftree_body {
my ($difftree, $hash, @parents) = @_;
my ($parent) = $parents[0];
@@ -2767,7 +2853,7 @@ sub git_difftree_body {
"diff_tree\">\n";
# header only for combined diff in 'commitdiff' view
- my $has_header = @parents > 1 && $action eq 'commitdiff';
+ my $has_header = @$difftree && @parents > 1 && $action eq 'commitdiff';
if ($has_header) {
# table header
print "\n" .
@@ -2788,13 +2874,7 @@ sub git_difftree_body {
my $alternate = 1;
my $patchno = 0;
foreach my $line (@{$difftree}) {
- my $diff;
- if (ref($line) eq "HASH") {
- # pre-parsed (or generated by hand)
- $diff = $line;
- } else {
- $diff = parse_difftree_raw_line($line);
- }
+ my $diff = parsed_difftree_line($line);
if ($alternate) {
print " \n";
@@ -3065,10 +3145,12 @@ sub git_patchset_body {
my ($fd, $difftree, $hash, @hash_parents) = @_;
my ($hash_parent) = $hash_parents[0];
+ my $is_combined = (@hash_parents > 1);
my $patch_idx = 0;
my $patch_number = 0;
my $patch_line;
my $diffinfo;
+ my $to_name;
my (%from, %to);
print "\n";
@@ -3082,140 +3164,85 @@ sub git_patchset_body {
PATCH:
while ($patch_line) {
- my @diff_header;
- my ($from_id, $to_id);
-
- # git diff header
- #assert($patch_line =~ m/^diff /) if DEBUG;
- #assert($patch_line !~ m!$/$!) if DEBUG; # is chomp-ed
- $patch_number++;
- push @diff_header, $patch_line;
-
- # extended diff header
- EXTENDED_HEADER:
- while ($patch_line = <$fd>) {
- chomp $patch_line;
-
- last EXTENDED_HEADER if ($patch_line =~ m/^--- |^diff /);
- if ($patch_line =~ m/^index ([0-9a-fA-F]{40})..([0-9a-fA-F]{40})/) {
- $from_id = $1;
- $to_id = $2;
- } elsif ($patch_line =~ m/^index ((?:[0-9a-fA-F]{40},)+[0-9a-fA-F]{40})..([0-9a-fA-F]{40})/) {
- $from_id = [ split(',', $1) ];
- $to_id = $2;
- }
-
- push @diff_header, $patch_line;
+ # parse "git diff" header line
+ if ($patch_line =~ m/^diff --git (\"(?:[^\\\"]*(?:\\.[^\\\"]*)*)\"|[^ "]*) (.*)$/) {
+ # $1 is from_name, which we do not use
+ $to_name = unquote($2);
+ $to_name =~ s!^b/!!;
+ } elsif ($patch_line =~ m/^diff --(cc|combined) ("?.*"?)$/) {
+ # $1 is 'cc' or 'combined', which we do not use
+ $to_name = unquote($2);
+ } else {
+ $to_name = undef;
}
- my $last_patch_line = $patch_line;
# check if current patch belong to current raw line
# and parse raw git-diff line if needed
- if (defined $diffinfo &&
- defined $from_id && defined $to_id &&
- from_ids_eq($diffinfo->{'from_id'}, $from_id) &&
- $diffinfo->{'to_id'} eq $to_id) {
+ if (is_patch_split($diffinfo, { 'to_file' => $to_name })) {
# this is continuation of a split patch
print "
\n";
} else {
# advance raw git-diff output if needed
$patch_idx++ if defined $diffinfo;
- # compact combined diff output can have some patches skipped
- # find which patch (using pathname of result) we are at now
- my $to_name;
- if ($diff_header[0] =~ m!^diff --cc "?(.*)"?$!) {
- $to_name = $1;
- }
-
- do {
- # read and prepare patch information
- if (ref($difftree->[$patch_idx]) eq "HASH") {
- # pre-parsed (or generated by hand)
- $diffinfo = $difftree->[$patch_idx];
- } else {
- $diffinfo = parse_difftree_raw_line($difftree->[$patch_idx]);
- }
+ # read and prepare patch information
+ $diffinfo = parsed_difftree_line($difftree->[$patch_idx]);
- # check if current raw line has no patch (it got simplified)
- if (defined $to_name && $to_name ne $diffinfo->{'to_file'}) {
+ # compact combined diff output can have some patches skipped
+ # find which patch (using pathname of result) we are at now;
+ if ($is_combined) {
+ while ($to_name ne $diffinfo->{'to_file'}) {
print "
\n" .
format_diff_cc_simplified($diffinfo, @hash_parents) .
"
\n"; # class="patch"
$patch_idx++;
$patch_number++;
+
+ last if $patch_idx > $#$difftree;
+ $diffinfo = parsed_difftree_line($difftree->[$patch_idx]);
}
- } until (!defined $to_name || $to_name eq $diffinfo->{'to_file'} ||
- $patch_idx > $#$difftree);
+ }
+
# modifies %from, %to hashes
parse_from_to_diffinfo($diffinfo, \%from, \%to, @hash_parents);
- if ($diffinfo->{'nparents'}) {
- # combined diff
- $from{'file'} = [];
- $from{'href'} = [];
- fill_from_file_info($diffinfo, @hash_parents)
- unless exists $diffinfo->{'from_file'};
- for (my $i = 0; $i < $diffinfo->{'nparents'}; $i++) {
- $from{'file'}[$i] = $diffinfo->{'from_file'}[$i] || $diffinfo->{'to_file'};
- if ($diffinfo->{'status'}[$i] ne "A") { # not new (added) file
- $from{'href'}[$i] = href(action=>"blob",
- hash_base=>$hash_parents[$i],
- hash=>$diffinfo->{'from_id'}[$i],
- file_name=>$from{'file'}[$i]);
- } else {
- $from{'href'}[$i] = undef;
- }
- }
- } else {
- $from{'file'} = $diffinfo->{'from_file'} || $diffinfo->{'file'};
- if ($diffinfo->{'status'} ne "A") { # not new (added) file
- $from{'href'} = href(action=>"blob", hash_base=>$hash_parent,
- hash=>$diffinfo->{'from_id'},
- file_name=>$from{'file'});
- } else {
- delete $from{'href'};
- }
- }
- $to{'file'} = $diffinfo->{'to_file'} || $diffinfo->{'file'};
- if (!is_deleted($diffinfo)) { # file exists in result
- $to{'href'} = href(action=>"blob", hash_base=>$hash,
- hash=>$diffinfo->{'to_id'},
- file_name=>$to{'file'});
- } else {
- delete $to{'href'};
- }
# this is first patch for raw difftree line with $patch_idx index
# we index @$difftree array from 0, but number patches from 1
print "
\n";
}
+ # git diff header
+ #assert($patch_line =~ m/^diff /) if DEBUG;
+ #assert($patch_line !~ m!$/$!) if DEBUG; # is chomp-ed
+ $patch_number++;
# print "git diff" header
- $patch_line = shift @diff_header;
print format_git_diff_header_line($patch_line, $diffinfo,
\%from, \%to);
# print extended diff header
- print "
\n" if (@diff_header > 0);
+ print "
\n";
EXTENDED_HEADER:
- foreach $patch_line (@diff_header) {
+ while ($patch_line = <$fd>) {
+ chomp $patch_line;
+
+ last EXTENDED_HEADER if ($patch_line =~ m/^--- |^diff /);
+
print format_extended_diff_header_line($patch_line, $diffinfo,
\%from, \%to);
}
- print "
\n" if (@diff_header > 0); # class="diff extended_header"
+ print "
\n"; # class="diff extended_header"
# from-file/to-file diff header
- $patch_line = $last_patch_line;
if (! $patch_line) {
print "
\n"; # class="patch"
last PATCH;
}
next PATCH if ($patch_line =~ m/^diff /);
#assert($patch_line =~ m/^---/) if DEBUG;
- #assert($patch_line eq $last_patch_line) if DEBUG;
+ my $last_patch_line = $patch_line;
$patch_line = <$fd>;
chomp $patch_line;
#assert($patch_line =~ m/^\+\+\+/) if DEBUG;
@@ -3240,16 +3267,11 @@ sub git_patchset_body {
# for compact combined (--cc) format, with chunk and patch simpliciaction
# patchset might be empty, but there might be unprocessed raw lines
- for ($patch_idx++ if $patch_number > 0;
+ for (++$patch_idx if $patch_number > 0;
$patch_idx < @$difftree;
- $patch_idx++) {
+ ++$patch_idx) {
# read and prepare patch information
- if (ref($difftree->[$patch_idx]) eq "HASH") {
- # pre-parsed (or generated by hand)
- $diffinfo = $difftree->[$patch_idx];
- } else {
- $diffinfo = parse_difftree_raw_line($difftree->[$patch_idx]);
- }
+ $diffinfo = parsed_difftree_line($difftree->[$patch_idx]);
# generate anchor for "patch" links in difftree / whatchanged part
print "
\n" .
@@ -3377,7 +3399,7 @@ sub git_project_list_body {
"
" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
-class => "list", -title => $pr->{'descr_long'}},
esc_html($pr->{'descr'})) . " \n" .
- "
" . chop_str($pr->{'owner'}, 15) . " \n";
+ "
" . chop_and_escape_str($pr->{'owner'}, 15) . " \n";
print "
{'age'}) . "\">" .
(defined $pr->{'age_string'} ? $pr->{'age_string'} : "No commits") . " \n" .
"
" .
@@ -3419,9 +3441,10 @@ sub git_shortlog_body {
print " \n";
}
$alternate ^= 1;
+ my $author = chop_and_escape_str($co{'author_name'}, 10);
# git_summary() used print "$co{'age_string'} \n" .
print "$co{'age_string_date'} \n" .
- "" . esc_html(chop_str($co{'author_name'}, 10)) . " \n" .
+ "" . $author . " \n" .
"";
print format_subject_html($co{'title'}, $co{'title_short'},
href(action=>"commit", hash=>$commit), $ref);
@@ -3469,9 +3492,10 @@ sub git_history_body {
print " \n";
}
$alternate ^= 1;
+ # shortlog uses chop_str($co{'author_name'}, 10)
+ my $author = chop_and_escape_str($co{'author_name'}, 15, 3);
print "$co{'age_string_date'} \n" .
- # shortlog uses chop_str($co{'author_name'}, 10)
- "" . esc_html(chop_str($co{'author_name'}, 15, 3)) . " \n" .
+ "" . $author . " \n" .
"";
# originally git_history used chop_str($co{'title'}, 50)
print format_subject_html($co{'title'}, $co{'title_short'},
@@ -3625,11 +3649,12 @@ sub git_search_grep_body {
print " \n";
}
$alternate ^= 1;
+ my $author = chop_and_escape_str($co{'author_name'}, 15, 5);
print "$co{'age_string_date'} \n" .
- "" . esc_html(chop_str($co{'author_name'}, 15, 5)) . " \n" .
+ "" . $author . " \n" .
"" .
$cgi->a({-href => href(action=>"commit", hash=>$co{'id'}), -class => "list subject"},
- esc_html(chop_str($co{'title'}, 50)) . " ");
+ chop_and_escape_str($co{'title'}, 50) . " ");
my $comment = $co{'comment'};
foreach my $line (@$comment) {
if ($line =~ m/^(.*)($search_regexp)(.*)$/i) {
@@ -3753,7 +3778,7 @@ sub git_summary {
print "
\n";
print "\n" .
"description " . esc_html($descr) . " \n" .
- "owner $owner \n";
+ "owner " . esc_html($owner) . " \n";
if (defined $cd{'rfc2822'}) {
print "last change $cd{'rfc2822'} \n";
}
@@ -4318,9 +4343,16 @@ sub git_snapshot {
@supported_fmts = filter_snapshot_fmts(@supported_fmts);
my $format = $cgi->param('sf');
- unless ($format =~ m/[a-z0-9]+/
- && exists($known_snapshot_formats{$format})
- && grep($_ eq $format, @supported_fmts)) {
+ if (!@supported_fmts) {
+ die_error('403 Permission denied', "Permission denied");
+ }
+ # default to first supported snapshot format
+ $format ||= $supported_fmts[0];
+ if ($format !~ m/^[a-z0-9]+$/) {
+ die_error(undef, "Invalid snapshot format parameter");
+ } elsif (!exists($known_snapshot_formats{$format})) {
+ die_error(undef, "Unknown snapshot format");
+ } elsif (!grep($_ eq $format, @supported_fmts)) {
die_error(undef, "Unsupported snapshot format");
}
@@ -4337,7 +4369,7 @@ sub git_snapshot {
my $cmd;
$filename .= "-$hash$known_snapshot_formats{$format}{'suffix'}";
$cmd = "$git_command archive " .
- "--format=$known_snapshot_formats{$format}{'format'}" .
+ "--format=$known_snapshot_formats{$format}{'format'} " .
"--prefix=\'$name\'/ $hash";
if (exists $known_snapshot_formats{$format}{'compressor'}) {
$cmd .= ' | ' . join ' ', @{$known_snapshot_formats{$format}{'compressor'}};
@@ -4640,8 +4672,8 @@ sub git_blobdiff {
}
%diffinfo = parse_difftree_raw_line($difftree[0]);
- $file_parent ||= $diffinfo{'from_file'} || $file_name || $diffinfo{'file'};
- $file_name ||= $diffinfo{'to_file'} || $diffinfo{'file'};
+ $file_parent ||= $diffinfo{'from_file'} || $file_name;
+ $file_name ||= $diffinfo{'to_file'};
$hash_parent ||= $diffinfo{'from_id'};
$hash ||= $diffinfo{'to_id'};
@@ -5132,12 +5164,13 @@ sub git_search {
print "\n";
}
$alternate ^= 1;
+ my $author = chop_and_escape_str($co{'author_name'}, 15, 5);
print "$co{'age_string_date'} \n" .
- "" . esc_html(chop_str($co{'author_name'}, 15, 5)) . " \n" .
+ "" . $author . " \n" .
"" .
$cgi->a({-href => href(action=>"commit", hash=>$co{'id'}),
-class => "list subject"},
- esc_html(chop_str($co{'title'}, 50)) . " ");
+ chop_and_escape_str($co{'title'}, 50) . " ");
while (my $setref = shift @files) {
my %set = %$setref;
print $cgi->a({-href => href(action=>"blob", hash_base=>$co{'id'},
@@ -5314,7 +5347,7 @@ sub git_feed {
# log/feed of current (HEAD) branch, log of given branch, history of file/directory
my $head = $hash || 'HEAD';
- my @commitlist = parse_commits($head, 150);
+ my @commitlist = parse_commits($head, 150, 0, undef, $file_name);
my %latest_commit;
my %latest_date;