Overview
Git prints:
- fatal: ambiguous argument '<thing>': unknown revision or path not in the working tree.
Meaning: Git couldn’t resolve the token you passed (e.g., feature, v1.2, src/app.js) as either a valid revision (commit, tag, branch) or a pathspec (file/dir) at the point you used it.
Typical causes:
- Typo or missing branch/tag/commit (not fetched yet or deleted).
- Passing a path where Git expects a revision without using -- to separate paths.
- Using object:path (colon) syntax accidentally, or a Windows path with a colon.
- Ref and path sharing the same name without disambiguation.
- Working outside the repo or in a submodule you didn’t init/fetch.
Quickstart (most common fixes)
- If it’s a file or directory, add -- before it:
- git log -- src/app.js
- If it’s a branch or tag, verify and fetch:
- git fetch --all --prune --tags
- git switch feature/login # or: git checkout feature/login
- If you used object:path (rev:path), ensure path exists in that rev or remove the colon.
- On Windows, avoid C:\style in Git args; prefer C:/ or add -- before paths.
Minimal working example
This reproduces the error and shows two fixes.
# 1) Setup
mkdir demo && cd demo
git init
printf 'hello\n' > README.md
git add README.md && git commit -m "init"
# 2) Error: ask Git to show a non-existent revision 'feature'
# Git tries to treat 'feature' as a revision and fails.
git show feature || true
# fatal: ambiguous argument 'feature': unknown revision or path not in the working tree.
# Fix A: you meant the file README.md; separate path with --
git show HEAD -- README.md # works
# Fix B: you meant a remote branch; fetch it then reference it
# Simulate: add a remote and branch name; in real life this is your real origin
git remote add origin https://example.org/repo.git
# Now fetch to get refs locally
git fetch origin feature # if it exists on remote
# Now it resolves
git log origin/feature
What Git is trying to tell you
- Ambiguous argument happens when a token can’t be resolved as either:
- a revision: commit SHA, ref name (refs/heads/branch, refs/tags/v1.2), or
- a path: file/dir in the working tree or in a given rev.
- Many Git commands parse arguments as: [<revisions>] -- [<paths>]. When you omit --, Git may try to interpret a path as a revision.
Diagnostic checklist
- Are you in the right repo?
- git rev-parse --is-inside-work-tree
- Is it a revision or a path?
- If path, rerun with -- before it.
- If revision, verify it exists:
- git rev-parse --verify my-branch
- git show-ref --verify refs/tags/v1.2
- If it’s remote-only, fetch it:
- git fetch origin my-branch
- git fetch --tags
- If you used a colon, did you intend rev:path?
- Ensure the path exists in that rev: git ls-tree --name-only HEAD | grep <path>
- Name collision?
- If a file and branch share a name, disambiguate:
- refs/heads/foo vs -- foo
Common scenarios and fixes
You meant a file, not a ref
- Symptom: git diff src/app.js errors.
- Fix: git diff -- src/app.js
The branch/tag doesn’t exist locally
- Fix: git fetch origin feature/login && git switch feature/login
- Verify: git branch -r | grep feature/login
Tags missing
- Fix: git fetch --tags
- Verify: git tag --list | grep v1
Using commit ranges with typos
- Example: git log feature..HEAD fails if feature is missing.
- Fix: ensure feature exists or use origin/feature after fetching.
rev:path mistakes
- Example: git show HEAD:src/app.js fails if src/app.js didn’t exist in HEAD.
- Fix: check the path in that tree: git ls-tree -r --name-only HEAD | grep app.js
Path/ref name collision
- Example: file named docs and branch named docs.
- Disambiguate:
- Explicit ref: git show refs/heads/docs
- Explicit path: git show HEAD -- docs
Windows paths with colon
- Example: git add C:\proj\file.txt inside a repo arg list.
- Fix: use forward slashes or add --: git add -- C:/proj/file.txt
Submodules or worktrees
- Ensure submodules are initialized and fetched:
- git submodule update --init --recursive
- In worktrees, verify you’re on the correct worktree and branch exists:
- git worktree list
- Ensure submodules are initialized and fetched:
Numbered steps to resolve
- Identify intent: Is the token a revision or a path?
- If a path, rerun with -- and correct the path.
- If a revision, verify locally with git rev-parse --verify <rev>.
- If missing, fetch it: git fetch origin <rev> or git fetch --tags.
- If still unresolved, fully qualify:
- Branch: refs/heads/<name>
- Tag: refs/tags/<name>
- Remote-tracking: refs/remotes/origin/<name>
- Address collisions by explicit namespaces or -- before paths.
- Re-run your original command.
Pitfalls
- Relying on implicit path parsing without --; works until a name collision occurs.
- Using stale remote refs; always fetch before referencing new branches.
- Shell globbing expanding arguments unexpectedly; quote paths with spaces or special chars.
- Assuming a file existed in older commits when using rev:path. Check with git ls-tree.
- Case sensitivity differences across OS can hide missing paths/refs.
Performance notes
- Prefer targeted fetches over fetch --all:
- git fetch origin feature/login instead of fetching everything.
- Use git rev-parse and git show-ref for constant-time existence checks before expensive logs.
- Fully qualify refs (refs/heads/…) in automation to avoid ambiguous lookups.
- Avoid wide pathspec globs in deep repos; specify directories or files precisely.
- In CI, fetch shallow when you only need a ref tip:
- git fetch --depth=1 origin feature/login
Tiny FAQ
Why does adding -- fix it?
- It tells Git: everything after -- is a path, not a revision.
I fetched, but the branch still doesn’t resolve.
- Check the remote name and branch spelling; confirm with git ls-remote --heads origin.
How do I check if a tag exists without fetching all tags?
- git ls-remote --tags origin 'v1.*'
Can I force Git to prefer paths over refs?
- No global switch; use -- or qualify refs explicitly.
What about commit SHAs?
- Abbreviations must be unique locally. If not found, fetch or use a longer prefix or the full SHA.