How to fix fatal: bad revision 'HEAD~5' in Git
This error occurs when Git cannot find the specified commit reference during a revert operation. Common causes include shallow clones with limited history, syntax errors in the revision specifier, or referencing commits that don't exist in your local repository.
Quick fix
Fixes fatal: bad revision 'HEAD~5'
# Correct: using tilde (~) for ancestor commits
git revert HEAD~5
# Wrong: using hyphen (-) instead of tilde
git revert HEAD-5 # This causes "bad revision" error- Verify the revision syntax is correct
- Check how many commits exist in your repository
- Unshallow a shallow clone
- Fetch missing commits from remote
# Correct: using tilde (~) for ancestor commitsgit revert HEAD~5# Wrong: using hyphen (-) instead of tildegit revert HEAD-5 # This causes "bad revision" errorfatal: bad revision 'HEAD~5'
What this error means
When you run `git revert HEAD~5` or any revert command with a revision specifier, Git needs to look up the specific commit you're referencing. The "fatal: bad revision" error means Git cannot resolve the revision you provided to an actual commit in your repository. This typically happens in one of three scenarios: your repository doesn't have enough commit history (common in CI/CD pipelines that use shallow clones), you've made a syntax error in the revision specifier (like using `HEAD-5` instead of `HEAD~5`), or the commit simply doesn't exist in your local repository yet (it may exist on the remote but hasn't been fetched). Understanding the difference between `~` (tilde) and `^` (caret) is crucial: `HEAD~5` means "5 commits before HEAD following first parents" while `HEAD^5` means "the 5th parent of HEAD" (only relevant for merge commits). Using the wrong syntax or referencing commits beyond your history will trigger this error.
Typical symptoms
- git revert commands fail with 'fatal: bad revision' immediately
- Error occurs in CI/CD pipelines that use shallow clones
- Commands like git log HEAD~5 also fail with the same error
- The error mentions the specific revision you tried to use (e.g., HEAD~5, a commit hash)
- Works fine on your local machine but fails in automated environments
Common causes
- Repository is a shallow clone with insufficient commit history (most common in CI/CD)
- Syntax error: using HEAD-N instead of HEAD~N (hyphen vs tilde)
- The commit hash you specified doesn't exist in your local repository
- You haven't fetched the commit from the remote yet
- The repository has fewer commits than you're trying to reference
- Using a short commit hash that's ambiguous or doesn't match any commit
How to fix "fatal: bad revision 'HEAD~5'"
Make sure you're using the correct syntax for revision specifiers:
# Correct: using tilde (~) for ancestor commits
git revert HEAD~5
# Wrong: using hyphen (-) instead of tilde
git revert HEAD-5 # This causes "bad revision" errorThe tilde (~) followed by a number means "N commits back following first parents." Using a hyphen is a common mistake.
Count the commits in your repository to ensure you're not referencing beyond the available history:
# Count total commits on current branch
git rev-list --count HEAD
# View recent commit history
git log --oneline | head -10If you only have 3 commits and try git revert HEAD~5, you'll get a bad revision error because that commit doesn't exist.
If you're working with a shallow clone (common in CI/CD pipelines), fetch the full history:
# Convert shallow clone to full clone
git fetch --unshallow
# Alternative: fetch specific depth
git fetch --depth=100For GitHub Actions, modify your checkout step:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetches all history for all branchesFor GitLab CI, set in your .gitlab-ci.yml:
variables:
GIT_DEPTH: 0 # Full cloneIf the commit exists on the remote but not locally, fetch it:
# Fetch all branches and tags
git fetch --all
# Fetch a specific branch
git fetch origin main
# Verify the commit now exists
git cat-file -t <commit-hash> # Should output "commit"If you're trying to revert a commit from a different branch, make sure that branch is fetched first.
Short commit hashes can be ambiguous or mistyped. Use the full 40-character hash:
# Get the full hash of a commit
git rev-parse HEAD~5
# Then use the full hash for the revert
git revert <full-40-char-hash>You can also use git log to copy the exact hash you need:
git log --oneline -10
# Pick the commit hash from the outputBefore running the revert, confirm the revision is valid:
# Check if revision exists and show commit info
git show HEAD~5 --no-patch
# Or check if a specific hash exists
git cat-file -e <commit-hash> && echo "Commit exists"If these commands fail, the commit doesn't exist in your local repository and you need to fetch it first.
If you're trying to revert to a previous state but can't find the commit, use reflog:
# Show all recent HEAD movements
git reflog
# Find the commit you want and use its reference
git revert HEAD@{3} # Reverts the state from 3 operations agoThe reflog shows every position HEAD has been in, even for commits that might not be reachable through normal history.
Advanced notes
### Understanding Git Revision Syntax
Git supports multiple ways to reference commits:
| Syntax | Meaning |
|--------|---------|
| HEAD~N | N commits before HEAD (following first parent) |
| HEAD^N | Nth parent of HEAD (for merge commits) |
| @{N} | Nth reflog entry |
| branch@{upstream} | The upstream branch |
For most use cases, HEAD~N is what you want.
### Shallow Clones in CI/CD
Many CI/CD systems use shallow clones by default for performance:
- GitHub Actions: fetch-depth: 1 by default
- GitLab CI: GIT_DEPTH: 20 by default
- Bitbucket Pipelines: 50 commits by default
- Jenkins: Configurable per job
When you need to access older commits, you must either increase the fetch depth or unshallow the clone.
### git revert vs git reset
Remember that git revert creates a new commit that undoes changes, while git reset moves the branch pointer. If you just want to see the state of a file at a specific commit, use:
git show HEAD~5:path/to/file
# or checkout that version
git checkout HEAD~5 -- path/to/file### Handling Merge Commits
When reverting merge commits, you need to specify which parent to follow:
# Revert a merge commit, keeping changes from parent 1 (usually main branch)
git revert -m 1 <merge-commit-hash>Without -m, Git won't know which parent's changes to undo.
Frequently asked questions
- What does "fatal: bad revision 'HEAD~5'" mean?
- When you run git revert HEAD~5 or any revert command with a revision specifier, Git needs to look up the specific commit you're referencing. The "fatal: bad revision" error means Git cannot resolve the revision you provided to an actual commit in your repository. This typically happens in one of three scenarios: your repository doesn't have enough commit history (common in CI/CD pipelines that use shallow clones), you've made a syntax error in the revision specifier (like using HEAD-5 instead of HEAD~5), or the commit simply doesn't exist in your local repository yet (it may exist on the remote but hasn't been fetched).
- How do I fix "fatal: bad revision 'HEAD~5'"?
- This error occurs when Git cannot find the specified commit reference during a revert operation. Common causes include shallow clones with limited history, syntax errors in the revision specifier, or referencing commits that don't exist in your local repository.
- What causes "fatal: bad revision 'HEAD~5'"?
- Repository is a shallow clone with insufficient commit history (most common in CI/CD) Syntax error: using HEAD-N instead of HEAD~N (hyphen vs tilde) The commit hash you specified doesn't exist in your local repository
- Is the "fatal: bad revision 'HEAD~5'" error serious?
- It is a low-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐Git Official Documentation
- ๐ฌWhat does 'fatal: bad revision' mean? - Stack Overflow(Stack Overflow)
- ๐ฌ
- ๐ฌ
- ๐ฌfatal: bad revision 'HEAD-1' on revert - Stack Overflow(Stack Overflow)
- ๐
- ๐ฌ