Overview
The error fatal: You are not currently on a branch occurs when HEAD points directly to a commit instead of a branch tip. This is a detached HEAD state. Actions that move a branch (pull, merge, revert) fail because there is no branch to update.
Typical causes:
- Checking out a specific commit, tag, or remote ref (e.g., git checkout <sha>, git checkout v1.2.3)
- Interactive operations (rebase, bisect) that temporarily detach HEAD
- CI pipelines that clone a specific commit instead of a branch
Quickstart (TL;DR)
Choose one path based on your intent:
- Keep your current work and continue: create a branch from the detached state
- git switch -c fix/keep-my-work
- Discard local changes and return to a branch
- git switch main
- You wanted to work from a tag or commit but on a branch
- git switch -c hotfix/from-tag
- Detached after rebase/bisect and want to back out
- git rebase --abort or git bisect reset
Minimal working example
This script shows the error and a fix.
#!/usr/bin/env bash
set -euo pipefail
# Create a demo repo
rm -rf demo-detached && mkdir demo-detached && cd demo-detached
git init -q
echo one > app.txt
git add app.txt
git commit -qm 'init'
echo two >> app.txt
git commit -am 'second commit' -q
# Detach to the previous commit
git checkout HEAD~1 -q
# Attempt a merge while detached (will fail)
set +e
git merge main 2>err.log
status=$?
set -e
printf "merge exit code: %s\n" "$status"
cat err.log | sed -n '1,2p'
# Fix: create a branch from the detached state and proceed
git switch -c fix/work -q
# Now merges are allowed because we are on a branch
# git merge main (if main exists)
Expected failure snippet contains:
fatal: You are not currently on a branch
Core fixes by scenario
Keep the current state and continue development
- git switch -c <new-branch>
- Explanation: you create a branch at the detached commit. Your subsequent commits now advance that branch.
Return to an existing branch (e.g., main)
- If you have no uncommitted changes: git switch main
- If you have uncommitted changes that conflict with switching:
- Save them: git stash -u; git switch main; git stash pop
- Or commit them on a new branch: git switch -c tmp/save-work
You checked out a tag
- Tags are immutable. Create a branch from the tag to make changes:
- git switch -c hotfix/v1.2.3 v1.2.3
- Tags are immutable. Create a branch from the tag to make changes:
You pulled or merged while detached
- Abort and move to the intended branch:
- git switch main
- If you need to integrate the detached commit: git merge <detached-sha> or cherry-pick specific commits
- Abort and move to the intended branch:
Detached due to rebase or bisect
- Rebase: git rebase --abort (or --continue, if appropriate)
- Bisect: git bisect reset
Identify where to go next
Find branches that contain your current commit:
git branch --contains HEAD
# remote branches that contain HEAD
git branch -r --contains HEAD
Tracking a remote branch if the local one is missing:
# Create a local branch that tracks origin/main
git switch -c main --track origin/main
Step-by-step procedure
Confirm detached state
- git status
- You will see: HEAD detached at <sha or tag>
Decide: keep, move, or discard
- Keep: git switch -c <feature-name>
- Move to a known branch: git switch <branch>
- Discard uncommitted work: git reset --hard; git switch <branch>
If switching is blocked by changes
- Save changes: git stash -u
- Or commit on a new branch: git add -A; git commit -m 'wip'; git switch <branch>
Resume normal workflow
- Pull latest: git pull --ff-only
- Push if you created a new branch: git push -u origin <branch>
Recovering commits made in detached HEAD
If you committed while detached, the commits exist but can be lost if not referenced. Recover them via reflog and branch them.
# Find the commit(s)
git reflog --date=local --abbrev
# Suppose you want commit <sha>
# Create a branch pointing to it
git branch rescue/<topic> <sha>
# or move your current branch to it (advanced)
# git reset --hard <sha>
Common pitfalls
- Assuming commits follow a branch automatically while detached.
- They do not. Always create a branch if you intend to keep the work.
- Switching away with uncommitted changes and losing track of them.
- Use git stash -u or commit to a temporary branch.
- Working on a tag and expecting git push to update it.
- Tags do not move; create a branch from the tag for changes.
- CI jobs checking out a specific commit, then trying to pull or merge.
- Ensure CI checks out a branch, or explicitly creates a branch from the commit.
DevOps and CI tips
- Ensure checkout is a branch when your job needs to merge or pull:
# Example: ensure a branch in CI even if given a SHA
sha=$(git rev-parse HEAD)
base_branch=${BASE_BRANCH:-main}
if [ "$(git rev-parse --abbrev-ref HEAD)" = HEAD ]; then
git switch -c ci/build-$sha --track origin/$base_branch || git switch -c ci/build-$sha $sha
fi
- Prefer fast-forward only pulls in automation to avoid unwanted merges:
- git pull --ff-only
- If your workflow checks out tags, create branches for hotfixes explicitly.
Performance notes
- Fetch selectively to speed up CI:
- git fetch --depth=50 --no-tags origin <branch>
- Avoid expensive history walks when locating branches:
- Use git branch --contains HEAD instead of scanning logs manually.
- Keep repos healthy to reduce command latency:
- Periodic: git gc --aggressive is rarely needed; prefer git gc and prune in maintenance windows.
- Use shallow clones for read-only jobs to reduce checkout time and bandwidth.
Quick scenario matrix
| Scenario | Symptom | Fix |
|---|---|---|
| Checked out a commit | git status shows HEAD detached | git switch -c feature/from-sha |
| Checked out a tag | Cannot commit to tag | git switch -c hotfix/from-tag vX.Y.Z |
| Need to get back to main | Merge or pull fails | git switch main |
| Rebase left you detached | Stuck mid-rebase | git rebase --abort or --continue |
| CI on a SHA | pull/merge fails | create a temp branch from HEAD |
Tiny FAQ
- Why did Git detach HEAD?
- You checked out something that is not a branch (commit, tag, or remote ref).
- Will I lose commits made while detached?
- Not immediately. Create a branch or note the SHA. If you move away without referencing them, garbage collection may eventually remove them.
- How do I avoid this in the future?
- Always use git switch -c to branch from commits or tags. In CI, ensure checkout uses a branch.
- Can I turn off detached head advice?
- You can mute advice, but better to fix the workflow. If needed: git config --global advice.detachedHead false