What's Actually Happening

A "detached HEAD" means Git's HEAD pointer is pointing directly to a commit hash instead of a branch name. Normally HEAD points to a branch (like main), which points to a commit. In detached state, HEAD points straight to a commit.

The Warning You'll See

```bash $ git checkout abc123 Note: switching to 'abc123'.

You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example:

git switch -c <new-branch-name>

Or undo this operation with: git switch - ```

Why This Happens

  1. 1.Checking out a commit hash - git checkout abc123d
  2. 2.Checking out a tag - git checkout v1.0.0
  3. 3.Rebase operation - During interactive rebase
  4. 4.Checking out a remote branch without tracking - git checkout origin/feature

Step 1: Check Your Current State

bash
git status

Shows:

bash
HEAD detached at abc123d
nothing to commit, working tree clean

Or if you have changes:

bash
HEAD detached at abc123d
Changes to be committed:
  (use "git commit"...) 
	modified:   src/app.js

Step 2: If You Haven't Made Changes

Just want to look at old code? No worries:

bash
# Return to your previous branch
git switch -
# Or:
git checkout main

Nothing lost - you were just viewing.

Step 3: If You Made Commits in Detached State

Critical: Save your work before switching away!

First, see what commits you made:

bash
git log --oneline -5

Shows your new commits on top of the detached point:

bash
def4567 (HEAD) My experimental change
abc123d Original commit I checked out

Create a branch to save these commits:

```bash # Create branch from current detached HEAD git branch my-experiment

# Or use switch with -c git switch -c my-experiment ```

Now your commits are saved on my-experiment branch.

Step 4: If You Made Uncommitted Changes

If you edited files but haven't committed:

bash
# Check what you changed
git status
git diff

Save by creating a branch and committing:

bash
git switch -c my-new-feature
git add .
git commit -m "Save work from detached state"

Step 5: Recover Lost Commits (If You Already Switched Away)

If you panicked and switched away, losing commits:

bash
# Check reflog for recent HEAD positions
git reflog

Output shows your movements:

bash
abc123d HEAD@{0}: checkout: moving from def4567 to abc123d
def4567 HEAD@{1}: commit: My experimental change
abc123d HEAD@{2}: checkout: moving from main to abc123d

Find your lost commit (def4567) and recover:

```bash # Create branch pointing to lost commit git branch recovered-work def4567

# Switch to it git switch recovered-work ```

Step 6: Understanding Reflog Recovery

Reflog keeps history of HEAD movements for ~90 days:

```bash # See all recent HEAD positions git reflog show HEAD

# Find specific action git reflog show HEAD --grep="commit" ```

Each entry shows where HEAD was, so you can return there.

Step 7: Intentional Detached HEAD Use

Sometimes detached HEAD is useful:

```bash # View old version of code git checkout v2.0.0

# Test against specific commit git checkout abc123d

# Start experiment without creating branch yet git checkout main~5 # 5 commits before main ```

Just remember: any commits you make need a branch to save them.

Verify the Fix

After creating branch and saving work:

```bash git status

# Should show: # On branch my-experiment # nothing to commit, working tree clean

git log --oneline -3 # Your commits should be visible ```

Prevention Tips

When checking out specific commits, use -c flag to create branch immediately:

```bash # Create branch while checking out commit git switch -c inspect-v1.0 v1.0.0

# Or with checkout git checkout -b inspect-v1.0 v1.0.0 ```

This avoids detached state entirely.