Detached HEAD State
“Detached HEAD” is one of the most-feared Git messages, but it is harmless if you understand it. It just means HEAD is pointing directly at a commit instead of at a branch. Nothing is broken, no work is lost — but any new commits you make in this state will not belong to any branch, which is where the danger lies.
What HEAD normally is
Normal: HEAD → branch → commit
HEAD ──▶ refs/heads/main ──▶ commit C ◀── main
A───B───CWhen you commit, Git advances the branch HEAD points to. That is how branches grow.
Detached: HEAD → commit directly
HEAD points at a commit, not a branch
HEAD ──▶ commit B
A───B───C ◀── mainYou enter this state when you check out a commit, tag, or remote-tracking ref — anything that is not a local branch.
How you end up here
Common triggers
git checkout 1f9ab2c # specific commit git checkout v1.0 # a tag git checkout origin/main # remote-tracking branch (read-only) git switch --detach 1f9ab2c # Git will warn: # Note: switching to '1f9ab2c'. # 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.
Why it exists
You may want to inspect an old commit — check what the code looked like at a specific point.
You may want to run a test against a tagged release without making changes.
You may want to experiment with changes you do not intend to keep.
CI/CD tools often check out a specific commit hash; their builds run in detached HEAD.
The danger
Detached, then made commits
HEAD ──▶ D───E
\
C ◀── main
|
B
|
A
After 'git switch main':
HEAD ──▶ main ──▶ C
D and E are orphaned. Reachable only via reflog.The safe way out: create a branch
Promote your experimental commits
# You made commits D and E in detached HEAD git switch -c keep-my-work # Now HEAD points to 'keep-my-work' which points to E # Your commits are saved
The other safe way: discard
If you don't want the commits, just switch away
git switch main # Warning: you are leaving 2 commits behind, not connected to any of your # branches: # abc1234 Experimental commit D # def5678 Experimental commit E # If you want to keep them by creating a new branch, this may be a good time # to do so with: # git branch <new-branch-name> def5678
Recovering after the fact
Even after you've switched, the reflog can save you
git reflog
# def5678 HEAD@{0}: checkout: moving from def5678 to main
# def5678 HEAD@{1}: commit: Experimental commit E
# abc1234 HEAD@{2}: commit: Experimental commit D
# 1f9ab2c HEAD@{3}: checkout: moving from main to 1f9ab2c
# Recover by creating a branch at that hash
git switch -c recovered-work def5678How to know you’re detached
git status # HEAD detached at 1f9ab2c # nothing to commit, working tree clean git branch # * (HEAD detached at 1f9ab2c) # feature-x # main
Intentional detached HEAD use cases
“What did this look like at v1.0?” —
git checkout v1.0, browse files,git switch -to come back.Running CI on a specific commit — pipelines check out by SHA in detached HEAD.
Bisecting —
git bisectworks in detached HEAD as it walks through history.Quick test — try a fix at an old commit without committing anything, then return to main.
The general rule
If you only want to look, detached HEAD is fine. If you start making commits, create a branch first:
# Instead of: git checkout 1f9ab2c # (make commits...) # Do: git switch -c temp-work 1f9ab2c # (make commits — they're on a branch, safe)
git switch -c <name>.