This error occurs when Git cannot resolve a revision specifier (branch name, tag, or commit hash) that you provided. The reference either doesn't exist, hasn't been fetched, or was typed incorrectly.
When you run a Git command that requires a revision (like `git log`, `git diff`, `git checkout`, or `git revert`), Git attempts to resolve the argument you provided into a specific commit SHA. A "revision" in Git terminology can be a branch name, tag name, commit hash, or special reference like HEAD. The "fatal: bad revision" error means Git could not find any object matching what you specified. This typically happens when you reference a branch that doesn't exist locally, use a commit hash that isn't in your repository, or make a typo in a branch or tag name. Git doesn't distinguish between "doesn't exist" and "can't be resolved to a commit" in this error message. This error is particularly common in CI/CD environments where shallow clones are used, after force-pushes that rewrite history, or when working with remote branches that haven't been fetched yet.
First, check if the branch, tag, or commit actually exists in your local repository:
# List all local branches
git branch -a
# List all tags
git tag -l
# Check if a specific commit exists
git cat-file -t <commit-hash>If the reference is a remote branch (like origin/feature-branch), verify it appears in the list of remote-tracking branches.
If the branch or tag exists on the remote but not locally, fetch it:
# Fetch all branches and tags from all remotes
git fetch --all
# Fetch with tags explicitly
git fetch --all --tags
# Fetch a specific branch
git fetch origin feature-branchAfter fetching, retry your command. The reference should now be available locally.
The error often occurs due to simple typos. Verify your reference name:
# Search for similar branch names
git branch -a | grep -i "partial-name"
# Search for similar tags
git tag -l | grep -i "partial-name"
# If using a commit hash, verify it's complete (at least 7 characters)
git rev-parse --verify <commit-hash>Common mistakes include:
- Using origin instead of origin/main
- Confusing branch names with tag names
- Missing characters in commit hashes
If you're working with a shallow clone (common in CI/CD), you may not have the full commit history:
# Check if repository is shallow
git rev-parse --is-shallow-repository
# Convert shallow clone to full clone
git fetch --unshallow
# Or fetch more history incrementally
git fetch --deepen=100For CI/CD configurations, increase the fetch depth:
GitHub Actions:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full historyGitLab CI:
variables:
GIT_DEPTH: 0In a new repository with no commits, HEAD doesn't exist yet:
# Check if HEAD exists
git rev-parse HEAD 2>/dev/null || echo "No commits yet"
# For new repositories, create an initial commit
git commit --allow-empty -m "Initial commit"This is normal for freshly initialized repositories before the first commit.
When comparing with remote branches, use the full reference:
# Wrong - 'origin' is a remote, not a revision
git diff origin
# Correct - use the full remote/branch reference
git diff origin/main
# Also correct - use HEAD on remote
git diff origin/HEADTo see what origin/HEAD points to:
git symbolic-ref refs/remotes/origin/HEADIf a commit was lost due to a force-push, you may be able to recover it:
# Check the reflog for lost commits
git reflog
# Search for the commit in reflog
git reflog | grep "commit message fragment"
# Once found, you can checkout or cherry-pick it
git checkout <recovered-hash>Note: Reflog entries expire after 90 days by default. For remote repositories, you may need to contact your repository host for assistance.
### Git Revision Syntax
Git supports many ways to specify revisions beyond simple branch names:
- HEAD~2: Two commits before HEAD (first parent only)
- HEAD^2: Second parent of HEAD (useful for merge commits)
- @{yesterday}: Where HEAD was yesterday
- main@{upstream}: The upstream of main branch
- :/fix bug: Most recent commit matching "fix bug" in message
All of these can produce "bad revision" errors if the referenced commit doesn't exist.
### Detached HEAD State
When in detached HEAD state, some revision shortcuts may not work as expected:
# Check if in detached HEAD state
git symbolic-ref HEAD 2>/dev/null || echo "Detached HEAD"### Jenkins and CI/CD Environments
Jenkins and similar tools sometimes check out specific commits rather than branches. Use explicit ref specs:
# Instead of branch name, use full ref
git checkout refs/remotes/origin/main
# Or use commit SHA directly
git checkout ${GIT_COMMIT}### Git Worktrees
If using git worktrees, ensure you're in the correct worktree:
# List all worktrees
git worktree list
# Each worktree may have different branches checked outwarning: BOM detected in file, this may cause issues
UTF-8 Byte Order Mark (BOM) detected in file
fatal: Server does not support --shallow-exclude
Server does not support --shallow-exclude
warning: filtering out blobs larger than limit
Git partial clone filtering large blobs warning
fatal: Server does not support --shallow-since
Server does not support --shallow-since in Git
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server