Learning Objectives
By the end of this lesson you will be able to:
- Explain what
HEADpoints to and why Git needs it - Determine your current branch three different ways
- Recognise a detached
HEADand get out of one without losing work - Use
HEAD~1,HEAD~3and similar references to talk about earlier commits
One Question, Constantly
Every Git command that changes something needs an answer to where am I? Commit — onto what? Merge — into what? Diff — against what?
HEAD is that answer. It is a single reference, stored in one file, that means "the commit you are currently standing on".
cat .git/HEAD
ref: refs/heads/feature/auth-test
Note what it contains: not a commit ID, but a pointer to a branch. HEAD points at a branch, and that branch points at a commit. Two hops.
HEAD ──▶ feature/auth-test ──▶ commit E
This indirection is what makes committing work. When you commit, Git creates the commit, moves the branch pointer forward, and HEAD follows along automatically because it points at the branch, not the commit.
Three Ways to Ask "Where Am I?"
git branch --show-current
feature/auth-test
Clean, scriptable, and unambiguous. This is the one to use.
git status
On branch feature/auth-test
nothing to commit, working tree clean
More verbose, but you were probably going to run it anyway.
git branch
main
* feature/auth-test
test/PAY-4417-verify
The asterisk marks the current branch. Useful when you also want to see what else exists.
Many teams also configure their shell prompt to display the branch permanently. If yours doesn't, it is worth ten minutes of setup — it removes an entire class of mistake.
Detached HEAD
Sometimes HEAD skips the branch and points straight at a commit:
git switch --detach 8f3c2a1
Note: switching to '8f3c2a1'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them...
HEAD ──▶ commit 8f3c2a1 (no branch in between)
This sounds like damage. It is not — it is a completely normal state, and testers end up in it often, usually after checking out a tag or a specific commit to reproduce a bug on an exact build.
What is safe in detached HEAD: looking at files, running the application, running tests, running git log and git diff. All of it.
What is risky: committing. A commit made in detached HEAD belongs to no branch. Move away and nothing points at it any more, so it becomes very hard to find and is eventually garbage-collected.
Getting Out
If you made no commits, just leave:
git switch main
If you did make commits and want them, give them a branch before you leave:
git switch -c test/repro-from-8f3c2a1
That creates a branch at exactly where you're standing, and everything you committed is now safely anchored.
Pro Tip: If you switched away and only then realised you'd lost commits, they are usually still recoverable.
git refloglists every positionHEADhas held recently, including the abandoned ones — find the ID and branch from it.
Talking About Earlier Commits
HEAD is also the anchor for relative references, which you will meet constantly:
| Reference | Means |
|---|---|
HEAD |
The current commit |
HEAD~1 |
Its parent — one commit back |
HEAD~3 |
Three commits back |
HEAD^ |
Same as HEAD~1 for ordinary commits |
They are read-only ways of naming a commit, so using them in an inspection command is completely safe:
git diff HEAD~1 # what changed in the most recent commit
git log HEAD~5..HEAD # the last five commits
git show HEAD~2 # the full contents of the commit two back
A word of caution about merge commits: they have two parents, so HEAD^1 and HEAD^2 select different sides of the merge. That distinction matters in Module 2.
Key Takeaways
HEADmeans "the commit you are currently on", and normally points at a branch, which points at a commitgit branch --show-currentis the fastest, cleanest way to check where you are- Detached
HEADmeansHEADpoints straight at a commit with no branch — normal and safe to read from - Committing while detached leaves commits with nothing pointing at them; create a branch first
git reflogrecovers commits you thought you lostHEAD~1,HEAD~3andHEAD^name earlier commits and are safe in inspection commands