Back to blog

How to Fix Git Detached HEAD State: A Step-by-Step Recovery Guide

If you use Git frequently, you have likely run into this warning: "You are in detached HEAD state".

This state sounds alarming, and to many developers, it feels like they have broken their repository or lost their code. However, a detached HEAD is a natural Git state. It is highly useful for inspecting older commits, but it becomes dangerous if you start committing new code without understanding how pointers work.

In this guide, we will break down what a detached HEAD is, explain why it happens, and demonstrate how to save your changes or recover lost commits using git reflog.

What is a Detached HEAD?

In Git, the HEAD pointer points to the specific commit you are currently viewing.

Normally, the HEAD pointer does not point to a commit directly; instead, it points to a Branch Pointer (like main or feature), which then points to the latest commit on that branch. When you make a new commit, your branch pointer moves forward automatically, and HEAD moves with it.

A Detached HEAD occurs when the HEAD pointer points directly to a specific commit hash rather than a branch name.

How You Got Here

The most common way to detach HEAD is checking out a specific historical commit:

git checkout a1b2c3d

Because a1b2c3d is a commit hash and not a branch name, Git detaches HEAD from the branch pointers and hooks it directly to that commit. You are now looking at a snapshot of your repository from the past.

You can also land in this state when:

  • Checking out a remote tracking branch directly without creating a local branch.
  • Checking out a tag (e.g., git checkout v1.0.0).
  • Initiating a Git rebase or cherry-pick operation that gets interrupted due to merge conflicts.

The Danger of Committing in Detached HEAD

You can edit code and write commits while in a detached HEAD state. However, because there is no branch pointer tracking these new commits, they are orphaned.

If you write three commits while detached, and then run git checkout main to switch back to your master branch:

  1. The HEAD pointer moves back to main.
  2. The new commits you created while detached are left floating in the repository database with no reference pointing to them.
  3. Over time, Git's automatic garbage collection (git gc) will delete these orphaned commits permanently.

How to Save Your Changes

If you are currently in a detached HEAD state and have written commits that you want to keep:

Solution 1: Create a New Branch (Recommended)

To save your commits, create a new branch pointer right where you are. This links the floating commits to a named branch, securing them:

git checkout -b my-saved-work

This merges the changes into a clean local branch. You can then switch back to main and merge your new branch:

git checkout main
git merge my-saved-work

Solution 2: Discard the Changes

If you only checked out a commit to read historical code and do not want to keep any changes, simply return to your working branch:

git checkout main

How to Recover Lost Commits (Using Reflog)

If you made commits in a detached HEAD state, forgot to create a branch, switched back to main, and now realize your work has disappeared: do not panic. The commits still exist in Git's database database.

Use git reflog to view a history of all pointer movements:

git reflog

The output displays a list of actions with index markers:

7c2a13b HEAD@{0}: checkout: moving from 9f3e4d2 to main
9f3e4d2 HEAD@{1}: commit: Added experimental feature
a1b2c3d HEAD@{2}: checkout: moving from main to a1b2c3d

In this case, 9f3e4d2 is the commit hash of your "lost" work. To recover it, create a new branch referencing that specific hash:

git branch recovery-branch 9f3e4d2

You can now checkout recovery-branch to find your commits intact.

Conclusion

A detached HEAD is a standard, useful Git state for reviewing historical snapshots of your project. By remembering to create a new branch (git checkout -b) before leaving the detached state, you can secure any experimental commits you wrote, and if you ever get lost, git reflog acts as your ultimate safety net to recover orphaned commits.