"Detached HEAD" means you have checked out a specific commit instead of a branch, so new commits you make are not attached to any branch name. To keep working from there, run git switch -c my-branch; to go back without keeping anything, run git switch main (or git switch - to return to the branch you came from).
Nothing is broken and no work is lost yet. The only risk is committing in this state and then switching away without a branch.
The message Git shows
This is the exact text from Git 2.45 after git checkout HEAD~2:
Note: switching to 'HEAD~2'.
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 -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at 5361315 first
Afterwards, git status starts with HEAD detached at 5361315 (or HEAD detached at v1.0 if you checked out a tag), and many shell prompts show a commit hash where the branch name used to be.
What "HEAD" and "detached" mean
HEAD is Git's pointer to "what you have checked out". Normally it points at a branch name, and the branch points at a commit. When you commit, the branch moves forward to the new commit and HEAD follows because it is attached to the branch.
In detached state, HEAD points straight at a commit. The Git docs illustrate it like this, with master at d and HEAD on b:
HEAD (refers to commit 'b')
|
v
a---b---c---d branch 'master' (refers to commit 'd')
If you commit now, the new commit e has b as its parent, but no branch moves to it. Only HEAD knows where it is.
How you ended up in detached HEAD
- Checking out a commit hash or relative ref:
git checkout 1a2b3c4,git checkout HEAD~2. - Checking out a tag:
git checkout v1.0. Tags are fixed labels, not branches, so Git cannot move them when you commit. - Checking out a remote-tracking branch directly:
git checkout origin/main.origin/mainis Git's record of the remote, not a local branch. (By contrast,git checkout featurewith no localfeaturebut a matching remote branch creates a local tracking branch, so you stay attached.) - A rebase that stopped on a conflict: during the rebase,
git branchshows(no branch, rebasing feature). Finish withgit rebase --continueorgit rebase --abortand the branch is reattached; don't create a branch here. - Submodules: by default
git submodule updatechecks out "the commit recorded in the superproject" on a detached HEAD inside each submodule. Rungit switch maininside the submodule before committing there.
The newer git switch command protects you from the first three by accident. It refuses anything that is not a branch:
$ git switch v1.0
fatal: a branch is expected, got tag 'v1.0'
hint: If you want to detach HEAD at the commit, try again with the --detach option.
So with switch, detaching is always deliberate: git switch --detach v1.0.
How to keep commits you made in detached HEAD
While you are still on the last of those commits, create a branch where you stand:
git switch -c keep-work
Example output:
Switched to a new branch 'keep-work'
Your commits are now on keep-work and HEAD is attached to it. git checkout -b keep-work does the same on older Git. Then merge or rebase it into the branch you want (see merge vs rebase).
The checkout docs list two variants that create a reference but leave you detached: git branch keep-work and git tag keep-work. Use them if you only want a bookmark.
If you already switched away
Git warns you when you leave commits behind. The real message:
Warning: you are leaving 1 commit behind, not connected to
any of your branches:
b950953 experiment
If you want to keep it by creating a new branch, this may be a good time
to do so with:
git branch <new-branch-name> b950953
Copy that hash and run the suggested command, for example git branch rescued b950953. If the message has scrolled away, find the commit in the reflog, which records every place HEAD has been:
git reflog -10
Look for the commit: lines made while detached, then create a branch at that hash. The docs explain why to do this promptly: unreferenced commits "will be deleted by the routine Git garbage collection process" eventually.
How to leave detached HEAD when you made no changes
git switch main
Or return to whichever branch you were on before:
git switch -
The - is shorthand for "the previous branch" (@{-1}). If you have uncommitted edits, Git may refuse with error: Your local changes to the following files would be overwritten by checkout. Commit them on a new branch with git switch -c, stash them with git stash, or discard them with git restore . if you don't need them.
When detached HEAD is exactly what you want
Looking at an old version to see whether a bug existed, building a release from a tag, or trying a quick experiment you plan to throw away are all legitimate reasons. The docs describe --detach as being for "inspection and discardable experiments". If you decide halfway through that the experiment is worth keeping, git switch -c still works at any point, as the original message says ("now or later").
If what you actually wanted was to drop your last commit rather than look at an older one, see how to undo the last Git commit.
Frequently asked questions
- Is detached HEAD state bad?
- No. It is a normal state for looking at an old commit, or building a tagged release. It only becomes a problem if you make commits there and then switch away without creating a branch, because nothing then points at those commits.
- How do I get out of detached HEAD without losing anything?
- If you made no commits, run git switch main (or any branch name) and you are back. If you made commits you want to keep, run git switch -c new-branch-name first; that creates a branch at your current commit and attaches HEAD to it.
- Why did git switch refuse with 'a branch is expected'?
- git switch only moves between branches unless you ask otherwise. Giving it a tag or commit prints 'fatal: a branch is expected, got tag ...'. Add --detach (git switch --detach v1.0) if you meant to look at that commit, or use git switch -c to start a new branch from it.
- How long do lost detached commits stay recoverable?
- Until Git's garbage collection removes unreachable commits. While they are still listed in git reflog you can recover them by hash with git branch name hash. Don't rely on this for long; create the branch as soon as you notice.