Fix: git fatal: A branch named 'x' already exists
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 failedGit 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/loginalready 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, sofeature/logincannot exist iffeatureis 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/loginReset it to a different commit (dangerous — rewrites history):
git branch -f feature/login main
# Moves feature/login to point at the same commit as mainDelete 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 # RecreateWarning:
git branch -Ddeletes 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 -rCreate 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/loginThis 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 originThis 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 mainIf 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/loginFix 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/login — feature 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 worksOr rename the existing branch:
git branch -m feature feature-main # Rename 'feature' to 'feature-main'
git branch feature/login # Now no conflictPro Tip: Use a consistent naming convention for branches. Common patterns:
feature/description,fix/description,chore/description. Avoid creating bare category names likefeatureorfixas 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-nameIf a branch with new-name already exists, use -M (force):
git branch -M old-name new-nameAfter 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-nameFor 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/loginAfter manual cleanup, run git gc to garbage-collect loose objects:
git gc --prune=nowFor 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/loginStill 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.lockCheck 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.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Undo git reset --hard and Recover Lost Commits
How to undo git reset --hard and recover lost commits using git reflog — step-by-step recovery for accidentally reset branches, lost work, and dropped stashes.
Fix: .gitignore Not Working (Files Still Being Tracked)
How to fix .gitignore not working — files still showing in git status after being added to .gitignore, caused by already-tracked files, wrong syntax, nested gitignore rules, and cache issues.
Fix: Git Keeps Asking for Username and Password
How to fix Git repeatedly prompting for credentials — credential helper not configured, HTTPS vs SSH, expired tokens, macOS keychain issues, and setting up a Personal Access Token.
Fix: Git submodule update failed / fatal: not a git repository
Resolve Git submodule update and init failures including 'fatal: not a git repository', path conflicts, URL mismatches, shallow clone issues, and CI/CD checkout problems.