Performance
Partial Clone: On-Demand Git Object Fetching
An in-depth look at Git partial clone — how filters and promisor remotes work, and how to speed up clone and fetch in large repositories.
- Developers managing large Git repositories
- Developers optimizing CI pipeline speed
- Basic understanding of clone and fetch mechanisms
- Awareness of the object database concept
- Using partial clone on unsupported servers
- Misconfigured sparse checkout leading to incomplete workspace
Citations & Further Reading
What you will learn
- Understand the core purpose of Partial Clone: On-Demand Git Object Fetching
- Master the basic usage and common options of Partial Clone: On-Demand Git Object Fetching
- An in-depth look at Git partial clone — how filters and promisor remotes work, and how to speed up clone and fetch in large repositories.
- Understand key concepts: How It Works
- Know when to use this feature and when to avoid it
Start with a problem
Your Git repository keeps growing, clones are getting slower, and everyday operations are starting to feel sluggish. You want to know what optimization techniques are available and which ones fit your project.
One-Sentence Understanding
Partial clone lets you clone a repository downloading only the Git objects you need, fetching others on-demand — like lazy loading for Git.
How It Works
Filter
At clone/fetch time, specify which objects to exclude:
git clone --filter=blob:none <url>
Promisor Remote
Filtered objects aren't lost — Git knows which remote can provide them. When needed, Git automatically fetches from the promisor remote:
# This is a partially cloned repo
cd repo
# The workspace is nearly empty, but metadata is local
git checkout main
# → Git auto-fetches file contents from the remote
Filter Types
blob:none
Exclude all blob objects (file contents), download only commit, tree, and tag objects:
git clone --filter=blob:none <url>
- Reduces initial download by 70-90%
- First checkout needs network
- Best for general use
tree:0
Exclude tree and blob objects, download only commits:
git clone --filter=tree:0 <url>
- Minimal initial download
- Most operations require remote requests
- Best for log/metadata only
blob:limit=<size>
Exclude blobs larger than the limit:
git clone --filter=blob:limit=1m <url>
Combining Filters
git clone --filter="combine:blob:none+tree:0" <url>
Practical Guide
Clone a Partial Clone Repo
# Standard partial clone
git clone --filter=blob:none https://github.com/example/large-repo.git
# With sparse checkout
git clone --filter=blob:none --sparse https://github.com/example/large-repo.git
cd large-repo
git sparse-checkout set src/my-team
Enable in Existing Repo
git config core.repositoryformatversion 1
git config extensions.partialClone origin
# Remove all local blob objects
git rev-list --objects --all | git pack-objects --stdout | git pack-objects --stdin --keep-unreachable
git prune
Manual Fetch
# Trigger promisor fetch
git fetch --refetch
# Auto-fetch missing blobs
git cat-file -p <blob-hash>
Performance
| Scenario | Full Clone | blob:none | Savings |
|---|---|---|---|
| Initial download | 500MB | 50MB | 90% |
| git log | Fast | Fast | Same |
| git checkout | Fast | Needs fetch | Slower |
| git status | Fast | Needs fetch | Slower |
Limitations
- Network dependency for first checkout and diffs
- Server-side support: GitHub ✓, GitLab 13.6+ ✓, Bitbucket limited
git gcneeds special handling- Some tools and old IDE integrations may not be compatible
Revert to Full Clone
git fetch --unshallow
git config --unset extensions.partialClone
Try it yourself
- Practice the partial-clone command in a test repository and observe state changes before and after
- Experiment with different options and compare the output differences
- Simulate a real scenario where you would need to use this, and walk through the full process
Continue Learning
performance/large-repo-optimization— Comprehensive optimizationcommands/git-sparse-checkout— Sparse checkoutinternals/packfiles-and-storage— Object storage & packfiles
Further reading
Keep going on the same topic: