Detached HEAD Recovery

Understand detached HEAD and recover from it — Git Tutorial. Learn what causes a detached HEAD, how to inspect your state, and safe recovery paths.

Focus: understand detached head and recover from it

Sponsored

You’re mid-feature, you checkout a commit hash to peek at an old version, and suddenly git status tells you you’re not on any branch. Your next commit seems to vanish into thin air. This is the infamous detached HEAD — and it’s scary only until you understand it. In this lesson, you’ll learn exactly what a detached HEAD is, why it happens, and how to recover from it safely using branches, tags, and the reflog. By the end, you’ll handle detached HEAD like a pro — and know how to turn any “lost” commit into a saved one.

The problem this lesson solves

A detached HEAD is Git’s way of telling you that your HEAD is pointing directly at a commit, not at a branch reference. When you git checkout <sha>, HEAD detaches — and any commit you make there is orphaned the moment you switch away. Without recovery, that work feels lost.

The pain is real: you experiment on an old release, make a couple of commits, then git checkout main — and your changes exist nowhere. You can’t see them in git branch. Panic sets in.

This lesson removes that panic. You’ll learn how to recognize a detached HEAD, inspect your new commits, and either preserve them with a new or existing branch, discard them cleanly, or recover them via the reflog — even if you already switched away.

Core concept / mental model

Think of branches as sticky notes pointing to commits. HEAD is your current location — normally, it points to a sticky note (a branch). In a detached HEAD state, Git removes the sticky note and HEAD points directly at the commit itself. The commit is still there, but without a branch, it’s not referenced — and unreferenced commits can be garbage-collected.

Normal:

  main --> C3 (HEAD)

Detached:

  HEAD --> C2
  main --> C3

The key insight: a detached HEAD is not an error — it’s an unlabeled pointer. It’s perfect for inspection or historical work, but dangerous for new commits unless you attach a branch.

How it works step by step

Detaching: what triggers it

HEAD detaches in three common ways:

  • Running git checkout <commit-sha>
  • Running git checkout <tag>
  • Running git checkout HEAD~2 (or any commit-ish expression that isn’t a branch name)

All three place HEAD at a commit directly, bypassing any branch label.

Recognizing it

Git prints a warning on checkout, and git status shows:

HEAD detached at 4a3b9c2

Committing while detached

New commits simply advance HEAD. They’re stored in .git/objects but not referenced by any branch.

Recovering: your options

  • Create a new branch from the current commit: preserves your work permanently.
  • Point an existing branch at the current commit: repurposes a branch to include your new work.
  • Return to a branch and keep no changes: if you don’t need the work.
  • Use the reflog to find lost commits after you’ve switched away.

Hands-on walkthrough

Let’s walk through a full scenario from detachment to recovery.

1. Set up a test repo

mkdir detached-demo && cd detached-demo
git init
echo "initial" > file.txt
git add file.txt
git commit -m "Initial commit"
echo "more" >> file.txt
git commit -am "Second commit"

2. Detach HEAD

# Get the latest commit SHA
git log --oneline HEAD~1 -1
# Output: <sha> Second commit

# Detach at the second commit
git checkout HEAD~1

You’ll see the warning:

Note: switching to 'HEAD~1'.
You are in 'detached HEAD' state...

3. Make a commit in the detached state

echo "experiment" >> file.txt
git commit -am "Experimental change"

HEAD now points to a new commit that’s not on any branch.

4. Inspect your state

git status
# Output: HEAD detached at <sha>
git log --oneline -3
# Output shows your new commit at the top

5. Recover: create a new branch

git branch experiment

This labels your current commit. Now HEAD still points at the commit, but you can safely switch:

git checkout experiment
# Or simply: git switch experiment

Your work is now preserved on experiment.

6. Recover: point an existing branch at it

If you prefer to fold the work into main (or any other branch), you can force-update that branch:

git branch -f main

Caution: this overwrites main — use only if you’re sure the old main is disposable. A safer alternative is to use git switch --discard-changes after noting the SHA.

7. Recover after switching away (reflog)

If you already switched back to main and your commit seems lost, find it via the reflog:

git reflog

You’ll see entries like 9c4a2d1 HEAD@{1}: checkout: moving from main to HEAD~1 and your commit’s SHA from your detached work. Then:

