Specifying parent revisions in git
Yesterday I merged two branches, resulting in a merge commit node. Later on I wanted to revert this merge and searched on Stackoverflow, where I found the solution
git reset --hard HEAD~1
Another answer noted instead
git reset --hard HEAD^1
This is almost the same, except the revision specified. Digging deeper reveals, that these two revisions are the same actually. In the Git Book Revision Selection - Ancestry References, we can see
If you place a ^ at the end of a reference, Git resolves it to mean the parent of that commit.
and a few paragraphs later
The other main ancestry specification is the ~. This also refers to the first parent, so HEAD~ and HEAD^ are equivalent.
Adding a number like
~3 gives the grand-grandparent of a
commit. Adding a number to a
^2 gives the second parent of
a commit. And using
~1 is the same as
So when both are specifying parents and grandparents, what is the difference?
The tilde is for selecting the first parent (
~1), the first
~2), the first grand-grandparent (
~3), and so on. But
it doesn’t allow you to select the second parent or second
grandparent, you can only select straight into the depth.
The caret is for immediate parents of a commit only, and allows
selecting in the breadth. This means, you can select the (single)
immediate parent (
^1), or one of the immediate parents in the case
of a merge commit, e.g.
^2. But you cannot select the grandparent by
using some number.
However, it is possible to combine multiple carets and tildes, so in
the end, you can select the grandparent with carets too. Just use two
carets for the grandparent,
^1^1, or use three carets for
^2^1 for the parent of
the second immediate parent.
Confused? You bet I was! But keeping in mind, that caret is for breadth and tilde is for depth, helps a bit.