What is git show?
The command git show is a generic command for displaying information about an object in git.
From the man page (git help show):
Shows one or more objects (blobs, trees, tags and commits).
...
For commits it shows the log message and textual diff.
It also presents the merge commit in a special format as produced by
git diff-tree --cc
...
So, the output of git show is different because this is a merge commit rather than a plain commit.
The man page for git diff-tree --cc says:
--cc
This flag changes the way a merge commit patch is displayed, in a
similar way to the -c option. It implies the -c and -p options and
further compresses the patch output by omitting uninteresting hunks whose
the contents in the parents have only two variants and the merge result
picks one of them without modification. When all hunks are uninteresting,
the commit itself and the commit log message is not shown, just like in
any other "empty diff" case.
further
-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.
Please take notice of that last line which I repeat here:
Furthermore, it lists only files which were modified from all parents.
So git show on a merge commit will only list the files that were modified when comparing the commit to all parents of the merge. For an ordinary merge (i.e. 2 parents) this is exactly the files that were merged. If, for example, you do this merge:
git checkout master
git merge feature
The files listed by git show are the files that were modified in both master and feature prior to the merge and were merged together in the merge commit.
For an octopus merge – i.e. more than two parents – the resulting file must differ from the file in all parents to be displayed by git show.
Please note, that other files can also show up when using git show on a merge commit. If, for example, you call git merge --no-commit and then before committing do any of the following, then these files will also be displayed by git show on the merge commit:
- Add a new file.
- Delete an existing file.
- Modify any file – including any of the files already staged by git merge.
Conclusion
What git show is doing is displaying a so-called combined diff.
The result of running the command git show on a merge commit can be thought of as showing only the files which were merged and not the files that were simply taken unchanged from one of the two parents.
This is a bit surprising as many people expect to see which files were modified compared to the branch into which you just merged.
So what to do if you want to look at the diff between either of the parents?
Let's have a final look at the man page of git show:
COMBINED DIFF FORMAT
Any diff-generating command can take the `-c` or --cc option to produce
a combined diff when showing a merge. This is the default format when
showing merges with git-diff(1) or git-show(1). Note also that you can
give the `-m' option to any of these commands to force generation of
diffs with individual parents of a merge.
So we can use the -m option to get both diffs like this:
git show -m commit
This will give you the diffs against all parents one by one.
To see the difference between the merge commit and the previous commit on the branch into which you merged (i.e. the first parent), use either of these commands:
git show --first-parent commit
git diff commit^..commit
git diff commit^!
The --first-parent option really belongs to git log but also works for git show. The notation commit^! is a shorthand for commit^..commit.
To see the difference between the merge commit and the branch from which you merged (e.g. to see what you left out from the other branch), use
git diff commit^2..commit
The notation commit^2 means the 2nd parent of commit.
If you have more than 2 parents (i.e. an octopus merge) I am sure you can guess how to diff against the 3rd, 4th, etc. commits.