Topic 2.5
Detached HEAD, and checkout vs switch vs restore
In one line
Normally HEAD points at a branch, and new commits move that branch. In 'detached HEAD' state, HEAD points straight at a commit, which happens when you check out a tag, an old commit, or during rebase, bisect, and CI. It's safe for looking around, but new commits belong to no branch and become hard to find once you leave. Create a branch (git switch -c name) to keep them. Since Git 2.23, git switch (branches) and git restore (files) split up the old do-everything git checkout.
Think of it like this
Reading an old edition of a book in the library. You can read anything, and even scribble notes on loose sheets. But if you walk away without clipping the sheets into your own notebook (a branch), the cleaner throws them out.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- HEAD
- Git's pointer to what you currently have checked out, usually a branch.
- Detached HEAD
- HEAD pointing directly at a commit instead of a branch.
- Orphaned commit
- A commit that no branch or tag points to, findable only through the reflog until cleanup.
- git switch
- Change branches, or create one with
-c(Git 2.23+). - git restore
- Restore files in the working directory or staging area (Git 2.23+).
- git checkout
- The older command that can do both, depending on its arguments.
Step by step
01Looking at an old release
A customer says delivery fees were different in v1.6.0. Priya checks out the tag to look, which detaches HEAD. Git explains what that means.
02Committing while detached
She tries a quick experiment and commits it. The commit exists, but only HEAD points to it, and no branch does.
03Leaving, and the warning
When she switches back to main, Git warns that a commit is being left behind and shows its hash. If she wants it, one command saves it on a branch. If it was just an experiment, she can ignore it, and it will be cleaned up eventually.
04checkout vs switch vs restore
git checkout decides what to do from its arguments: a branch name switches branches, but a file name silently overwrites your file with the staged version. The newer commands make the intent explicit.
git checkout feature/coupons → git switch feature/coupons
git checkout -b feature/coupons → git switch -c feature/coupons
git checkout v1.6.0 → git switch --detach v1.6.0
git checkout -- src/cart.js → git restore src/cart.js
git checkout main -- src/cart.js → git restore --source=main src/cart.js
git reset HEAD src/cart.js → git restore --staged src/cart.jsBreak it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
A day of work on no branch
After a bisect (Topic 6.2) Arjun forgets git bisect reset, works all afternoon, commits three times, then runs git switch main, ignoring the warning.
Myth vs fact
Myth
Detached HEAD means something is broken.
Fact
It's a normal state for inspecting old code, and Git uses it during rebase and bisect. It only matters if you commit there and forget to create a branch.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
CI systems usually check out a specific commit in detached HEAD state, so scripts that run
git branch --show-currentget an empty string there. Use the CI's variables (for exampleGITHUB_REF_NAME) orgit rev-parse HEADinstead.
Remember this
- 1
Attached (normal):
HEAD → main → commit. Committing movesmain. - 2
Detached:
HEAD → commit. Committing creates commits no branch points to. - 3
You get there by
git switch --detach v1.6.0,git checkout <hash>or a tag, and also automatically duringrebase,bisect, and in most CI checkouts. - 4
git statussaysHEAD detached at …, and many shell prompts show a hash instead of a branch name. - 5
Keep work made there:
git switch -c new-branchbefore leaving. Already left? Git prints the hash in a warning, and the reflog has it (Topic 5.3). - 6
git checkoutdoes two unrelated jobs: switch branches and overwrite files. That's whygit checkout file(which discards changes) was a common accident. Usegit switchfor branches andgit restorefor files.
Explain it without notes
What changes when HEAD is detached?
Why were git switch and git restore added?
Practice
Check out an old commit, make a commit there, and save it on a branch.
Trade-offs
- ↔
Detached HEAD is quick for inspecting any point in history without creating branches, but committing there is risky. A throwaway branch costs nothing and is safer for experiments.
Done when you can
I can recognise detached HEAD.
I save detached commits with git switch -c.
I use switch for branches and restore for files.