By admin , 29 April 2026

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 -p across 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".