101

HEAD is a pointer at the current branch. I have seen a variety of notations for ancestors of HEAD including

  • HEAD~2
  • HEAD^2
  • HEAD@{2}
  • HEAD~~
  • HEAD^^

What does each of the above mean, exactly? Where is the documentation for this?

Greg Bacon
  • 134,834
  • 32
  • 188
  • 245
Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467

3 Answers3

117

From the docs here.

  • HEAD~2 : 2 commits older than HEAD
  • HEAD^2 : the second parent of HEAD, if HEAD was a merge, otherwise illegal
  • HEAD@{2} : refers to the 3rd listing in the overview of git reflog
  • HEAD~~ : 2 commits older than HEAD
  • HEAD^^ : 2 commits older than HEAD

If HEAD was a merge, then

  • first parent is the branch into which we merged,
  • second parent is the branch we merged.

Some Combinations and Synonyms

First Parent    First Grandparent    Second Parent    Second Grandparent

HEAD~
HEAD^
HEAD~1          HEAD~2               HEAD^2           HEAD^2~        
HEAD^1          HEAD^^                                HEAD^2^ 
Tim
  • 41,901
  • 18
  • 127
  • 145
  • The documentation link is perfect. Git Book v2 has many useful additions to v1. – Shaun Luttin Nov 06 '14 at 17:13
  • 4
    `HEAD~0` is the same as `HEAD`, as you would expect. Somewhat confusingly, `HEAD^0` is also the same as `HEAD`. – Vladimir Reshetnikov Jun 14 '17 at 18:15
  • 4
    To remember which symbol is which, I find it helpful that `^` LOOKS like two branches (at the bottom left and bottom right) **merging** together into one (at the top) – mareoraft Jan 26 '19 at 14:44
  • If the OP (or someone with enough rep for a 1-character edit) sees this, there is now an https version of the git-scm URL linked to in the answer. – AJM Oct 22 '21 at 13:26
  • 1
    @AJM-Reinstate-Monica updated :thumbs-up: – Tim Oct 22 '21 at 14:27
29

git reference suffixes (^N, ~N, @{...})

ref~ is shorthand for ref~1 and means the commit's first parent. ref~2 means the commit's first parent's first parent. ref~3 means the commit's first parent's first parent's first parent. And so on.

ref^ is shorthand for ref^1 and means the commit's first parent. But where the two differ is that ref^2 means the commit's second parent (remember, commits can have two parents when they are a merge).

The ^ and ~ operators can be combined.

Here's a diagram showing how to reference various commits using HEAD as the starting point.
enter image description here

src

Premraj
  • 72,055
  • 26
  • 237
  • 180
8

I count each ~ or ^ to mean "going back one level". If there is a number next to ~ (eg. ~n), then n acts as a multiplier. If there is a number next to ^ (eg. ^n), then n is the n'th parent to use (or sideways movement going from left-to-right column position in git log --graph).

Example:

$ git log --oneline --graph 
*   29392c8 (HEAD -> master, tag: A) A
|\
| * a1ef6fd (tag: C) C
| |
|  \
*-. \   8ae20e9 (tag: B) B
|\ \ \
| | |/
| | *   03160db (tag: F) F
| | |\
| | | * 9df28cb (tag: J) J
| | * 2afd329 (tag: I) I
| * a77cb1f (tag: E) E
*   cd75703 (tag: D) D
|\
| * 3043d25 (tag: H) H
* 4ab0473 (tag: G) G

Coordinates for above tags:

A =      = A^0
B = A^   = A^1     = A~1
C = A^2
D = A^^  = A^1^1   = A~2
E = B^2  = A^^2
F = B^3  = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2  = B^^2    = A^^^2  = A~2^2
I = F^   = B^3^    = A^^3^
J = F^2  = B^3^2   = A^^3^2

The git log --online --graph output makes it hard to see which commits are on the same level, so here is another presentation (where "A" is the latest commit and older commits are at the top):

G   H   I   J
 \ /     \ /
  D   E   F
   \  |  / \
    \ | /   |
     \|/    |
      B     C
       \   /
        \ /
         A

(Illustrations excerpted from What's the difference between HEAD^ and HEAD~ in Git?).

mvanle
  • 1,847
  • 23
  • 19