What this warning means
Git prints "warning: refname 'X' is ambiguous" when the name you typed matches more than one reference (branch, tag, remote branch, etc.), or can be mistaken for a path. Examples:
- A branch and a tag named the same (e.g., release)
- A local branch and a remote-tracking branch with the same leaf name
- A tag named HEAD or a branch named HEAD
- A path named like a ref without using -- to separate path arguments
Quickstart: fix it fast
- List all refs that collide with the name:
# Replace <name> with the ambiguous name (e.g., release)
git for-each-ref --format='%(refname)' "refs/*/<name>"
Choose what you want to keep (branch, tag, or remote branch).
Disambiguate immediately in commands by using a fully-qualified ref:
# Examples
git show refs/heads/<name>
git show refs/tags/<name>
git show refs/remotes/origin/<name>
- Permanently resolve the conflict by renaming or deleting the unwanted ref:
# Delete a local tag or branch
git tag -d <name>
# or
git branch -D <name>
# Delete remote refs (be explicit)
git push origin :refs/tags/<name>
# or
git push origin :<name> # deletes remote branch <name>
Minimal working example
Reproduce and fix the warning in a scratch repo:
mkdir demo-ambig && cd demo-ambig
git init
printf 'v1\n' > version.txt
git add version.txt && git commit -m "init"
# Create both a branch and a tag named v1.0
git branch v1.0
git tag v1.0
# This is ambiguous: branch vs tag
git show v1.0 # prints: warning: refname 'v1.0' is ambiguous
# Disambiguate via fully-qualified names
git show refs/heads/v1.0
git show refs/tags/v1.0
# Resolve permanently by removing the tag (or renaming one of them)
git tag -d v1.0
# Now this is unambiguous
git show v1.0
Common causes and how to diagnose
- Same-name branch and tag
- Local branch and remote-tracking branch with the same name
- Accidental branch or tag named HEAD
- Name collision with a path (e.g., a directory called release and a ref release)
Identify exactly what collides:
# List all matching refs across namespaces
git for-each-ref --format='%(objectname:short) %(refname)' "refs/*/<name>"
# Or, explicitly check each namespace
git show-ref --heads | awk -v n="<name>" '$2 ~ "/" n "$"'
git show-ref --tags | awk -v n="<name>" '$2 ~ "/" n "$"'
git show-ref --remotes | awk -v n="<name>" '$2 ~ "/" n "$"'
If you suspect a path/ref ambiguity, try:
# Treat the name as a path
git log -- <name>
# Treat the name as a ref explicitly
git log refs/heads/<name>
How to fix (choose one)
- Keep both, but always qualify the name
Use fully-qualified refs in commands.
Handy disambiguators:
- refs/heads/<branch>
- refs/tags/<tag>
- refs/remotes/<remote>/<branch>
- <tag>^{commit} to peel a tag to its commit
- Rename one side
# Rename a branch
git branch -m <old> <new>
# Push new name and delete old on remote
git push origin <new>:<new>
git push origin :<old>
# Rename a tag (delete and recreate at same object)
git tag <new> <old>
git tag -d <old>
git push origin :refs/tags/<old>
git push origin refs/tags/<new>
- Delete the unwanted ref
# Local
git branch -D <name> # branch
git tag -d <name> # tag
# Remote
git push origin :<name> # branch
git push origin :refs/tags/<name> # tag
- Special case: HEAD is ambiguous If a branch or tag named HEAD exists, remove it:
git branch -D HEAD 2>/dev/null || true
git tag -d HEAD 2>/dev/null || true
# Ensure symbolic HEAD points to your main branch
git symbolic-ref HEAD refs/heads/main # adjust if needed
One-off disambiguation cheatsheet
- Show a branch: git show refs/heads/release
- Show a tag’s commit: git show release^{commit}
- Diff two tags: git diff refs/tags/v1.0 refs/tags/v1.1
- Checkout a branch when a path conflicts: git checkout refs/heads/release
- Treat a name as a path in history queries: git log -- release
Preventing future ambiguity
- Enforce naming policy: never reuse the same leaf name for branches and tags.
- Use prefixes for tags (e.g., v/, rel/) or for branches (e.g., feat/, fix/, release/).
- Add server-side hooks to reject pushes that create conflicting names.
- Avoid names like HEAD, FETCH_HEAD, ORIG_HEAD.
- On case-insensitive filesystems, avoid branch/tag names that differ only by case.
Pitfalls and safety
- Deleting the wrong ref: always inspect first with git for-each-ref and git show <ref>.
- Recoverability: branches have reflogs; tags do not. Before deleting a tag, record its object id.
- Remote deletions require explicit refspecs; double-check you are deleting the intended remote ref.
- CI/CD may pin to tag or branch names; coordinate renames to avoid pipeline breakage.
Performance notes
- Enumerate specific namespaces when possible (heads/tags/remotes) to avoid scanning all refs.
- git for-each-ref and git rev-parse operate on refs and packed-refs; they are efficient and do not traverse history.
- Avoid grepping full output of git show-ref in very large repos; filter by namespace or exact suffix.
- Prefer fully-qualified refs in automation to skip ambiguity checks entirely.
FAQ
Q: Can I silence the warning without fixing the names? A: You can disable it via: git config advice.refnameAmbiguity false. This only hides the warning; ambiguity remains and can still cause mistakes.
Q: Which ref does Git pick when ambiguous? A: Git searches namespaces in a defined order, but you should not rely on it. Always qualify the ref to be explicit.
Q: How do I check what a ref points to? A: Use git rev-parse <ref> or git show <ref> to print the object and its commit message.
Q: How do I prevent this in a shared repo? A: Enforce policies in pre-receive/update hooks to block pushes that introduce a ref with a conflicting leaf name.