This error occurs when you run `git fetch --unshallow` on a repository that already has full history. The fix involves checking if the repository is shallow before attempting to unshallow it, typically by using conditional logic in CI/CD scripts.
The "fatal: --unshallow on a complete repository does not make sense" error indicates that you're trying to convert a shallow clone to a full clone, but the repository already has complete history. When you clone a repository with `git clone --depth N`, Git creates a "shallow" clone that only fetches the specified number of commits. This saves time and bandwidth, especially in CI/CD pipelines. The `--unshallow` flag is designed to fetch the remaining history for such shallow clones. However, if the repository is not actually shallow (either because it was cloned without depth limits, or was already unshallowed), running `git fetch --unshallow` will fail with this error. Git refuses to perform an operation that doesn't make sense for the repository's current state. This commonly happens in CI/CD environments where scripts assume the checkout is always shallow, but the configuration changes or the clone behavior differs between CI systems or versions.
Before running --unshallow, verify the repository is actually shallow:
# Check if .git/shallow file exists
if [ -f .git/shallow ]; then
git fetch --unshallow
else
echo "Repository is not shallow, skipping unshallow"
fiAlternatively, use Git's built-in method:
# Git returns true if shallow, false otherwise
if git rev-parse --is-shallow-repository | grep -q "true"; then
git fetch --unshallow
fiIf using GitHub Actions, you can either clone with full depth initially or add conditional logic:
Option 1: Clone with full depth (simpler)
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full clone, no need to unshallowOption 2: Conditional unshallow
- uses: actions/checkout@v4
with:
fetch-depth: 1 # Shallow clone
- name: Fetch full history if needed
run: |
if git rev-parse --is-shallow-repository | grep -q "true"; then
git fetch --prune --unshallow
fiFor GitLab CI, control clone depth through variables:
Option 1: Full clone via variables
variables:
GIT_DEPTH: 0 # Full clone
script:
# No unshallow needed
- git log --onelineOption 2: Conditional unshallow in script
variables:
GIT_DEPTH: 10 # Shallow clone
script:
- |
if [ -f .git/shallow ]; then
git fetch --unshallow origin
fi
- git log --onelineIf you need more history but not necessarily all of it, use --depth or --deepen which work on both shallow and full repositories:
# Fetch additional commits (works on any repo)
git fetch --depth=100
# Or deepen by N commits from current shallow point
git fetch --deepen=50Note: --depth on a full repository has no effect (it won't truncate history), making it safe to use unconditionally.
If you want your script to continue regardless of whether unshallow succeeds:
# Attempt unshallow but don't fail the script
git fetch --unshallow 2>/dev/null || true
# Or with more informative output
git fetch --unshallow || echo "Repository already has full history"For more complex scenarios:
#!/bin/bash
set -e
fetch_full_history() {
if git rev-parse --is-shallow-repository 2>/dev/null | grep -q "true"; then
echo "Fetching full history..."
git fetch --prune --unshallow
else
echo "Repository already has full history"
fi
}
fetch_full_historyIf you're unsure about your repository's state, run these diagnostic commands:
# Check if shallow
git rev-parse --is-shallow-repository
# View shallow boundaries (if any)
cat .git/shallow 2>/dev/null || echo "Not a shallow clone"
# Count available commits
git rev-list --count HEAD
# Check clone configuration
git config --get remote.origin.fetchIf the repository shows as not shallow but you expected it to be, check your CI configuration for clone depth settings.
### Why CI Systems Use Shallow Clones
CI/CD systems default to shallow clones (typically depth 1 or 10) for performance:
- Faster checkout times
- Less bandwidth usage
- Reduced disk space
However, some operations require full history:
- Generating changelogs between tags
- Running git describe
- Determining version numbers from tags
- Bisecting to find bug introductions
### The .git/shallow File
The .git/shallow file contains SHA-1 hashes of commits that mark the boundary of your shallow clone. Git treats these as root commits even though they have parents. When this file doesn't exist, Git knows the repository has complete history.
# Example .git/shallow content
e4c5a8b9d1f2e3a4b5c6d7e8f9a0b1c2d3e4f5a6### Portable Detection Script
For scripts that need to work across different Git versions and environments:
is_shallow_repo() {
# Method 1: Check file (works everywhere)
if [ -f "$(git rev-parse --git-dir)/shallow" ]; then
return 0
fi
# Method 2: Use git command (Git 2.15+)
if git rev-parse --is-shallow-repository 2>/dev/null | grep -q "true"; then
return 0
fi
return 1
}
if is_shallow_repo; then
git fetch --unshallow
fi### Differences Between CI Systems
| CI System | Default Clone | Unshallow Method |
|-----------|---------------|------------------|
| GitHub Actions | shallow (depth 1) | fetch-depth: 0 or git fetch --unshallow |
| GitLab CI | shallow (depth 20) | GIT_DEPTH: 0 or git fetch --unshallow |
| Jenkins | full clone | N/A (already complete) |
| CircleCI | shallow | checkout with full clone option |
| Azure DevOps | shallow (depth 1) | fetchDepth: 0 |
Understanding your CI system's default behavior helps prevent this error.
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