Reputation: 26345
I have always understood git show
to never show a diff on a merge commit. Probably for the same reason git log -p
doesn't show a diff on merge commits. However, I am able to create two reproducible scenarios: A merge commit that does produce a diff with git show
and one that does not. I would like to understand why the behavior of git show
is different between these scenarios.
First, here is a script I ran which creates the repository required to observe the two scenarios above:
#!/usr/bin/env bash
set -ex
git init test_repo
cd test_repo
# master (commit 1)
printf "one\n" > file.txt
git add file.txt
git commit -m one
# master (commit 2)
printf "two\n" >> file.txt
git commit -am two
# master (commit 3)
printf "three\n" >> file.txt
git commit -am three
# topic1 (commit 1)
git checkout -b topic1 @^
printf "four\n" >> file.txt
git commit -am four
# merge topic1 to master (commit 4)
git checkout master
git merge - || true # conflict
printf "one\ntwo\nthree\nfour\n" > file.txt
git add file.txt
git commit --no-edit
git tag merge1 # tag so we can refer to it in examples
# master (commit 5)
printf "five\n" >> file.txt
git commit -am five
# topic2 (commit 1)
git checkout -b topic2
printf "six\n" >> file.txt
git commit -am six
# merge topic2 to master (commit 6)
git checkout master
git merge --no-edit - # no conflict
git tag merge2 # tag so we can refer to it in examples
Scenario 1: git show
shows a diff:
$ cd test_repo
$ git show merge1
commit cb7aba11aed80917e3fac64e60aef3fe0a27e5de (tag: merge1)
Merge: 75bae65 5f63df7
Author: John Doe <[email protected]>
Date: Wed Jun 19 14:05:34 2019 -0500
Merge branch 'topic1'
# Conflicts:
# file.txt
diff --cc file.txt
index 4cb29ea,87a123c..f384549
--- file.txt
+++ file.txt
@@@ -1,3 -1,3 +1,4 @@@
one
two
+three
+ four
Scenario 2: git show
does not show a diff:
$ cd test_repo
$ git show merge2
commit 5f37be9b563afc9c9f43ad04198d80809e6fc13a (HEAD -> master, tag: merge2)
Merge: 6f4cf36 bde33e8
Author: John Doe <[email protected]>
Date: Wed Jun 19 14:05:34 2019 -0500
Merge branch 'topic2'
The main difference between the two scenarios (e.g. merge1
and merge2
) is that merge2^
refers to the merge base of topic2
and master
(before the merge) and merge1^
is a unique, non-merge commit. I'm not sure if this intermediate commit being between the merge base and the merge commit matters, but I can't think of anything else it could be. Can anyone explain this difference in behavior?
What I expect is that git show merge1
does not show a diff. As far as I am concerned, git show merge2
output is correct, and git show merge1
is incorrect (buggy).
Git version is 2.22.0 on Windows.
Upvotes: 1
Views: 44
Reputation: 488003
git show
produces combined diffs by default. (This is an improvement over git log -p
, which, for merge commits, produces no diffs at all by default!)
Combined diffs are documented—somewhat poorly in my opinion—in two separate sections that show up in several of the various git diff
command manual pages. Here are the two critical sections from the git diff-tree
documentation:
The first section, near the bottom, has this caveat:
Note that combined diff lists only files which were modified from all parents.
This should probably be boldface, 18-point font, and/or blinking and not quite so far from the second section that tells you how to read the output. (The -p
description has its own section between these two. Also, the first section is talking about the mode-line stuff, but the fact that many files are omitted entirely applies to the second section, it's just not mentioned in the second section.)
I think the goal here is to make the default git show
output show you where someone might have had to do conflict resolution. That's usually a good idea, but sometimes you really want git show -m
, which just shows one diff against the first parent, and then a second diff against the second parent.
Upvotes: 2
Reputation: 30174
git show
will show diff stuff if there was a conflict resolution.
Upvotes: 0