What Happens When You Mistype HEAD~1 as HEAD^1?
When I first started my career, I remember breaking into a “cold sweat” while using git reset to fix a broken merge. At the time, I was convinced that ~ (Tilde) and ^ (Caret) were the same thing and could be used interchangeably. The result? I jumped into an ancient feature branch instead of returning to the main commit on master. Luckily, git reflog saved me, otherwise a whole morning’s work would have been lost (a lesson in recovering deleted commits).
In my team of eight, even senior developers sometimes hesitate for a few seconds when encountering complex merge commits. Understanding these two symbols helps you master git rebase -i. You’ll feel more confident when digging through old code without fear of messing up the commit history.
30-Second Quick Tip
If you’re in a hurry, remember this simple rule:
- The
~(Tilde) symbol: Moves backwards in time in a straight line.HEAD~3goes back exactly 3 steps. - The
^(Caret) symbol: Selects which parent to follow in a merge. This symbol is only truly important when a commit has two or more parents.
# Go back 1 commit (both yield the same result)
git reset --hard HEAD~1
git reset --hard HEAD^
# Go back exactly 3 commits along the vertical axis
git reset --hard HEAD~3
# Select the 2nd parent commit of a merge commit
git show HEAD^2
Now, let’s take a closer look at the mechanics to dissect Git from the inside so it never “tricks” you again.
1. Tilde (~): Jumping Back Along the Vertical Axis
Think of Git history as a rope. The ~ symbol acts like the number of steps you take backward on that rope.
When you write HEAD~n, Git understands it as: “From here, go back n steps. At each step, if there’s a fork, always choose the first parent commit (first parent)”.
HEAD~1: Direct parent.HEAD~2: Grandparent.HEAD~3: Great-grandparent.
Writing HEAD~~~ yields the same result as HEAD~3. However, I recommend using the number for brevity—it saves your fingers and prevents miscounting symbols.
2. Caret (^): Choosing a Direction at a Fork
The real difference appears at Merge Commits. A normal commit has only one parent, but when you merge a Feature branch into Main, that commit will have two parents.
- Parent 1: The commit belonging to the branch you were on (e.g.,
main) before the merge. - Parent 2: The last commit of the branch you just pulled in.
In this case, HEAD^1 takes you back to the main track. Meanwhile, HEAD^2 leads you to the merged feature branch. If you use HEAD^3, Git looks for a third parent. This is extremely rare, usually only seen when using an Octopus Merge to combine 4-5 branches at once.
Note: For a single commit (not a merge), HEAD^1 and HEAD~1 point to the same place. This is why many people mistakenly think they are identical twins.
3. Visualizing the Commit Diagram
To visualize this, look at the diagram below:
G (HEAD)
|
F (Merge commit: merge E into D)
/ \
D E
| |
C |
| /
B /
|
A
At position G (HEAD), the results would be:
HEAD~1points to F.HEAD~2points to D (Git goes G -> F -> D along the main branch).HEAD^1points to F.F^1points to D (Main branch before merge).F^2points to E (The feature branch just merged).
So, what if you want to go from G to E? Use: HEAD~1^2. This means: go back one step to F, then switch to the second parent.
4. Combined Techniques for Rebase
When cleaning up commits with git rebase -i, combining ~ and ^ is very powerful. You no longer need to bother copying long SHA-1 hashes. Just specify the correct coordinates and you’re done.
Example: HEAD~3^2
HEAD~3: Go back 3 steps in a straight line.^2: At that point, switch to the secondary branch.
My advice: Before running the reset --hard command, check your destination with show or preview your commit history:
git show HEAD~2^1 --oneline -s
If the commit name that appears is what you intended, only then hit Enter to execute the main command.
Practical Advice: Trust the Visuals
That’s the theory, but when facing a project with 10,000 commits, counting ~ by eye is suicide. In my team, I always require everyone to turn on the diagram before typing commands:
git log --oneline --graph --all
Looking at the chart, you will clearly see the connections. Determining HEAD^2 or HEAD~5 becomes much more intuitive.
Another common situation is git cherry-pick. When you want to take code from a merge commit, Git will freeze because it doesn’t know which side to pick, requiring manual work in resolving Git conflicts. You must use the -m flag with the parent index, for example: git cherry-pick -m 1 <commit_hash>. This is exactly where knowledge of Parents comes into play.
Summary
To use Git like a pro, remember:
- Use Tilde (~) to move backward in time on the same branch.
- Use Caret (^) to switch to a different branch at Merge points.
- Always use
git log --graphto see the path before you jump.
Once you master these two symbols, commit history will no longer feel like a maze. Happy smooth commit managing!

