Why Did Git Detach My HEAD (and How to Get Back on a Branch Without Losing Work)

You ran a git command, the terminal printed “You are in ‘detached HEAD’ state”, and now every instinct says you have broken something. You almost certainly have not. Nothing is lost yet, and the recovery is two commands once you understand what HEAD is actually pointing at.

Detached HEAD panics more developers than any other Git state, and it panics them because the message sounds like an amputation rather than what it is: a completely normal, recoverable position that Git puts you in whenever you ask to stand on a commit rather than on a branch. This is a root-cause piece. We will fix the symptom, but the point is to leave you with a mental model of refs and HEAD so the state stops frightening you.

What HEAD normally points at, and what “detached” changes

Almost everything in Git is a reference (a ref) to a commit. A branch like main is nothing more than a movable pointer to one commit. HEAD is the ref that says “this is where I am right now”. In normal working, HEAD does not point at a commit directly. It points at a branch, and the branch points at the commit. That indirection is the whole trick: when you commit, Git advances the branch to the new commit and HEAD follows along, because HEAD is attached to the branch.

Free · 4 minutes

Is your engineering team shipping safely, or quietly accumulating risk?

Fourteen questions on how work gets from idea to production — cadence, testing, rollback, and the key-person risk in your delivery. Banded finding on screen, full sheet by email.

A detached HEAD removes the middle step. HEAD points straight at a commit SHA, with no branch in between. You can still look around, build, test and even commit. But when you make a new commit, there is no branch to advance. HEAD moves to the new commit, and that commit is held in place by nothing but HEAD itself. The moment you switch to a branch, HEAD lets go, and the commit you made is no longer reachable by any name.

The operations that trigger it

Git detaches HEAD whenever you ask to be at a specific commit rather than on a branch. The common triggers:

  • Checking out a tag or a raw SHA. git checkout v2.3.0 or git checkout 9f2c1a puts you on that exact commit. Tags do not move, so Git will not attach HEAD to one.
  • Checking out a remote-tracking ref directly. git checkout origin/main detaches, because origin/main is a read-only mirror of the remote, not a local branch you can commit to.
  • Running git bisect. Bisect parks you on each candidate commit in turn to test it. You are detached for the whole session by design.
  • An interactive rebase in flight. During git rebase -i, especially when a step stops at edit or hits a conflict, HEAD is detached while Git replays commits.

Modern Git tries to warn you. Since the git switch command settled in, the safe way to say “detach me on purpose” is git switch --detach <ref>, and git checkout prints the long advisory hint unless you have set advice.detachedHead false. CI systems detach constantly and silence that hint, which is why actions/checkout and similar runners leave you in a detached state as a matter of routine.

Reproduce it, then recover before you leave

The cleanest way to lose the fear is to create the state deliberately and walk out of it. This runs on any git 2.x:

# start on a branch, make a commit to point at
git switch -c demo
echo one > file.txt && git add file.txt && git commit -m "first"

# detach HEAD onto that commit's SHA
git switch --detach HEAD
git status        # => HEAD detached at 3a1f9c2

# do real work while detached
echo two >> file.txt && git commit -am "work made while detached"

# recover: give this commit a branch BEFORE switching away
git switch -c rescue
git log --oneline -2   # the detached commit is now safely on 'rescue'

That is the whole fix when you catch it in time. git switch -c <name> creates a branch at your current commit and attaches HEAD to it. The commit that was held by nothing is now held by a branch. You can keep working, push it, or open a pull request as normal.

You already switched away: rescue it with the reflog

The harder case is when you committed while detached, then ran git switch main and only afterwards realised your work is gone from every branch. It is not deleted. Git keeps a private log of everywhere HEAD has been, and that log still holds the SHA. This is the single most useful recovery tool in Git, and most developers never learn it.

# show recent HEAD positions, newest first
git reflog

# example output
# 8d4e2a1 HEAD@{0}: checkout: moving from 7c9b0f4 to main
# 7c9b0f4 HEAD@{1}: commit: work made while detached
# 3a1f9c2 HEAD@{2}: checkout: moving from demo to 3a1f9c2

# 7c9b0f4 is the lost commit. give it a branch.
git branch rescue 7c9b0f4
git switch rescue

Read the reflog as a diary of HEAD. The line describing your commit shows its SHA on the left; git branch rescue <sha> pins a name to it and you are whole again. You can equally use git switch -c rescue 7c9b0f4 to create the branch and move onto it in one step.

There is a clock on this. Git’s garbage collector eventually prunes commits that no ref can reach. By default, reflog entries for reachable commits expire after 90 days (gc.reflogExpire) and unreachable ones after 30 days (gc.reflogExpireUnreachable). A commit orphaned in a detached HEAD is unreachable, so you realistically have around a month before git gc can collect it. In practice that is ample — you find these within minutes — but do not treat the reflog as long-term storage.

The habit that makes it a non-event

Detached HEAD is not a bug and not a failure. It is Git telling you the truth: you are standing on a commit, not on a branch, and anything you build here needs a name before you walk away. The discipline is small. If you find yourself detached and about to commit, run git switch -c first. If you have already left, reach for git reflog before you touch anything else.

The wider point for anyone running a team is that this is exactly the kind of quiet Git literacy that separates a smooth delivery function from a jumpy one. It is the same category of competence as a pre-commit baseline that actually runs or a sensible read on whether your developers are doing good work without reading every line — undramatic fundamentals that keep work from being lost and keep your delivery metrics honest. A developer who panics at a detached HEAD loses an afternoon. One who knows the reflog loses thirty seconds.

Build and rescue work

Hands-on delivery of this kind is handled by Sixteen Pillars Studio.

Free interactive tool

Website compliance checklist

What your site has to do, based on what it actually does

Answer as much or as little as you like — the list builds as you go. Nothing is stored against your name and no email is required.

Most technology problems are not technology problems. They are control problems.

The systems exist. The investment has been made. The question is whether leadership can understand, direct, evidence, and sustain what those systems produce. Find out where control exists — and where it only appears to.