This Git error occurs when Git cannot determine whether an argument is a branch name, commit reference, or file path. The specified reference doesn't exist locally, often because it was never fetched, was deleted, is misspelled, or the repository is a shallow clone. Fix it by verifying the branch exists and fetching from the remote.
The "ambiguous argument: unknown revision or path not in the working tree" error indicates that Git cannot interpret the argument you provided. When you run commands like `git diff branch-name`, `git log branch-name`, or `git show branch-name`, Git needs to determine whether the argument refers to: 1. **A revision** (branch name, tag, commit SHA, or other Git reference) 2. **A path** (file or directory in your working tree) When Git cannot find the argument as either a valid revision or an existing path, it throws this error. The message "unknown revision or path not in the working tree" means Git looked for both possibilities and found neither. This error commonly occurs when: - You reference a branch that doesn't exist locally - The repository was cloned with `--depth` (shallow clone) limiting available references - You're in a fresh repository with no commits yet - The branch was deleted or renamed - You're using the wrong character (en-dash vs hyphen, often from copy-pasting)
First, check if the branch, tag, or commit you're referencing actually exists:
# List all local branches
git branch
# List all remote tracking branches
git branch -r
# List all branches (local and remote)
git branch -a
# List all tags
git tag
# Search for a specific branch pattern
git branch -a | grep -i "branch-name"
# Check if a specific ref exists
git rev-parse --verify branch-nameIf the reference isn't listed, it either doesn't exist or hasn't been fetched.
If the branch exists on the remote but not locally, fetch it:
# Fetch all branches from all remotes
git fetch --all
# Fetch from a specific remote
git fetch origin
# Verify the branch is now available
git branch -r | grep branch-nameAfter fetching, you can reference the branch as origin/branch-name or create a local tracking branch:
# Create local branch tracking the remote
git checkout branch-name
# Or explicitly:
git checkout -b branch-name origin/branch-nameIf your repository was cloned with --depth (common in CI/CD), you may not have access to all references:
# Check if repo is shallow
git rev-parse --is-shallow-repository
# Returns "true" if shallow
# Convert to a full clone
git fetch --unshallow
# Or fetch specific branch with depth
git fetch --depth=100 origin branch-nameFor CI/CD environments, configure full fetching:
GitHub Actions:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all historyGitLab CI:
variables:
GIT_DEPTH: 0If the repository was cloned with --single-branch, only one branch is tracked:
# Check current fetch configuration
git config --get remote.origin.fetch
# If it shows a single branch like:
# +refs/heads/main:refs/remotes/origin/main
# Update to fetch all branches
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
# Now fetch all branches
git fetch origin
# Verify branches are available
git branch -aIn a fresh repository before the first commit, references like HEAD don't exist:
# Check if any commits exist
git rev-parse HEAD
# If this fails, you have no commits
# Create an initial commit
git commit --allow-empty -m "Initial commit"
# Now HEAD and other references work
git log HEADFor pre-commit hooks that fail on new repos, use --no-verify for the initial commit or handle the case in your hook script.
If the error references 'origin', the remote HEAD may not be set:
# Check if origin/HEAD exists
git symbolic-ref refs/remotes/origin/HEAD
# Set it automatically based on remote
git remote set-head origin --auto
# Or set it manually
git remote set-head origin mainThis is particularly important when scripts reference origin without specifying a branch.
When copying commands from web pages or documentation, invisible characters or wrong dashes may be introduced:
# The problem: en-dash (–) vs hyphen (-)
# These look similar but are different characters:
# Wrong: git reset –-hard (en-dash from web page)
# Right: git reset --hard (hyphen)
# Check for hidden characters in your command
echo "git reset --hard" | cat -A
# Should show only ASCII characters
# Retype the command manually instead of pastingThis is a common issue with:
- --hard becoming –-hard
- Branch names with hyphens
- Options like -- separator
If Git is confused between a path and a revision, use -- to explicitly separate them:
# Tell Git everything after -- is a path
git log -- path/to/file
# Tell Git everything before -- is a revision
git show branch-name -- file.txt
# Explicit revision
git diff HEAD -- .
# Compare file between branches
git diff main:path/to/file branch:path/to/fileThe -- separator removes ambiguity when a file and branch have similar names.
### How Git Resolves References
When you provide an argument to Git, it tries to resolve it in this order:
1. Exact ref match: .git/refs/heads/name, .git/refs/tags/name
2. Symbolic ref: .git/HEAD, .git/refs/remotes/origin/HEAD
3. Short SHA: Partial commit hash (at least 4 characters)
4. Reflog reference: HEAD@{1}, branch@{yesterday}
5. Ancestor notation: HEAD~3, main^2
6. File path: Path in working tree or specified revision
If none match, you get the "ambiguous argument" error.
### Debugging Reference Resolution
Use git rev-parse to understand how Git interprets references:
# Check what a reference resolves to
git rev-parse main
git rev-parse HEAD~3
git rev-parse origin/feature
# Check if something is a valid ref
git rev-parse --verify branch-name 2>/dev/null && echo "Valid" || echo "Invalid"
# See all refs
git for-each-ref### Common CI/CD Patterns
Many CI systems use optimized clones that cause this error. Common fixes:
GitHub Actions with checkout:
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: |
git fetch origin main:refs/remotes/origin/main
git diff origin/main...HEADFetching specific refs in CI:
# Fetch specific branch for comparison
git fetch origin main:refs/remotes/origin/main
# Fetch PR base for diff
git fetch origin +refs/pull/*/head:refs/remotes/origin/pr/*### HEAD Issues in New Repositories
In a new repository, .git/HEAD points to refs/heads/main (or master), but that ref doesn't exist yet:
# Check what HEAD points to
cat .git/HEAD
# ref: refs/heads/main
# But the ref doesn't exist
cat .git/refs/heads/main
# cat: No such file or directoryAfter your first commit, the ref is created and HEAD works normally.
### Reflog-Based Recovery
If a branch was recently deleted but you need to reference it:
# Find in reflog
git reflog show branch-name
# Or search all reflogs
git reflog | grep branch-name
# Recreate branch from reflog
git branch branch-name HEAD@{1}### Stale Remote References
Remote tracking branches can become stale:
# List stale remote branches
git remote prune origin --dry-run
# Remove stale references
git remote prune origin
# Or during fetch
git fetch --pruneConfigure automatic pruning:
git config --global fetch.prune truekex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git