git branch rescue 9c4a2d1

Your work is safe again.

Compare options / when to choose what

Method When to use Pros Cons
git branch <name> Preserve work as a new feature Safe, explicit, no force needed Creates a new branch you must later merge
git branch -f <existing> Replace existing branch with detached work Reuses branch name Dangerous — overwrites history
git checkout <branch> (no commit) No changes made, just exploring Zero side effects None
git reflog + git branch Already moved away Recovers any lost commit Extra steps; reflog history can expire
git cherry-pick <sha> Pull specific commits Selective, no branch juggling Requires manual conflict resolution

Rule of thumb: If you made commits while detached, create a new branch. If you only inspected, just check out your original branch — no harm done.

Troubleshooting & edge cases

“I switched away before creating a branch — my work is gone!”

It’s not gone — it’s in the reflog. Run git reflog, find the commit SHA, then git branch to rescue it. Act quickly because reflog entries expire (default 90 days).

“I did git branch -f main and now my main is wrong!”

You overwrote main with the detached commit. To undo, find the old main SHA from the reflog: git reflog show main, then git reset --hard <sha> — or git branch -f main with the correct SHA.

“I want to discard the detached commits entirely.”

Simply git checkout main (or git switch main). Your detached commits remain in the reflog but are no longer referenced — they’ll be garbage-collected eventually. No branch needed.

git checkout gives me ‘pathspec did not match’ errors.”

That happens when you mix commit SHAs with branch names. Ensure you’re using the full (or unique abbreviation) SHA, and avoid spaces.

“I’m stuck in detached HEAD with uncommitted changes.”

Run git stash before switching away, or use git switch --discard-changes only if you don’t need them. To keep them, git branch first.

What you learned & what's next

You now understand what a detached HEAD is, how to identify it, and several safe ways to recover from it. You learned to create a new branch to preserve your work, to force-update an existing branch, and to use the reflog to rescue lost commits — even after you’ve moved on. You can also confidently discard detached work when you’re done experimenting.

Next lesson: Now that you can rescue orphaned commits, the next step is to master refs and remotes — how branches, tags, and remote-tracking references work together, and how to manage upstreams without losing your head.

Practice recap

Create a scratch repository, check out HEAD~2 to detach, make a commit, then recover it with a new branch. Then simulate losing it by switching back to main and rescue it via the reflog. Repeat until the flow is automatic — it’s the same muscle memory you’ll use in real projects.

Common mistakes

  • Switching back to a branch before creating a new branch — your detached commits aren’t lost, but they become unreferenced; use git reflog to recover them.
  • Forcing an existing branch with git branch -f without checking what it overwrites — you can accidentally destroy work you meant to keep.
  • Assuming git checkout <commit-sha> is harmless for inspection — it’s fine for reading, but any commit you make there creates orphaned commits unless you attach a branch.
  • Panicking and running git reset --hard immediately when detached, losing uncommitted work that could have been stashed or branched first.

Variations

  1. Use git switch instead of git checkout for branch switches — it safer and more explicit when detaching.
  2. Use git cherry-pick to copy specific commits from a detached HEAD to your current branch without creating a new branch.
  3. Set up a detached HEAD automatically with git switch --detach <commit> for explicit, readable detachment.

Real-world use cases

  • Inspect a bug-fix tag (e.g., v1.2.3) on a production checkout to reproduce a customer issue, then safely return to main without side effects.
  • Accidentally stumble into a detached HEAD during a code review, make a quick comment commit, and later preserve it as a suggestion branch with git branch.
  • Recover an experimental commit made in detached HEAD a week ago via git reflog and merge it into your feature branch with git cherry-pick.

Key takeaways

  • Detached HEAD means HEAD points directly at a commit, not a branch — it’s not an error, just an unlabeled location.
  • Always create a new branch (git branch <name>) before making permanent commits in a detached state.
  • Use git reflog to recover any commit you think you lost after switching branches.
  • Use git branch -f <existing> with extreme caution — it overwrites history.
  • If you make no commits while detached, simply git checkout <branch> returns you to normal with zero side effects.
  • Practice detachment in a scratch repo to build muscle memory for safe recovery.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.