Lazy object fetching
Partial clone (--filter) lets a clone omit some objects from the initial transfer, fetching them lazily when needed. The promisor remote keeps its promise to provide them on demand. This is the foundation of usable monorepo clones — full history, fraction of the data.
Filter specs
git clone --filter=blob:none url # no blobs
git clone --filter=blob:limit=1m url # blobs <1MB only
git clone --filter=tree:0 url # no trees or blobs (history-only)
git clone --filter=sparse:oid=<oid> url # only paths matching sparse spec
See "Filter specs: blob:none, tree:0, and combining filters".
How fetching works
When a command asks for a missing object, Git automatically fetches it from the promisor remote. This is transparent for most operations but can introduce latency on first use. For predictable workflows, prefetch:
git rev-list --objects --missing=allow-promisor HEAD | \
awk '{print $1}' | git cat-file --batch-check
git fetch --refetch # rebuild missing
Inspecting
git config --get-all remote.origin.partialclonefilter
git rev-list --missing=print HEAD | head
git config --get extensions.partialClone
Caveats
- Operations like
git log -pacross all history may trigger massive on-demand fetches; pair with sparse checkout for predictability. - Disconnected use is limited — without the promisor, missing objects fail.
- Server must support partial clone (Git 2.22+;
uploadpack.allowFilter=true).
Server config
[uploadpack]
allowFilter = true
allowAnySHA1InWant = true
Combining with sparse
git clone --filter=blob:none --sparse https://example.com/big.git
cd big
git sparse-checkout init --cone --sparse-index
git sparse-checkout set apps/web
git checkout main
Now you have history for everything, but blob content only for the cone — the gold-standard monorepo setup.
Common mistakes
Using --filter=tree:0 for development work — every operation that needs a tree fetches it, slow and unpredictable. Reserve for analysis-only clones. Forgetting to keep the promisor reachable; offline becomes painful. Disabling fetch.parallel; multiple lazy fetches benefit from concurrency.
Related
See "Filter specs: blob:none, tree:0, and combining filters", "Sparse checkout for monorepos", and "The sparse index: operating without a full index".