Git "detached HEAD" state in CI
CI checkouts deliberately check out the exact commit SHA, not a branch, so HEAD is detached. That is fine for building, but steps that need a branch name or want to push will fail or push nowhere useful.
What this error means
Git reports HEAD detached at <sha>. git rev-parse --abbrev-ref HEAD returns HEAD, branch-name scripts return empty, and a push fails or goes to a dangling ref.
Note: switching to '9fceb02'.
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.Common causes
CI checks out a commit, not a branch
actions/checkout and most CI runners check out the triggering SHA so builds are reproducible, which leaves HEAD detached.
A script assumes a current branch
Tooling that reads the branch from git rev-parse --abbrev-ref HEAD gets HEAD and either errors or uses the wrong value.
A push from detached HEAD has no upstream
Without a local branch tracking a remote ref, the push has no obvious destination.
How to fix it
Read the branch from CI metadata
- Use the CI-provided branch variable instead of parsing git HEAD.
- On Actions use github.ref_name or GITHUB_HEAD_REF for pull requests.
BRANCH="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME}}"
echo "Building branch: $BRANCH"Create a local branch before pushing
- Check out a named branch at the current SHA when a step must commit or push.
- Set the upstream explicitly on push.
git checkout -B "$BRANCH"
git push origin "HEAD:$BRANCH"How to prevent it
- Never derive the branch from git HEAD in CI; read the runner-provided ref variable, and create a named branch before any commit-and-push step.