\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;
- }
+ # read and prepare patch information
+ $diffinfo = parsed_difftree_line($difftree->[$patch_idx]);
- 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]);
- }
-
- # 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"; # 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;
@@ -3286,16 +3533,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" .
@@ -3423,7 +3665,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" .
"
" .
@@ -3453,7 +3695,7 @@ sub git_shortlog_body {
$from = 0 unless defined $from;
$to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to);
- print "\n";
+ print "\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my %co = %{$commitlist->[$i]};
@@ -3465,9 +3707,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);
@@ -3498,7 +3741,7 @@ sub git_history_body {
$from = 0 unless defined $from;
$to = $#{$commitlist} unless (defined $to && $to <= $#{$commitlist});
- print "\n";
+ print "\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my %co = %{$commitlist->[$i]};
@@ -3515,9 +3758,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'},
@@ -3557,7 +3801,7 @@ sub git_tags_body {
$from = 0 unless defined $from;
$to = $#{$taglist} if (!defined $to || $#{$taglist} < $to);
- print "\n";
+ print "\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my $entry = $taglist->[$i];
@@ -3598,8 +3842,8 @@ sub git_tags_body {
"" . " | " .
$cgi->a({-href => href(action=>$tag{'reftype'}, hash=>$tag{'refid'})}, $tag{'reftype'});
if ($tag{'reftype'} eq "commit") {
- print " | " . $cgi->a({-href => href(action=>"shortlog", hash=>$tag{'name'})}, "shortlog") .
- " | " . $cgi->a({-href => href(action=>"log", hash=>$tag{'name'})}, "log");
+ print " | " . $cgi->a({-href => href(action=>"shortlog", hash=>$tag{'fullname'})}, "shortlog") .
+ " | " . $cgi->a({-href => href(action=>"log", hash=>$tag{'fullname'})}, "log");
} elsif ($tag{'reftype'} eq "blob") {
print " | " . $cgi->a({-href => href(action=>"blob_plain", hash=>$tag{'refid'})}, "raw");
}
@@ -3620,7 +3864,7 @@ sub git_heads_body {
$from = 0 unless defined $from;
$to = $#{$headlist} if (!defined $to || $#{$headlist} < $to);
- print "\n";
+ print "\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my $entry = $headlist->[$i];
@@ -3634,13 +3878,13 @@ sub git_heads_body {
$alternate ^= 1;
print "| $ref{'age'} | \n" .
($curr ? "" : " | ") .
- $cgi->a({-href => href(action=>"shortlog", hash=>$ref{'name'}),
+ $cgi->a({-href => href(action=>"shortlog", hash=>$ref{'fullname'}),
-class => "list name"},esc_html($ref{'name'})) .
" | \n" .
"" .
- $cgi->a({-href => href(action=>"shortlog", hash=>$ref{'name'})}, "shortlog") . " | " .
- $cgi->a({-href => href(action=>"log", hash=>$ref{'name'})}, "log") . " | " .
- $cgi->a({-href => href(action=>"tree", hash=>$ref{'name'}, hash_base=>$ref{'name'})}, "tree") .
+ $cgi->a({-href => href(action=>"shortlog", hash=>$ref{'fullname'})}, "shortlog") . " | " .
+ $cgi->a({-href => href(action=>"log", hash=>$ref{'fullname'})}, "log") . " | " .
+ $cgi->a({-href => href(action=>"tree", hash=>$ref{'fullname'}, hash_base=>$ref{'name'})}, "tree") .
" | \n" .
"";
}
@@ -3657,7 +3901,7 @@ sub git_search_grep_body {
$from = 0 unless defined $from;
$to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to);
- print "\n";
+ print "\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my %co = %{$commitlist->[$i]};
@@ -3671,27 +3915,36 @@ 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)) . " ");
+ $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}),
+ -class => "list subject"},
+ chop_and_escape_str($co{'title'}, 50) . " ");
my $comment = $co{'comment'};
foreach my $line (@$comment) {
- if ($line =~ m/^(.*)($search_regexp)(.*)$/i) {
- my $lead = esc_html($1) || "";
- $lead = chop_str($lead, 30, 10);
- my $match = esc_html($2) || "";
- my $trail = esc_html($3) || "";
- $trail = chop_str($trail, 30, 10);
- my $text = "$lead$match$trail";
- print chop_str($text, 80, 5) . " \n";
+ if ($line =~ m/^(.*?)($search_regexp)(.*)$/i) {
+ my ($lead, $match, $trail) = ($1, $2, $3);
+ $match = chop_str($match, 70, 5, 'center');
+ my $contextlen = int((80 - length($match))/2);
+ $contextlen = 30 if ($contextlen > 30);
+ $lead = chop_str($lead, $contextlen, 10, 'left');
+ $trail = chop_str($trail, $contextlen, 10, 'right');
+
+ $lead = esc_html($lead);
+ $match = esc_html($match);
+ $trail = esc_html($trail);
+
+ print "$lead$match$trail ";
}
}
print " | \n" .
"" .
$cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, "commit") .
" | " .
+ $cgi->a({-href => href(action=>"commitdiff", hash=>$co{'id'})}, "commitdiff") .
+ " | " .
$cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$co{'id'})}, "tree");
print " | \n" .
" \n";
@@ -3797,9 +4050,9 @@ sub git_summary {
git_print_page_nav('summary','', $head);
print " \n";
- 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";
}
@@ -3818,8 +4071,10 @@ sub git_summary {
if (-s "$projectroot/$project/README.html") {
if (open my $fd, "$projectroot/$project/README.html") {
- print "readme \n";
+ print "readme \n" .
+ "\n";
print $_ while (<$fd>);
+ print "\n \n"; # class="readme"
close $fd;
}
}
@@ -3871,7 +4126,7 @@ sub git_tag {
git_print_header_div('commit', esc_html($tag{'name'}), $hash);
print "\n" .
- " \n" .
+ "\n\n";
- close $fd
- or print "Reading blob failed.\n";
- print "";
- git_footer_html();
-}
-
sub git_tags {
my $head = git_get_head_hash($project);
git_header_html();
@@ -4130,6 +4288,7 @@ sub git_heads {
}
sub git_blob_plain {
+ my $type = shift;
my $expires;
if (!defined $hash) {
@@ -4145,13 +4304,13 @@ sub git_blob_plain {
$expires = "+1d";
}
- my $type = shift;
open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash
- or die_error(undef, "Couldn't cat $file_name, $hash");
+ or die_error(undef, "Open git-cat-file blob '$hash' failed");
- $type ||= blob_mimetype($fd, $file_name);
+ # content-type (can include charset)
+ $type = blob_contenttype($fd, $file_name, $type);
- # save as filename, even when no $file_name is given
+ # "save as" filename, even when no $file_name is given
my $save_as = "$hash";
if (defined $file_name) {
$save_as = $file_name;
@@ -4160,9 +4319,9 @@ sub git_blob_plain {
}
print $cgi->header(
- -type => "$type",
- -expires=>$expires,
- -content_disposition => 'inline; filename="' . "$save_as" . '"');
+ -type => $type,
+ -expires => $expires,
+ -content_disposition => 'inline; filename="' . $save_as . '"');
undef $/;
binmode STDOUT, ':raw';
print <$fd>;
@@ -4191,7 +4350,7 @@ sub git_blob {
open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash
or die_error(undef, "Couldn't cat $file_name, $hash");
my $mimetype = blob_mimetype($fd, $file_name);
- if ($mimetype !~ m!^(?:text/|image/(?:gif|png|jpeg)$)!) {
+ if ($mimetype !~ m!^(?:text/|image/(?:gif|png|jpeg)$)! && -B $fd) {
close $fd;
return git_blob_plain($mimetype);
}
@@ -4204,18 +4363,15 @@ sub git_blob {
if (defined $file_name) {
if ($have_blame) {
$formats_nav .=
- $cgi->a({-href => href(action=>"blame", hash_base=>$hash_base,
- hash=>$hash, file_name=>$file_name)},
+ $cgi->a({-href => href(action=>"blame", -replay=>1)},
"blame") .
" | ";
}
$formats_nav .=
- $cgi->a({-href => href(action=>"history", hash_base=>$hash_base,
- hash=>$hash, file_name=>$file_name)},
+ $cgi->a({-href => href(action=>"history", -replay=>1)},
"history") .
" | " .
- $cgi->a({-href => href(action=>"blob_plain",
- hash=>$hash, file_name=>$file_name)},
+ $cgi->a({-href => href(action=>"blob_plain", -replay=>1)},
"raw") .
" | " .
$cgi->a({-href => href(action=>"blob",
@@ -4223,7 +4379,8 @@ sub git_blob {
"HEAD");
} else {
$formats_nav .=
- $cgi->a({-href => href(action=>"blob_plain", hash=>$hash)}, "raw");
+ $cgi->a({-href => href(action=>"blob_plain", -replay=>1)},
+ "raw");
}
git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);
git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
@@ -4234,16 +4391,7 @@ sub git_blob {
}
git_print_page_path($file_name, "blob", $hash_base);
print "\n";
- if ($mimetype =~ m!^text/!) {
- my $nr;
- while (my $line = <$fd>) {
- chomp $line;
- $nr++;
- $line = untabify($line);
- printf " \n",
- $nr, $nr, $nr, esc_html($line, -nbsp=>1);
- }
- } elsif ($mimetype =~ m!^image/!) {
+ if ($mimetype =~ m!^image/!) {
print qq! ![$file_name $file_name]() "blob_plain", hash=>$hash,
hash_base=>$hash_base, file_name=>$file_name) .
qq!" />\n!;
+ } else {
+ my $nr;
+ while (my $line = <$fd>) {
+ chomp $line;
+ $nr++;
+ $line = untabify($line);
+ printf " \n",
+ $nr, $nr, $nr, esc_html($line, -nbsp=>1);
+ }
}
close $fd
or print "Reading blob failed.\n";
@@ -4286,8 +4443,7 @@ sub git_tree {
my @views_nav = ();
if (defined $file_name) {
push @views_nav,
- $cgi->a({-href => href(action=>"history", hash_base=>$hash_base,
- hash=>$hash, file_name=>$file_name)},
+ $cgi->a({-href => href(action=>"history", -replay=>1)},
"history"),
$cgi->a({-href => href(action=>"tree",
hash_base=>"HEAD", file_name=>$file_name)},
@@ -4314,7 +4470,7 @@ sub git_tree {
}
git_print_page_path($file_name, 'tree', $hash_base);
print " \n";
- print " \n";
+ print "\n";
my $alternate = 1;
# '..' (top directory) link if possible
if (defined $hash_base &&
@@ -4421,7 +4577,7 @@ sub git_log {
my @commitlist = parse_commits($hash, 101, (100 * $page));
- my $paging_nav = format_paging_nav('log', $hash, $head, $page, (100 * ($page+1)));
+ my $paging_nav = format_paging_nav('log', $hash, $head, $page, $#commitlist >= 100);
git_header_html();
git_print_page_nav('log','', $hash,undef,undef, $paging_nav);
@@ -4461,7 +4617,7 @@ sub git_log {
}
if ($#commitlist >= 100) {
print "\n";
- print $cgi->a({-href => href(action=>"log", hash=>$hash, page=>$page+1),
+ print $cgi->a({-href => href(-replay=>1, page=>$page+1),
-accesskey => "n", -title => "Alt-n"}, "next");
print " \n";
}
@@ -4536,7 +4692,7 @@ sub git_commit {
git_print_header_div('tree', esc_html($co{'title'}) . $ref, $co{'tree'}, $hash);
}
print " | | | |