@ -1122,6 +1122,31 @@ sub format_diff_from_to_header {
return $result;
return $result;
}
}
# create note for patch simplified by combined diff
sub format_diff_cc_simplified {
my ($diffinfo, @parents) = @_;
my $result = '';
$result .= "<div class=\"diff header\">" .
"diff --cc ";
if (!is_deleted($diffinfo)) {
$result .= $cgi->a({-href => href(action=>"blob",
hash_base=>$hash,
hash=>$diffinfo->{'to_id'},
file_name=>$diffinfo->{'to_file'}),
-class => "path"},
esc_path($diffinfo->{'to_file'}));
} else {
$result .= esc_path($diffinfo->{'to_file'});
}
$result .= "</div>\n" . # class="diff header"
"<div class=\"diff nodifferences\">" .
"Simple merge" .
"</div>\n"; # class="diff nodifferences"
return $result;
}
# format patch (diff) line (not to be used for diff headers)
# format patch (diff) line (not to be used for diff headers)
sub format_diff_line {
sub format_diff_line {
my $line = shift;
my $line = shift;
@ -2973,6 +2998,14 @@ sub git_patchset_body {
# advance raw git-diff output if needed
# advance raw git-diff output if needed
$patch_idx++ if defined $diffinfo;
$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
# read and prepare patch information
if (ref($difftree->[$patch_idx]) eq "HASH") {
if (ref($difftree->[$patch_idx]) eq "HASH") {
# pre-parsed (or generated by hand)
# pre-parsed (or generated by hand)
@ -2980,6 +3013,18 @@ sub git_patchset_body {
} else {
} else {
$diffinfo = parse_difftree_raw_line($difftree->[$patch_idx]);
$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'}) {
print "<div class=\"patch\" id=\"patch". ($patch_idx+1) ."\">\n" .
format_diff_cc_simplified($diffinfo, @hash_parents) .
"</div>\n"; # class="patch"
$patch_idx++;
$patch_number++;
}
} until (!defined $to_name || $to_name eq $diffinfo->{'to_file'} ||
$patch_idx > $#$difftree);
# modifies %from, %to hashes
# modifies %from, %to hashes
parse_from_to_diffinfo($diffinfo, \%from, \%to, @hash_parents);
parse_from_to_diffinfo($diffinfo, \%from, \%to, @hash_parents);
if ($diffinfo->{'nparents'}) {
if ($diffinfo->{'nparents'}) {
@ -3069,6 +3114,27 @@ sub git_patchset_body {
print "</div>\n"; # class="patch"
print "</div>\n"; # class="patch"
}
}
# 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;
$patch_idx < @$difftree;
$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]);
}
# generate anchor for "patch" links in difftree / whatchanged part
print "<div class=\"patch\" id=\"patch". ($patch_idx+1) ."\">\n" .
format_diff_cc_simplified($diffinfo, @hash_parents) .
"</div>\n"; # class="patch"
$patch_number++;
}
if ($patch_number == 0) {
if ($patch_number == 0) {
if (@hash_parents > 1) {
if (@hash_parents > 1) {
print "<div class=\"diff nodifferences\">Trivial merge</div>\n";
print "<div class=\"diff nodifferences\">Trivial merge</div>\n";
@ -4582,7 +4648,11 @@ sub git_commitdiff {
die_error(undef, "Unknown commit object");
die_error(undef, "Unknown commit object");
}
}
# we need to prepare $formats_nav before any parameter munging
# choose format for commitdiff for merge
if (! defined $hash_parent && @{$co{'parents'}} > 1) {
$hash_parent = '--cc';
}
# we need to prepare $formats_nav before almost any parameter munging
my $formats_nav;
my $formats_nav;
if ($format eq 'html') {
if ($format eq 'html') {
$formats_nav =
$formats_nav =
@ -4590,7 +4660,8 @@ sub git_commitdiff {
hash=>$hash, hash_parent=>$hash_parent)},
hash=>$hash, hash_parent=>$hash_parent)},
"raw");
"raw");
if (defined $hash_parent) {
if (defined $hash_parent &&
$hash_parent ne '-c' && $hash_parent ne '--cc') {
# commitdiff with two commits given
# commitdiff with two commits given
my $hash_parent_short = $hash_parent;
my $hash_parent_short = $hash_parent;
if ($hash_parent =~ m/^[0-9a-fA-F]{40}$/) {
if ($hash_parent =~ m/^[0-9a-fA-F]{40}$/) {
@ -4622,6 +4693,17 @@ sub git_commitdiff {
')';
')';
} else {
} else {
# merge commit
# merge commit
if ($hash_parent eq '--cc') {
$formats_nav .= ' | ' .
$cgi->a({-href => href(action=>"commitdiff",
hash=>$hash, hash_parent=>'-c')},
'combined');
} else { # $hash_parent eq '-c'
$formats_nav .= ' | ' .
$cgi->a({-href => href(action=>"commitdiff",
hash=>$hash, hash_parent=>'--cc')},
'compact');
}
$formats_nav .=
$formats_nav .=
' (merge: ' .
' (merge: ' .
join(' ', map {
join(' ', map {
@ -4634,9 +4716,10 @@ sub git_commitdiff {
}
}
my $hash_parent_param = $hash_parent;
my $hash_parent_param = $hash_parent;
if (!defined $hash_parent) {
if (!defined $hash_parent_param) {
# --cc for multiple parents, --root for parentless
$hash_parent_param =
$hash_parent_param =
@{$co{'parents'}} > 1 ? '-c' : $co{'parent'} || '--root';
@{$co{'parents'}} > 1 ? '--cc' : $co{'parent'} || '--root';
}
}
# read commitdiff
# read commitdiff
@ -4713,10 +4796,14 @@ TEXT
# write patch
# write patch
if ($format eq 'html') {
if ($format eq 'html') {
git_difftree_body(\@difftree, $hash, $hash_parent || @{$co{'parents'}});
my $use_parents = !defined $hash_parent ||
$hash_parent eq '-c' || $hash_parent eq '--cc';
git_difftree_body(\@difftree, $hash,
$use_parents ? @{$co{'parents'}} : $hash_parent);
print "<br/>\n";
print "<br/>\n";
git_patchset_body($fd, \@difftree, $hash, $hash_parent || @{$co{'parents'}});
git_patchset_body($fd, \@difftree, $hash,
$use_parents ? @{$co{'parents'}} : $hash_parent);
close $fd;
close $fd;
print "</div>\n"; # class="page_body"
print "</div>\n"; # class="page_body"
git_footer_html();
git_footer_html();