Subject: [PATCH 5/6] gitweb: Show combined diff for merge commits in 'commitdiff' view

From: Jakub Narebski <[email-masked]>
Date: Mon, 7 May 2007 01:10:07 +0200

When 'commitdiff' action is requested without 'hp' (hash parent)
parameter, and commit given by 'h' (hash) parameter is merge commit,
show merge as combined diff.

Earlier for merge commits without 'hp' parameter diff to first parent
was shown.

Note that in compact combined (--cc) format 'uninteresting' hunks
omission mechanism can make that there is no patch corresponding to
line in raw format (difftree) output. That is why (at least for now)
we use --combined and not --cc format for showing commitdiff for merge
commits.

Signed-off-by: Jakub Narebski <[email-masked]>
---
Note the following fragment of combined diff format description from
git-diff-tree(1) man page; note the final sentence

-c::
        This flag changes the way a merge commit is displayed
        (which means it is useful only when the command is given
        one <tree-ish>, or '--stdin').  It shows the differences
        from each of the parents to the merge result simultaneously
        instead of showing pairwise diff between a parent and the
        result one at a time (which is what the '-m' option does).
        Furthermore, _it lists only files which were modified
        from all parents_.

This means that now 'commitdiff' would show empty diff for all trival
(tree-level) merges, which I think is a majority of merges. Is showing
empty diff better than diff to first parent for merges, then? Or do we
need some way to show from which parent was final version of a file
taken?

Currently there is no way to generate 'commitdiff' view to one of the
parents by clicking some link directly from 'commitdiff' view: you
have to go via 'commit' view (click on commit subject, which functions
as switch between 'commitdiff' and 'commit' views, then on "diff" link
next to one of the parents in commit header). Perhaps this can be
improved with improving difftree/whatchanged output for combined
diff.

 gitweb/gitweb.perl |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index b3e2e07..c0e2473 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -4391,8 +4391,10 @@ sub git_commitdiff {
 		}
 	}
 
+	my $hash_parent_param = $hash_parent;
 	if (!defined $hash_parent) {
-		$hash_parent = $co{'parent'} || '--root';
+		$hash_parent_param =
+			@{$co{'parents'}} > 1 ? '-c' : $co{'parent'} || '--root';
 	}
 
 	# read commitdiff
@@ -4401,7 +4403,7 @@ sub git_commitdiff {
 	if ($format eq 'html') {
 		open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
 			"--no-commit-id", "--patch-with-raw", "--full-index",
-			$hash_parent, $hash, "--"
+			$hash_parent_param, $hash, "--"
 			or die_error(undef, "Open git-diff-tree failed");
 
 		while (my $line = <$fd>) {
@@ -4413,7 +4415,7 @@ sub git_commitdiff {
 
 	} elsif ($format eq 'plain') {
 		open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
-			'-p', $hash_parent, $hash, "--"
+			'-p', $hash_parent_param, $hash, "--"
 			or die_error(undef, "Open git-diff-tree failed");
 
 	} else {
@@ -4469,10 +4471,10 @@ TEXT
 
 	# write patch
 	if ($format eq 'html') {
-		git_difftree_body(\@difftree, $hash, $hash_parent);
+		git_difftree_body(\@difftree, $hash, $hash_parent || @{$co{'parents'}});
 		print "<br/>\n";
 
-		git_patchset_body($fd, \@difftree, $hash, $hash_parent);
+		git_patchset_body($fd, \@difftree, $hash, $hash_parent || @{$co{'parents'}});
 		close $fd;
 		print "</div>\n"; # class="page_body"
 		git_footer_html();
-- 
1.5.1.3