Shallow Clone
A shallow clone is a repository clone that contains only a limited portion of the commit history rather than the full graph going back to the very first commit. Git truncates the history at a specified depth and marks those boundary commits as grafts. The result is a fully functional working repository — you can build, test, and commit — using a fraction of the disk space and download time of a full clone. For CI/CD pipelines that run hundreds of times per day, shallow clones are an enormous practical improvement.
Clone with Depth 1 (Most Common)
Depth 1 means download only the most recent commit on the requested branch. This is the absolute fastest way to get code onto a machine and is the default in most CI systems.
Clone with only the latest commit
git clone --depth=1 https://github.com/org/large-repo.git cd large-repo # Only one commit in history git log --oneline # a3f1c2d (HEAD -> main, origin/main) Add authentication module # Confirm it is shallow git rev-parse --is-shallow-repository # true
Size comparison (a real web app repository)
Full clone: 500 MB 30 seconds Shallow --depth=1: 12 MB 2 seconds GitHub Actions pipeline improvement: Without shallow clone: 45s checkout With --depth=1: 4s checkout (~89% faster)
Clone with N Commits of History
A depth greater than 1 is useful when you need git log to show recent changes, generate changelogs, detect which packages changed between commits, or run release tools like semantic-release that inspect commit messages.
Clone with the last 10 commits
git clone --depth=10 https://github.com/org/repo.git cd repo git log --oneline # Shows 10 commits
Shallow Clone Since a Date
Clone only commits after a specific date
# All commits since January 1, 2023 git clone --shallow-since="2023-01-01" https://github.com/org/repo.git # Using a relative time expression git clone --shallow-since="6 months ago" https://github.com/org/repo.git
Exclude Commits Reachable from a Tag
Shallow clone excluding commits before v1.0
git clone --shallow-exclude=v1.0 https://github.com/org/repo.git # Downloads all commits after v1.0 was tagged
Single-Branch Shallow Clone (Fastest CI Setup)
Combine shallow with single-branch for maximum speed
git clone --depth=1 --branch=main --single-branch https://github.com/org/repo.git # --single-branch: do not fetch any other branches # --branch=main: fetch only this branch # --depth=1: only the most recent commit
What the Shallow Boundary Looks Like
ASCII diagram: full history vs shallow clone
Full history:
A --- B --- C --- D --- E --- F --- G (HEAD)
Shallow clone with --depth=3:
E --- F --- G (HEAD)
^
shallow graft point
(Git pretends E has no parents)
.git/shallow file:
<hash of E> ← marks the truncation boundaryInspect the shallow boundary file
cat .git/shallow # e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8 # Check if the repo is shallow git rev-parse --is-shallow-repository # true
Inspecting History in a Shallow Clone
git log in a shallow clone
git log --oneline # a3f1c2d (HEAD -> main, origin/main) Add auth module ← depth=1, only this git log --oneline --graph # * a3f1c2d (HEAD -> main, origin/main) Add auth module # Trying to go deeper shows nothing git log --oneline main~5 # fatal: ambiguous argument 'main~5': unknown revision
Deepening an Existing Shallow Clone
After cloning with a small depth, you can fetch more history without re-cloning from scratch. This is more efficient when you realise mid-pipeline that you need a few more commits.
Fetch more history into a shallow clone
# Add 20 more commits to the history git fetch --deepen=20 # Now you have 21 commits visible (original 1 + 20 more) git log --oneline | wc -l # 21 # Deepen until you reach a specific commit git fetch --shallow-exclude=abc1234
Unshallowing a Clone
To convert a shallow clone into a full clone with complete history, fetch --unshallow downloads all the missing history from the remote.
Convert shallow clone to full clone
git fetch --unshallow # Equivalent using pull git pull --unshallow
Limitations of Shallow Clones
git log shows incomplete history — commits before the graft point are invisible
git blame may be cut off — cannot trace lines beyond the shallow boundary
git bisect is limited — binary search only works within the visible commit range
git describe may give wrong results — the nearest tag might be hidden by the shallow cut
Some merge strategies fail — merge-base calculations can break if the common ancestor is beyond the boundary
Submodule operations may fail — if submodule commits fall below the shallow boundary
Shallow Clone in CI/CD Systems
GitHub Actions: controlling fetch depth
# .github/workflows/ci.yml
- uses: actions/checkout@v4
with:
fetch-depth: 1 # default: shallow clone, fastest
# For semantic-release, changelogs, or affected-packages detection:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # full history (0 = unshallow)GitLab CI: controlling clone depth
# .gitlab-ci.yml variables: GIT_DEPTH: 1 # shallow — last commit only # GIT_DEPTH: 0 # full history # GIT_DEPTH: 20 # last 20 commits
Partial Clone: A More Advanced Alternative
Git 2.22+ supports partial clones, which are related to but different from shallow clones. A partial clone downloads full commit history but defers downloading large file contents (blobs) until they are actually checked out. This is ideal when you need full history for git operations but want to avoid downloading large binary assets upfront.
Partial clone variants
# Blobless: full history, fetch blobs on demand git clone --filter=blob:none https://github.com/org/repo.git # Treeless: full history, fetch trees and blobs on demand git clone --filter=tree:0 https://github.com/org/repo.git
Comparison Table
Feature | Full Clone | Shallow Clone (--depth=1) | Partial Clone (--filter=blob:none) |
|---|---|---|---|
Download size | Largest | Smallest | Medium |
Full commit history | Yes | No — truncated | Yes |
git blame (full) | Yes | Limited | Yes |
git bisect (full) | Yes | Limited | Yes |
git describe accuracy | Yes | May be wrong | Yes |
Blobs downloaded upfront | All | Only for shallow commits | No — on demand |
Best for | Development, code review | CI builds, read-only runs | CI needing git ops |
Server requirement | Any Git server | Any Git server | Git 2.22+ server |