HEAD~ vs HEAD^ vs HEAD@{} also known as tilde vs caret vs at sign
From the docs here.
HEAD~2
: 2 commits older than HEADHEAD^2
: the second parent of HEAD, if HEAD was a merge, otherwise illegalHEAD@{2}
: refers to the 3rd listing in the overview ofgit reflog
HEAD~~
: 2 commits older than HEADHEAD^^
: 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^
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?).
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.
src