Detached HEAD in Git: Diagnose It, Recover Your Commits, and Reattach Safely
Git says 'HEAD detached' and your commits feel one wrong command away from disappearing. Diagnose the state, save unreferenced work with a branch or the reflog, and reattach safely.
01 Dec 2025, 07:31 UTC

You ran git checkout on a commit hash — maybe to inspect an old version — and now git status says HEAD detached at a1b2c3d. Worse, you may have already made commits in this state. The good news: nothing is lost yet. A detached HEAD is not corruption; it is Git pointing directly at a commit instead of at a branch label. The risk only appears when you move HEAD away without saving a reference to any new commits you made.
What the condition looks like
Run git status in your repository. A detached state reports:
HEAD detached at a1b2c3d
nothing to commit, working tree cleanNormally, HEAD points to a branch (for example main), and the branch points to a commit. When you check out a commit hash, a tag, or a remote-tracking branch such as origin/main, Git skips the branch layer and points HEAD at the commit itself. Commits you create now advance HEAD but update no branch, so no name points at them. Git warns you about this at checkout time, but the warning is easy to scroll past.
Cause and diagnostic table
| What you observe | Likely cause | First check |
|---|---|---|
HEAD detached at <hash>, no new work done | Checked out a commit, tag, or remote branch to inspect it | git log -1 --oneline |
| Detached, with commits made after detaching | Started editing after a historical checkout | git log --oneline -5 vs. the branch tip |
| Detached during a rebase or bisect | Normal — these operations detach HEAD temporarily | git status mentions rebase/bisect in progress |
| Already switched away, work seems gone | Commits left unreferenced when HEAD moved | git reflog |
Ordered checks before you change anything
- Confirm the state. Run
git statusand note the exact hash after "detached at". These are read-only commands; run them as your normal user in the repository. - See whether you have unreferenced commits. Run
git log --oneline -5and compare the top hashes against the branch you came from (git log --oneline -3 main). Any commits above the branch tip exist only on the detached HEAD. - Check for uncommitted changes.
git statusshows modified or staged files. These survive a branch switch only if there is no conflict, so decide whether to commit or stash them first. - Rule out an in-progress operation. If
git statussays a rebase or bisect is underway, do not just switch branches — finish or abort that operation first (git rebase --abortorgit bisect reset).
Fixes matched to what you found
Case 1: No new commits, just browsing
Simply return to your branch:
git switch mainOr git checkout main on older Git versions (the switch command was added in Git 2.23). Verify with git status — it should now read On branch main.
Case 2: You made commits worth keeping
Create a branch at the current position before moving anywhere. This attaches a permanent name to your work:
git switch -c recovery-workHEAD is now attached to the new branch recovery-work, and your commits are safe. From here you can merge or rebase onto your main line, or push the branch to a remote. Verify with git branch --show-current, which prints the branch name only when HEAD is attached.
Case 3: You already switched away and the work "disappeared"
The commits still exist; only the pointer is gone. The reflog records every position HEAD has held:
git reflogLook for entries like commit: my message made while detached, and note the hash. Then create a branch at that hash:
git branch recovery-work <hash>
git switch recovery-workConfirm recovery with git log --oneline -3 — your commits should be at the tip. Do this promptly: orphaned commits are eventually pruned by garbage collection (git gc), typically after a grace period, so reflog recovery is not a permanent safety net.
Case 4: The detached commits were experimental and unwanted
Switch back to your branch and let them become orphaned:
git switch mainGit will print a warning listing the commits you are leaving behind — that warning is your last easy chance to copy the hash. Avoid git reset --hard while detached; it offers no benefit here and increases the chance of losing work you actually wanted.
What not to do
- Do not push from a detached HEAD.
git push origin HEAD:mainfrom a detached state can update the remote branch in ways that are hard to reason about and easy to get wrong. Create a local branch first, then push that. - Do not run a hard reset while detached unless you are certain the commits are disposable — unreferenced commits become much harder to find afterward.
- Do not ignore a mid-rebase or mid-bisect detachment. Those are expected states; "fixing" them by switching branches abandons the operation.
When to escalate
Handle it yourself when the reflog shows your commits and you can branch them cleanly. Stop and get help from a teammate or your repository administrator when: the reflog entry you need is missing or ambiguous, the repository is shared and someone else may have force-pushed, or you already rangit gc or a hard reset and the commits no longer appear in the reflog. At that point, git fsck --lost-found can sometimes surface dangling commits, but recovery becomes specialist work — avoid further state-changing commands until someone experienced looks at it.A quick prevention habit
If you only want to look at an old commit, prefer read-only views: git show <hash> for a single commit, or git log -p for history. If you intend to experiment, create the branch first with git switch -c experiment <hash> — you start attached, and anything you commit is automatically referenced. That one habit eliminates the entire class of detached-HEAD recovery work.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.