This error occurs when Git cannot resolve the revision range specified in git format-patch. Common causes include not having enough commits in the repository, working with a shallow clone, or referencing commits that don't exist.
When you run `git format-patch HEAD~5..HEAD`, Git tries to create patch files for the last 5 commits by resolving the revision range. The `HEAD~5` syntax means "go back 5 commits from HEAD." If your repository doesn't have 5 commits yet, or if you're working with a shallow clone that truncated the history, Git cannot find this reference and fails with "bad revision." The error can also occur in completely empty repositories where HEAD doesn't point to any commit yet (called an "unborn branch"). In this state, any reference to HEAD will fail since there's no commit history to traverse. This is commonly encountered in CI/CD pipelines where shallow clones are used to speed up checkout times, or when working with newly initialized repositories that don't have enough commit history for the specified range.
First, determine how many commits are available in your current branch:
git rev-list --count HEADIf this returns a number smaller than the range you're trying to use (e.g., returns 3 but you're using HEAD~5), that's the problem. You can also view recent commits:
git log --onelineThis shows commit history so you can see exactly how many commits exist.
If you have fewer commits than requested, adjust your range accordingly:
# If you have 3 commits, use HEAD~3 instead of HEAD~5
git format-patch HEAD~3..HEAD
# Or create patches for all commits since root
git format-patch --root HEAD
# For a single commit patch
git format-patch -1 HEADTo dynamically use all available commits:
# Get the count and use it
COUNT=$(git rev-list --count HEAD)
git format-patch HEAD~$COUNT..HEADShallow clones truncate history to speed up cloning. Check if your repository is shallow:
git rev-parse --is-shallow-repositoryIf this returns "true", fetch more history:
# Fetch complete history
git fetch --unshallow
# Or fetch a specific depth
git fetch --depth=100In CI/CD configurations, you can prevent shallow cloning:
GitHub Actions:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all historyGitLab CI:
variables:
GIT_DEPTH: 0 # Fetch all historyIf the repository has no commits yet, HEAD doesn't exist:
# Check if HEAD exists
git rev-parse HEADIf this fails with "bad revision 'HEAD'", you need to create at least one commit first:
# Create initial commit
git add .
git commit -m "Initial commit"
# Now format-patch will work
git format-patch -1 HEADTo create patches from the very first commit, use the --root option:
# Create patches for all commits
git format-patch --root
# Create patches from root to specific commit
git format-patch --root <commit-hash>
# Get root commit hash
git rev-list --max-parents=0 HEADThis is useful when you need patches for all commits regardless of how many exist.
If HEAD is corrupted, you may need to repair it:
# Check current HEAD state
cat .git/HEAD
# Should show something like: ref: refs/heads/main
# If empty or corrupted, reset it:
git symbolic-ref HEAD refs/heads/main
# Verify repository integrity
git fsck --fullIf fsck reports errors, you may need to restore from a backup or re-clone the repository.
### Using format-patch in CI/CD Pipelines
When automating patch generation in CI/CD, always account for shallow clones:
# Safe script that handles any commit count
COMMITS=$(git rev-list --count HEAD 2>/dev/null || echo 0)
if [ "$COMMITS" -eq 0 ]; then
echo "No commits found"
exit 1
elif [ "$COMMITS" -lt 5 ]; then
git format-patch --root HEAD
else
git format-patch HEAD~5..HEAD
fi### Difference Between ~ and ^ in Git
Understanding Git's revision syntax helps avoid these errors:
- HEAD~N - Go back N generations following first parent (linear history)
- HEAD^N - Go to the Nth parent of a merge commit
- HEAD~3 is equivalent to HEAD~~~ or HEAD^^^^ following first parents
### Creating Patches for Specific Commits
Instead of using ranges, you can specify exact commits:
# Single commit
git format-patch -1 abc1234
# Between two specific commits
git format-patch abc1234..def5678
# Using branch comparison
git format-patch origin/main..HEAD### Format-patch vs diff
- git format-patch creates email-formatted patches with commit metadata
- git diff creates raw diffs without commit information
- Use git am to apply format-patch output, git apply for raw diffs
warning: 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