How to fix fatal: bad revision 'HEAD~10' in Git

GitBEGINNERLOWUpdated Dec 6, 2025ยท 154 views

This error occurs when Git cannot find the specified commit reference, usually because the repository has fewer commits than requested or you're working with a shallow clone that lacks sufficient history.

Quick fix

Fixes fatal: bad revision 'HEAD~10'

git rev-list --count HEAD
  1. Check how many commits exist
  2. Check if you're in a shallow clone
  3. Fetch more history (for shallow clones)
  4. Fix CI/CD configuration (GitHub Actions)
git โ€” error
git rev-list --count HEAD
fatal: bad revision 'HEAD~10'

What this error means

The "fatal: bad revision 'HEAD~10'" error means Git cannot locate the commit you're trying to reference. HEAD~10 refers to the commit that is 10 commits before your current HEAD position. This error typically occurs in these scenarios: 1. **Fewer commits than requested**: If your repository only has 5 commits but you reference HEAD~10, Git cannot find a commit that far back in history. 2. **Shallow clone**: CI/CD systems like GitHub Actions, GitLab CI, and Jenkins often perform shallow clones (--depth=1) by default to save bandwidth and time. This means only recent commits are available locally. 3. **Empty repository**: In a freshly initialized repository with no commits, HEAD doesn't exist yet, so any reference to HEAD~N will fail. 4. **Corrupted or incomplete history**: If commits are missing from your local repository due to corruption or incomplete fetch operations, Git cannot resolve the reference. This is an extremely common issue in CI/CD pipelines where shallow cloning is the default behavior for performance optimization.

Typical symptoms

  • Running 'git reset HEAD~10' fails with 'bad revision' error
  • CI/CD pipeline fails when trying to access commit history
  • 'git log HEAD~10' or 'git diff HEAD~10' commands fail
  • Git bisect operations fail due to missing history
  • Scripts that compare commits fail in automated environments
  • 'git rebase -i HEAD~N' fails with bad revision error
  • GitHub Actions or GitLab CI jobs fail on git history commands

Common causes

  1. Repository has fewer commits than the number specified in HEAD~N reference
  2. Working in a shallow clone where only recent commits were fetched (common in CI/CD)
  3. Empty repository with no commits yet
  4. Missing commits due to incomplete fetch or clone operations
  5. Corrupted .git directory with missing commit objects
  6. Detached HEAD state pointing to an invalid reference
  7. Clone depth setting too low for the operation being performed

How to fix "fatal: bad revision 'HEAD~10'"

1Check how many commits exist

First, verify the total number of commits in your repository:

bash
git rev-list --count HEAD

If this returns a number smaller than the N in HEAD~N you're trying to reference, that's the cause of the error. For example, if you have 5 commits but try to reference HEAD~10, it will fail.

2Check if you're in a shallow clone

Determine if your repository is a shallow clone:

bash
git rev-parse --is-shallow-repository

If this returns "true", your repository has truncated history. You can also check:

bash
cat .git/shallow

If this file exists, you're in a shallow clone with limited history.

3Fetch more history (for shallow clones)

If you're in a shallow clone, fetch more history:

bash
# Fetch all history (removes shallow status)
git fetch --unshallow

# Or fetch a specific amount of additional history
git fetch --deepen=50

# Or fetch to a specific depth
git fetch --depth=100

After fetching more history, your HEAD~N references should work.

4Fix CI/CD configuration (GitHub Actions)

For GitHub Actions, configure the checkout action to fetch more history:

yaml
- name: Checkout code
  uses: actions/checkout@v4
  with:
    fetch-depth: 0  # Fetch all history

Alternatively, fetch only what you need:

yaml
- name: Checkout code
  uses: actions/checkout@v4
  with:
    fetch-depth: 20  # Fetch last 20 commits
5Fix CI/CD configuration (GitLab CI)

For GitLab CI, adjust the clone depth in your .gitlab-ci.yml:

yaml
variables:
  GIT_DEPTH: 0  # Fetch all history

# Or for specific jobs:
job_name:
  variables:
    GIT_DEPTH: 50  # Fetch last 50 commits

You can also configure this globally in GitLab:
Settings > CI/CD > General Pipelines > Git shallow clone depth

6Use available history safely in scripts

When writing scripts that need to reference history, check available commits first:

bash
#!/bin/bash
NEEDED_DEPTH=10
AVAILABLE=$(git rev-list --count HEAD)

if [ "$AVAILABLE" -lt "$NEEDED_DEPTH" ]; then
  echo "Only $AVAILABLE commits available, need $NEEDED_DEPTH"
  # Fetch more history if in shallow clone
  if [ "$(git rev-parse --is-shallow-repository)" = "true" ]; then
    git fetch --deepen=$NEEDED_DEPTH
  else
    # Use what's available
    NEEDED_DEPTH=$AVAILABLE
  fi
fi

git log HEAD~$NEEDED_DEPTH..HEAD
7Alternative: Use commit hash or --root

If you need to reference commits beyond available history, use alternatives:

Reference the first commit:

bash
# Get the first commit hash
git rev-list --max-parents=0 HEAD

# Use it in rebase
git rebase -i --root

Reference by date instead of count:

bash
git log --since="1 week ago"
git diff @{1.week.ago}

Advanced notes

Why CI/CD uses shallow clones: Shallow cloning significantly reduces clone time and bandwidth usage. For large repositories, fetching full history can take minutes, while a shallow clone completes in seconds. Most CI jobs only need the current commit to run tests.

Treeless clones as a middle ground: Git 2.19+ supports partial clones. You can fetch commit history without blob data using:

bash
git clone --filter=tree:0 <url>

This gives you full commit history for references while still saving bandwidth on file contents.

Understanding HEAD~N vs HEAD^N:
- HEAD~N follows the first parent N times (linear history)
- HEAD^N selects the Nth parent of a single commit (useful for merge commits)
- HEAD~3 = "three commits back"
- HEAD^2 = "second parent of HEAD" (in a merge commit)

Repository depth inspection:

bash
# See the shallow boundary commits
cat .git/shallow

# Check repository status
git rev-parse --is-shallow-repository

# See actual depth
git rev-list --count HEAD

Performance considerations: For GitHub Actions, using fetch-depth: 0 on very large repositories (100k+ commits) can significantly slow down your workflow. Consider using a specific depth or fetching only necessary history with git fetch --deepen=N.

Frequently asked questions

What does "fatal: bad revision 'HEAD~10'" mean?
The "fatal: bad revision 'HEAD~10'" error means Git cannot locate the commit you're trying to reference. HEAD~10 refers to the commit that is 10 commits before your current HEAD position. This error typically occurs in these scenarios: 1.
How do I fix "fatal: bad revision 'HEAD~10'"?
This error occurs when Git cannot find the specified commit reference, usually because the repository has fewer commits than requested or you're working with a shallow clone that lacks sufficient history.
What causes "fatal: bad revision 'HEAD~10'"?
Repository has fewer commits than the number specified in HEAD~N reference Working in a shallow clone where only recent commits were fetched (common in CI/CD) Empty repository with no commits yet
Is the "fatal: bad revision 'HEAD~10'" error serious?
It is a low-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading