Getting Out of Git Detached HEAD — Causes and Recovering Commits
You check out a commit hash to look at an old version of the code, and a long, unfamiliar warning appears.
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.The sheer length of the warning makes it look like a serious accident, so let’s settle the conclusion first. Detached HEAD is not a malfunction — it is simply the state where HEAD points directly at a commit instead of a branch. The state itself breaks nothing. But if you make commits in this state and walk away without doing anything, you can lose them, so the structure and the exits are worth knowing.
What it means for HEAD to be detached #
Normally HEAD points not at a commit but at a branch. When you commit on main, the main pointer advances to the new commit, and HEAD follows main along automatically.
But when you check out a specific commit hash or a tag directly, rather than a branch, HEAD ends up pointing straight at that commit without a branch in between. It has come off the branch — hence detached, a detached HEAD.
[normal — attached]
HEAD ──▶ main ──▶ C3
[detached]
HEAD ──────────▶ C1 (no branch in between)There are roughly three paths into the detached state.
- Checking out an old commit or a tag directly —
git checkout 1a2b3c4,git checkout v2.1.0, or explicitlygit switch --detach 1a2b3c4 - While bisect is running — the binary search checks out one middle commit after another, so you stay detached for the whole hunt. Ending it with
git bisect resetputs you back. - Inside a submodule — a submodule references a repository pinned to a specific commit by design, so inside that directory you are detached by default.
What the actual risk is — commits that belong to no branch #
If you only read code in the detached state, there is no danger at all. The problem begins when you make commits.
A commit made on a branch stays referenced by the branch pointer. A commit made in the detached state, however, is pointed at by no branch. The moment you leave with git switch main, those fresh commits become unreachable, and in time they become targets for garbage collection. Git knows this, which is why it prints one last warning as you leave.
Warning: you are leaving 2 commits behind, not connected to
any of your branches:
8f3c2d1 experiment: tune cache size
5e9a7b4 experiment: print cache stats
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> 8f3c2d1The warning even spells out the fix. Put a branch on the commits.
Escape routes by situation #
How you get out of detached HEAD splits three ways, depending on what you did while you were there.
If you only looked around — just go back.
git switch -- means the branch you were on right before. If you made no commits, this one line ends the situation.
If you made commits and want to keep them — put a branch on them before leaving.
git switch -c experiment-cacheA new branch is created on the commit HEAD is pointing at, and HEAD reattaches to that branch. The commits are now referenced by a branch, so there is nothing left to lose.
If you already left and lost the commits — find the hash and put a branch on it.
The warning printed as you left has the commit hash in it, so create a branch from that hash.
git branch experiment-cache 8f3c2d1If you closed the terminal and lost the warning, search the reflog. Commits made in the detached state are all recorded there too. The procedure for tracking down the hash is covered in Recovering Deleted Git Commits and Branches with reflog.
git switch <branch> and then commit.The habit of looking around safely in the first place #
If you have a reason to inspect the code at some point in the past, it is cleaner to create a branch before going in.
git switch -c temp-look 1a2b3c4
# when you are done
git switch main
git branch -d temp-lookSince the detached state never comes into being, there is no warning and no chance of losing commits. If you only looked and never committed, deleting the branch cleans everything up without a trace.
Wrap-up #
The key points of this post are three.
- Detached HEAD is the state where HEAD points directly at a commit instead of a branch, and by itself it breaks nothing.
- The risk lies only in commits made in this state. Putting a branch on them with
git switch -c <branch>before leaving keeps them safe, and if you already left, recover with the hash from the warning or from the reflog. - If you create a temporary branch from the start when inspecting old code, you never meet this state at all.
The warning reads as threatening because it is long, but its content is closer to guidance. Once you understand the structure, detached HEAD is not an accident but a free exploration mode that Git provides.