(git) ~ vs. ^
When using relative references to identify git commits, there is a difference between HEAD~1
and HEAD^1
. The ~
looks back linearly at commits from earlier generations of a single branch, while the ^
walks through all immediate parents for a single commit. These may seem similar, but that's only the case until a fork is introduced into the repository. Once someone creates a merge commit, these two symbols become very different.
An example
To illustrate different commit references, we will use the example created by Jon Loeliger. Here's his git repository structure:
A
/ \
/ \
B C
/|\ |
/ | \ |
/ | \ /
D E F
/ \ / \
G H I J
Any git commits near the bottom-left of the visualization are older, while the ones towards the top or right sides are newer. One implementation might look like this:
$ git log --graph --oneline
* 7522b1c (HEAD -> main) Commit A
|\
| * 8ae601a Commit C
| |
| \
*-. | 59eb30f Commit B
|\ \|
| | * 6421881 Commit F
| | |\
| | | * 75fe470 Commit J
| | * bb7eb7c Commit I
| |
| * 3fd5db5 Commit E
|
* bac00e3 Commit D
|\
| * d8daf15 Commit H
| |
* eba4957 Commit G
For demonstration purposes, I find this visualization easiest:
git log
-like graph of Jon Loeliger's example git repository.The tilde
Using commit A as a starting point, we use tildes to walk vertically down the left-most branch, i.e. B = A~1
, D = A~2
, etc. There is no way to reference commits in other branches using the tilde.
The caret
Using commit A as a starting point, we use carets to walk horizontally forward through all parent objects, i.e. B = A^1
and C = A^2
. Parent references are 1-indexed (and ^
is specially reserved to reference the starting commit).
It's common to use ^
as shorthand for ^1
, so B = A^
too. However, even though ^1^1
shortens to ^^
, this isn't the same thing as ^2
. A^1^1
is commit D, while A^2
is commit C.
Putting it together
Here are ways to reference other commits in this repository:
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
It's also possible to mix-and-match tildes and carets. For example, F = A~1^3
. Order matters!