I wonder, what does
git diff --name-only "$CI_COMMIT_SHA"^!
do exactly? Does it check changes in one last commit or what?
I wonder, what does
git diff --name-only "$CI_COMMIT_SHA"^!
do exactly? Does it check changes in one last commit or what?
See git help revisions
, specifially the section Revision Range Summary:
<rev>^!
, e.g.HEAD^!
A suffix
^
followed by an exclamation mark is the same as giving commit<rev>
and then all its parents prefixed with^
to exclude them (and their ancestors).
So for a regular (non-merge) commit, e.g. HEAD
, this is simply a shorthand notification for HEAD ^HEAD^
. But for a merge commit, this resolves to HEAD ^HEAD^1 ^HEAD^2 ^HEAD^...
(normally, merges have only 2 parents).
The easiest way to find out what those revision specifiers mean is to run them through git rev-parse
, e.g. git rev-parse HEAD^!
, git rev-parse HEAD^@
, or git rev-parse ^HEAD
.
In the context of git diff
, this will call the following form of git diff:
git diff [<options>] <commit> <commit>… <commit> [--] [<path>…]
This form is to view the results of a merge commit. The first listed
<commit>
must be the merge itself; the remaining two or more commits should be its parents. A convenient way to produce the desired set of revisions is to use the^@
suffix. For instance, ifmaster
names a merge commit,git diff master master^@
gives the same combined diff as git show master.
So to view the combined diff of a merge commit, you would need to run git diff HEAD HEAD^@
, or shorter git diff HEAD^!
I'd expect to get a combined diff of a merge commit by running git diff HEAD HEAD^@
or at least with git diff --cc HEAD HEAD^@
, but quick tests didn't confirm that.
In fact, it looks like git diff HEAD^!
is equivalent to running git diff HEAD HEAD^
even for a merge-commit which doesn't make much sense to me because it shows the "reverse diff" (going from the current commit to its first parent). This might well be a bug OR something simply not supported by git diff
, i.e. undefined behavior. Why? Because git diff
is all about endpoints and not revision ranges – and HEAD^!
specifies a range of commits.