Specifying parent revisions in git

Submitted by olaf on 2017-02-15

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 ^, e.g. ^2 gives the second parent of a commit. And using ^1 or ~1 is the same as ^ and ~ respectively.


So when both are specifying parents and grandparents, what is the difference?

The tilde is for selecting the first parent (~1), the first grandparent (~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, ^^ or ^1^1, or use three carets for the grand-grandparent, ^^^ or ^1^1^1, or ^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.

Post a comment

All comments are held for moderation; Markdown and basic HTML formatting accepted. If you want to stay anonymous, leave name, e-mail and website empty.