KhueApps
Home/DevOps/Fix 'fatal: You are not currently on a branch' (detached HEAD)

Fix 'fatal: You are not currently on a branch' (detached HEAD)

Last updated: October 07, 2025

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
  • 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
  • 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

  1. Confirm detached state

    • git status
    • You will see: HEAD detached at <sha or tag>
  2. 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>
  3. 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>
  4. 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

ScenarioSymptomFix
Checked out a commitgit status shows HEAD detachedgit switch -c feature/from-sha
Checked out a tagCannot commit to taggit switch -c hotfix/from-tag vX.Y.Z
Need to get back to mainMerge or pull failsgit switch main
Rebase left you detachedStuck mid-rebasegit rebase --abort or --continue
CI on a SHApull/merge failscreate 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

Series: Git

DevOps