Bring detached HEAD work back onto a Git branch

Save detached commits with a branch, integrate them into the intended target, and distinguish committed recovery from uncommitted work.

Best practices
Illustration of Git branches and version history

If you made commits while HEAD was detached, create a branch at the current commit before leaving it. If you were only inspecting history and have no work to preserve, switch back to the intended branch. Detached HEAD is a normal state, not an error by itself.

Understand the state first

Normally HEAD refers to a branch, which identifies a commit. In detached mode, HEAD identifies a commit directly. Checking out a tag or commit can produce this state; rebase, bisect, and CI checkouts can also use it intentionally.

Run git status. If another operation is in progress, follow that operation's continue, abort, or reset workflow rather than switching branches arbitrarily. In the examples below, replace main with the actual target; origin is a remote name, not a branch.

Keep and integrate your work

git switch -c my-fix
git status
# If there are intended uncommitted changes:
git add -- path/to/intended-file
git diff --cached
git commit -m "Fix discovered while inspecting history"

The new branch makes the current commit reachable, including its detached ancestors. Uncommitted changes remain in the index and working tree; merely creating a branch does not store those contents in a commit.

With the work saved and the checkout ready to switch:

git switch main
git pull --ff-only
git merge my-fix

This pull assumes main has the intended upstream. If it has diverged, stop and choose a reconciliation strategy rather than forcing it. Review and test the merge, then publish with git push origin main when that is the intended destination.

Return without keeping the experiment

If the checkout is clean, git switch main returns to the branch. git switch - selects the previous checkout, which may itself have been detached.

Before discarding work, inspect git status, git diff, and git diff --cached. A rescue branch saves commits; save uncommitted files separately or use an appropriate stash. A normal switch can carry compatible local changes and therefore does not always stop to warn you. git switch --discard-changes main discards tracked index and working-tree changes; it is not a general untracked-file cleanup command. Ignored files can also be overwritten when switching, so do not use ignore rules as a backup policy.

Recovery and prevention

If you already switched away, inspect git reflog, then create git branch rescued COMMIT_ID while the object is still available. There is no guaranteed recovery window: reflog expiration and object cleanup vary.

For future experiments, git switch -c experiment COMMIT_ID creates a branch immediately. Use git switch --detach COMMIT_ID when detached inspection is intentional. An explicit pull can sometimes update detached HEAD, but does not create a branch; saving a named branch first is usually clearer for ongoing work. CI jobs that intentionally test a fixed commit normally need no such conversion.

See git-switch, git-pull, and git-reflog.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting