Skip to content

Fix: git fatal: A branch named 'x' already exists

FixDevs ·

Quick Answer

How to fix 'git fatal: A branch named already exists' when creating or renaming branches — including local conflicts, remote tracking branches, and worktree issues.

The Error

You try to create or rename a Git branch and get:

fatal: A branch named 'feature/login' already exists.

Or when switching with branch creation:

fatal: A branch named 'main' already exists.

Or when renaming:

error: refname refs/heads/feature/login not found
fatal: Branch rename failed

Git refuses to create the branch because a branch with that name already exists — locally, as a remote-tracking reference, or in a linked worktree.

Why This Happens

Git stores branches as references (refs) in .git/refs/heads/. When you run git branch feature/login, Git tries to create a new ref at that path. If one already exists, it fails. Common causes:

  • You already created this branch in a previous session and forgot.
  • A remote-tracking branch exists with the same name (e.g., origin/feature/login already fetched).
  • A Git worktree has this branch checked out — a branch cannot be checked out in two worktrees simultaneously.
  • A partial branch name conflict — Git uses / as a directory separator in refs, so feature/login cannot exist if feature is already a file (not a directory) in .git/refs/heads/.
  • Corrupted or leftover refs from a failed operation.

Fix 1: Check If the Branch Already Exists

Before creating, verify what branches exist:

# List all local branches
git branch

# List all remote-tracking branches
git branch -r

# List all branches (local + remote)
git branch -a

# Search for a specific branch name
git branch -a | grep "feature/login"

If the branch already exists locally, you have three options:

Switch to it:

git checkout feature/login
# or
git switch feature/login

Reset it to a different commit (dangerous — rewrites history):

git branch -f feature/login main
# Moves feature/login to point at the same commit as main

Delete it and recreate:

git branch -d feature/login   # Safe delete (fails if unmerged)
git branch -D feature/login   # Force delete (even if unmerged)
git branch feature/login      # Recreate

Warning: git branch -D deletes the branch and discards any commits that exist only on that branch. Make sure you do not need those commits, or cherry-pick them to another branch first.

Fix 2: Create the Branch from a Different Starting Point

If you want to reset an existing branch to start fresh from a different commit:

# Reset the branch to point to main's current commit
git branch -f feature/login main

# Or to a specific commit
git branch -f feature/login abc1234

# Then switch to it
git switch feature/login

-f (force) moves the branch pointer even if it already exists. This does not delete any commits — it just moves the label.

Alternatively, use checkout -B:

git checkout -B feature/login main

-B (uppercase) creates the branch if it does not exist, or resets it to the given start point if it does. It also switches to the branch in one command.

Fix 3: Fix Remote-Tracking Branch Conflicts

When you fetch from a remote, Git creates remote-tracking branches like origin/feature/login. These do not conflict with local branches by default — but the error can appear if you try to create a local branch with the exact same full ref path as a remote-tracking branch, or if the remote branch was set up in a way that creates a naming conflict.

Check remote branches:

git fetch --all
git branch -r

Create a local branch that tracks the remote branch:

git checkout -b feature/login origin/feature/login
# or
git switch -c feature/login --track origin/feature/login

This creates a local feature/login that tracks origin/feature/login. If a local branch with that name already exists, use git branch -f to reset it first.

If the remote branch no longer exists but the tracking reference persists:

# Prune stale remote-tracking references
git fetch --prune
git remote prune origin

This removes remote-tracking branches that no longer exist on the remote.

Fix 4: Fix Worktree Branch Conflicts

If you use git worktree, a branch can only be checked out in one worktree at a time. Trying to check it out in a second worktree fails:

git worktree add ../new-worktree feature/login
# fatal: 'feature/login' is already checked out at '/path/to/original-worktree'

Fix — list and manage worktrees:

# See all worktrees and their branches
git worktree list

# Remove a worktree you no longer need
git worktree remove ../old-worktree

# Or create a new worktree with a new branch
git worktree add ../new-worktree -b feature/login-v2 main

If a worktree was deleted without git worktree remove (e.g., you deleted the folder manually), the ref may be locked:

# Clean up stale worktree references
git worktree prune

# Then try the branch operation again
git worktree add ../new-worktree feature/login

Fix 5: Fix Branch Naming Conflicts with Slashes

Git uses / in branch names as a path separator in the refs filesystem. This means you cannot have both a branch named feature and a branch named feature/loginfeature would need to be both a file and a directory in .git/refs/heads/.

Broken — naming conflict:

git branch feature          # Creates .git/refs/heads/feature (a file)
git branch feature/login    # Tries to create .git/refs/heads/feature/login
# fatal: cannot lock ref 'refs/heads/feature/login':
# 'refs/heads/feature' exists; cannot create 'refs/heads/feature/login'

Fix — delete the conflicting branch:

git branch -d feature        # Delete the 'feature' branch
git branch feature/login     # Now this works

Or rename the existing branch:

git branch -m feature feature-main  # Rename 'feature' to 'feature-main'
git branch feature/login            # Now no conflict

Pro Tip: Use a consistent naming convention for branches. Common patterns: feature/description, fix/description, chore/description. Avoid creating bare category names like feature or fix as standalone branches — they will conflict with all branches in that category.

Fix 6: Rename a Branch

To rename a local branch:

# Rename the current branch
git branch -m new-name

# Rename a specific branch (not currently checked out)
git branch -m old-name new-name

If a branch with new-name already exists, use -M (force):

git branch -M old-name new-name

After renaming, update the remote:

# Push the new name
git push origin new-name

# Delete the old name from remote
git push origin --delete old-name

# Update the tracking reference
git branch --set-upstream-to=origin/new-name new-name

For the main/master rename specifically, see GitHub’s branch rename guide — it involves additional steps for open pull requests and branch protection rules.

Fix 7: Clean Up Leftover or Corrupted Refs

After failed operations, corrupted refs can leave branches in a broken state:

# Check for broken refs
git fsck --full

# View the raw ref to see what it points to
cat .git/refs/heads/feature/login

# Manually delete a broken ref file
rm .git/refs/heads/feature/login

# Or use git update-ref to delete it cleanly
git update-ref -d refs/heads/feature/login

After manual cleanup, run git gc to garbage-collect loose objects:

git gc --prune=now

For packed refs (branches stored in .git/packed-refs instead of individual files):

cat .git/packed-refs | grep feature/login
# If it appears there, edit the file manually to remove that line
# Or use git update-ref:
git update-ref -d refs/heads/feature/login

Still Not Working?

Check for case sensitivity issues. On macOS and Windows (case-insensitive filesystems), Feature/Login and feature/login are the same file. Git may warn about this or fail silently. Use all-lowercase branch names to avoid this entirely.

Check for locked ref files. If a previous Git operation was interrupted, it may have left a .lock file:

ls .git/refs/heads/feature/
# feature.lock  ← This is leftover from a failed operation

rm .git/refs/heads/feature/login.lock

Check your Git version. Very old versions of Git have bugs with ref management. Run git --version and update if you are below 2.30.

For errors pushing branches after creating them, see Fix: git push rejected (non-fast-forward) and Fix: git error failed to push some refs.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles