How to Recover Lost Git Changes After Accidentally Checking Out from “(no branch)” State


2 views

When working with Git, you might occasionally find yourself in this peculiar state:

git branch
* (no branch)
  master

This typically occurs when:

  • You're in a detached HEAD state (usually after checking out a specific commit)
  • You've rebased or cherry-picked changes
  • You've performed an interactive rebase

When you ran git checkout master, Git essentially abandoned your uncommitted work from the detached HEAD state. However, your changes might still be recoverable through several methods.

1. Check Git Reflog

The reflog is your first line of defense:

git reflog
# Look for entries mentioning "checkout" or "commit"
# Example output:
# a1b2c3d HEAD@{2}: checkout: moving from a1b2c3d to master
# e4f5g6h HEAD@{3}: commit: Your lost commit message

Once you identify the hash of your lost commit:

git checkout e4f5g6h
# Or create a new branch to preserve it:
git branch recovery-branch e4f5g6h

2. Search for Orphaned Commits

Git doesn't immediately garbage collect lost commits:

git fsck --lost-found
# Then examine dangling commits:
git show [commit-hash]

3. Check Stash (Just in Case)

While unlikely in this scenario, it doesn't hurt to check:

git stash list

To avoid this situation:

# Always create a temporary branch when working in detached HEAD:
git checkout -b temp-branch

# Or if you realize you're in (no branch):
git branch temp-branch
git checkout temp-branch

If you had staged but uncommitted changes, they might still exist in Git's object database. Try:

git fsck --unreachable | grep blob | awk '{print $3}' | xargs -n 1 git show

This will show all unreachable blobs (file contents) that Git still knows about but aren't referenced by any commit.


When you see * (no branch) in your Git status, it means you're in a "detached HEAD" state. This typically occurs when:

  • You checkout a specific commit hash instead of a branch
  • You checkout a remote branch without creating a local tracking branch
  • You rebase or bisect and Git puts you in this temporary state

When you ran git checkout master, Git essentially did this:

# What really happened behind the scenes
git stash          # if you had uncommitted changes
git checkout master # switches to master branch
git clean -fd      # removes untracked files

Method 1: Using Git Reflog

The most reliable way to recover lost commits:

git reflog
# Look for lines containing "commit" or "checkout"
# Example output:
# a1b2c3d HEAD@{2}: commit: My lost changes
# e4f5g6h HEAD@{3}: checkout: moving from a1b2c3d to master

git checkout -b recovery-branch a1b2c3d

Method 2: Finding Orphaned Commits

Git keeps unreferenced commits for about 30 days:

git fsck --lost-found
# Then inspect the dangling commits:
git show [commit-hash]

Method 3: Checking Stash

Git might have automatically stashed your changes:

git stash list
git stash apply stash@{0}

Best practices when working with branches:

# Always create a branch when in detached HEAD
git checkout -b temp-branch

# Verify branch status before checking out
git status
git branch -vva

# Push your work frequently
git push origin HEAD

Here's what a complete recovery session might look like:

$ git reflog
a1b2c3d HEAD@{5}: commit: Implement new API endpoints
e4f5g6h HEAD@{6}: checkout: moving from master to v1.2.3
[...]

$ git checkout -b api-work a1b2c3d
Switched to a new branch 'api-work'

$ git log --oneline -n 3
a1b2c3d (HEAD -> api-work) Implement new API endpoints
b2c3d4e Update documentation
c3d4e5f Fix login bug