Lesson 24 of 30
HEAD is usually a pointer to a branch, which is a pointer to a commit. Check out a commit directly, and you cut out the middle pointer — and the safety net that comes with it.
12 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
HEAD is Git's answer to "where am I right now." Normally it's a pointer to a branch name, and the branch name is a pointer to a commit — so HEAD -> main -> a1b2c3d. When you commit, Git creates the new commit, then moves the branch pointer forward, and HEAD just rides along because it's pointing at the branch, not the commit directly.
Detached HEAD happens when you check out a commit directly instead of a branch — HEAD now points straight at a commit hash, with no branch name in between. Git isn't broken and nothing is wrong yet; you can look around, build, run tests, even make new commits. The danger only shows up the moment you commit while detached: that new commit has a real hash and a real place in the object graph, but no branch pointer is tracking it. There's nothing keeping it reachable. Switch to another branch, and that commit isn't deleted immediately — but it's no longer reachable from anything Git considers a "ref," which means normal Git commands (git log, git branch) will never show it to you again, and it becomes eligible for garbage collection.
You land here more often than you'd expect: checking out a tag (git checkout v2.1.0), checking out a specific commit to inspect old code (git checkout a1b2c3d), or checking out a PR ref for review. All of these point at a specific snapshot, not a branch, so Git has no branch pointer to attach HEAD to.
$ git checkout v2.1.0
Note: switching to 'v2.1.0'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
HEAD is now at a1b2c3d Release 2.1.0
That warning is Git being genuinely helpful — it's telling you exactly what's about to be true. Say you poke around, then make a quick fix commit without reading it closely:
$ echo "hotfix" >> notes.txt
$ git commit -am "quick patch on the tag"
[detached HEAD f7e8d9a] quick patch on the tag
1 file changed, 1 insertion(+)
$ git switch main
Warning: you are leaving 1 commit behind, not connected to
any of your branches:
f7e8d9a quick patch on the tag
If you want to keep it by creating a new branch, this is fine:
git branch <new-branch-name> f7e8d9a
Git even hands you the exact hash and the exact command to recover it — take it seriously, because that commit is genuinely one git gc away from being unreachable for good. Do it right then:
$ git branch rescue-fix f7e8d9a
$ git log rescue-fix -1 --oneline
f7e8d9a quick patch on the tag
Now rescue-fix is a real branch pointer holding that commit, and it's as safe as any other commit in the repo. If you'd already switched away and lost the hash from your terminal scrollback, git reflog still has it — it records every place HEAD has pointed, detached commits included, typically for 90 days by default.
git reflog plus git branch <name> <hash>, as long as you notice before an eventual git gc sweeps them.git switch and git checkout behave differently on purpose here. checkout overloads branch-switching, commit-checkout, and file-restoration into one command, which is part of why detached HEAD surprises people. git switch is the newer, narrower command for exactly "change what HEAD points to," and git switch -c is the direct, readable way to escape detached HEAD into a real branch.This is the practical, everyday reason this track's reflog lesson matters — the reflog is the safety net specifically for moments like an accidental commit in detached HEAD, where no branch was ever pointing at the work. Understanding branches as "just movable pointers to a commit" — the same idea from this track's very first lesson on Git's internal model — is what makes detached HEAD click: you're not in a special mode, you've simply removed the pointer that normally rides along and keeps a commit easy to find.