Common causes
- Checking out a specific commit hash or tag, such as git checkout v2.1.0
- Checking out a remote-tracking branch directly, such as git checkout origin/main
- Git submodules, which are checked out at a fixed commit by default
- An interrupted rebase or bisect that leaves HEAD on a commit
- CI systems and some IDEs checking out a commit instead of a branch
How to fix it
- Check where you are. Run git status. 'HEAD detached at 1a2b3c4' confirms the state, and git log --oneline -5 shows whether you made any commits since detaching.
- Return to a branch if you made no changes. Run git switch main (or git checkout main). Nothing is lost if you did not commit anything while detached.
- Keep commits made while detached. Run git switch -c my-work to create a branch at the current commit. Then merge or rebase that branch into main as usual.
- Recover commits after switching away. Run git reflog, find the commit you made (for example 9f8e7d6 HEAD@{2}: commit: fix header) and run git branch rescue 9f8e7d6. Reflog entries for commits not on any branch are kept for 30 days by default, so recover them before garbage collection removes them.
- Finish or abort rebase and bisect. If a rebase or bisect is in progress, run git rebase --continue or git rebase --abort, or git bisect reset. These return you to your branch.
- Put submodules on a branch. Inside the submodule run git switch main before editing, or update with git submodule update --remote --merge so changes land on a branch.
Terminal
git status # HEAD detached at 1a2b3c4
git switch -c my-work # keep commits made while detached
git switch main # or just go back
# recover commits after leaving them
git reflog
git branch rescue 9f8e7d6 How to stop it happening again
- Use git switch for branches and git switch --detach only when you mean to detach
- Create a local branch from a remote one with git switch main instead of git checkout origin/main
- Run git status before committing to confirm you are on a branch
- Show the current branch in your shell prompt