KhueApps
Home/DevOps/Fix "fatal: A branch named … already exists" in Git

Fix "fatal: A branch named … already exists" in Git

Last updated: October 07, 2025

What this error means

Git shows "fatal: A branch named '<name>' already exists" when you try to create a branch with a name that already exists in your local repository. This happens with commands like:

  • git branch <name>
  • git checkout -b <name>
  • git switch -c <name>

It does not indicate a remote problem by itself; it’s a local name collision under refs/heads/<name>.

Quickstart (TL;DR)

  • If you meant to switch to the branch:
    • git switch <name>
    • or: git checkout <name>
  • If you want to recreate/reset the branch to a start point:
    • git switch -C <name> <start-point>
    • or: git checkout -B <name> <start-point>
  • If you need a different name:
    • git switch -c <new-name>
  • If the local branch is stale and you want to delete it:
    • git branch -d <name> # safe delete (merged only)
    • git branch -D <name> # force delete (data loss risk)
  • If a remote branch exists and you want a local tracking branch:
    • git switch -c <name> --track origin/<name>
    • or: git switch -C <name> origin/<name>

Minimal working example

Reproduce the error and apply common fixes in a scratch repo.

# 1) Create a repo and a branch
mkdir demo && cd demo
git init -q
echo one > file.txt
git add file.txt
git commit -qm "init"

git switch -c feature/login

# 2) Try to create it again (triggers the error)
# Any of these will fail because feature/login already exists
set -e
{
  git branch feature/login
} || true
{
  git checkout -b feature/login
} || true
{
  git switch -c feature/login
} || true

# 3) Fix A: You meant to use it, not create it
git switch feature/login

# 4) Fix B: Reset it to main (danger: rewrites branch tip)
git switch -C feature/login main

# 5) Fix C: Use a different name instead
git switch -c feature/login-v2

Solutions by intent

  1. I only wanted to use the existing branch
  • git switch <name>
  • Legacy: git checkout <name>
  1. I need a branch at a specific commit, regardless of current branch tip
  • Reset/create in one step:
    • git switch -C <name> <start-point>
    • or: git checkout -B <name> <start-point>
  • Notes:
    • -C and -B overwrite the existing branch ref to point at <start-point>.
    • Use with care; you are rewriting the branch tip.
  1. I need a new branch with a similar name
  • Choose another name:
    • git switch -c <new-name>
  • Consider a naming convention (e.g., feature/login-2 or feature/login-refactor).
  1. I want a local branch that tracks an existing remote branch
  • Create and track:
    • git switch -c <name> --track origin/<name>
    • or replace both with one idempotent command:
      • git switch -C <name> origin/<name>
  • Afterward, pushing works without extra args: git push
  1. I want to delete the existing local branch, then recreate it
  • Safe delete (only if fully merged):
    • git branch -d <name>
  • Force delete (even if unmerged; data loss risk):
    • git branch -D <name>
  • Recreate:
    • git switch -c <name> <start-point>
  1. I need to rename the existing branch
  • If you’re on a different branch:
    • git branch -m <old> <new>
  • If you’re on the branch:
    • git branch -m <new>
  • Push rename to remote (if needed):
    • git push origin -u <new>
    • git push origin --delete <old>

CI/CD and automation tips (DevOps)

  • Prefer idempotent commands in pipelines:
    • git fetch --prune origin
    • git switch -C <name> origin/<name> This works whether the local branch exists or not and aligns it with the remote tip.
  • For ephemeral runners, avoid local caching issues by always fetching the exact refs you need:
    • git fetch --no-tags --depth=1 origin <refspec>
  • If your CI uses a detached HEAD, explicitly create/reset the target branch with -C.

Numbered steps: diagnose and resolve

  1. List branches and confirm the collision
    • git branch --list
    • git show-ref --heads | grep "refs/heads/<name>"
  2. Decide your intent (switch, reset, rename, delete, or track remote).
  3. Apply the matching fix:
    • Switch: git switch <name>
    • Reset: git switch -C <name> <start-point>
    • Rename: git branch -m <old> <new>
    • Delete: git branch -d <name> (or -D)
    • Track remote: git switch -C <name> origin/<name>
  4. If a remote is involved, sync it
    • git push -u origin <name>
    • If you renamed: git push origin --delete <old>
  5. Clean up stale refs
    • git fetch --prune

Pitfalls and how to avoid them

  • Data loss with -D, -C, and -B:
    • These can move or delete refs even if commits are unmerged. Consider creating a safety tag first: git tag backup/<name> <name>.
  • Branch name vs tag name collisions:
    • If a tag shares the name, commands may be ambiguous. Prefer fully qualified refs: refs/heads/<name> or refs/tags/<name>.
  • Case sensitivity:
    • Git is case-sensitive; some filesystems are not. feature/Login and feature/login can collide on macOS/Windows. Normalize names.
  • Protected branches on remotes:
    • You may not be able to delete or force-push protected branches. Adjust branch protection or use a different branch.
  • Detached HEAD confusion:
    • Creating branches from a detached HEAD works, but remember to switch to them before committing.

Performance notes

  • Listing branches in very large repos:
    • Use filters: git branch --list 'feature/*'
    • For scripts, prefer plumbing: git for-each-ref --format='%(refname:short)' refs/heads
  • Reduce network overhead in CI:
    • Fetch only needed refs and prune: git fetch --prune --depth=1 origin <branch>
  • Idempotent reset avoids extra steps:
    • git switch -C <name> <start-point> performs create-or-reset in one command.

FAQ (tiny)

  • Q: I ran git checkout -b <name> and got the error. How do I just use it?
    • A: Run git switch <name> (or git checkout <name>).
  • Q: How do I create or reset the branch in one go?
    • A: Use git switch -C <name> <start-point> or git checkout -B <name> <start-point>.
  • Q: The branch exists remotely but not locally. What now?
    • A: git switch -c <name> --track origin/<name> or git switch -C <name> origin/<name>.
  • Q: Can I safely delete the local branch?
    • A: Use git branch -d <name> to delete only if merged. Use -D only if you’re sure.
  • Q: My CI keeps failing with this error. How to make it idempotent?
    • A: Fetch with prune, then git switch -C <name> origin/<name>.

Series: Git

DevOps