Git, CI/CD & GitOpsCII · Large Repository PerformanceShallowAndPartial
Shallow clones and partial checkouts — fetching less history
What you'll learn
- Distinguish a shallow clone from a partial clone and explain when each helps
- Choose `--depth`, `--shallow-since`, `--filter=blob:none`, `--filter=tree:0` for the workload
- Recognise the operations a shallow or partial clone does not support
- Apply the right combination for an engineer workstation versus a CI runner
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
A shallow clone truncates history at a depth; a partial clone defers blobs on demand. Both cut bandwidth; both impose limits. The trade is fetch cost versus local capability.
Shallow clones
git clone --depth 1 "$REPO_URL" repo
git clone --depth 50 --branch main "$REPO_URL" repo
git clone --shallow-since="2024-01-01" "$REPO_URL" repo
--depth 1 fetches only the tip (cheapest).
--shallow-since is date-bounded.
flowchart LR
A[("full")] -->|"depth 1"| B[("tip")]
A -->|"depth 50"| C[("last 50")]
A -->|"shallow-since"| D[("since date")]
Shallow clones cannot run most history ops:
git log --all shows only the present window;
git bisect cannot reach older bugs.
Partial clones
git clone --filter=blob:none "$REPO_URL" repo
git clone --filter=tree:0 "$REPO_URL" repo
git clone --filter=blob:limit=1m "$REPO_URL" repo
--filter=blob:none defers all blobs. --filter=tree:0
defers all trees (rarely useful). --filter=blob:limit=1m
defers blobs above 1 MB.
flowchart LR
A[("full")] -->|"filter blob:none"| B[("commits+trees")]
B -->|"checkout needs blob"| C["on-demand"]
A partial clone has full history, but ops that read a
blob trigger fetches. git log -p fetches per hunk.
Choosing a strategy
- CI cold cache.
--depth 1, no--filter. - Engineer workstation.
--filter=blob:none, no--depth. - CI release tag.
--branch $TAG --depth 1. - Long-lived feature. No shallow, no partial; the history is the value.
Shallow can git fetch --unshallow; partial can
git fetch --filter= to materialise.
Production discipline
- Default CI to
--depth 1, no--filter. - Default workstations to
--filter=blob:none, no--depth. - Pin release builds to
--branch $TAG. - Document the unshallow path.
Cross-course references
- Linux for Production Sysadmins Part XXVI: filesystem analogue.
- Terraform for Production Sysadmins Part IX: state in a backend.
Quiz
Knowledge check · 4 questions
Q1. An engineer runs `git clone --depth 1`, then `git bisect start` for a year-old regression. What fails?
Q2. A partial clone (`--filter=blob:none`) defers all reachable blobs and is equivalent to a shallow clone in capability.
Q3. Name the two shallow-clone flags that bound commits by depth and by date, and the two partial-clone flags that defer all blobs and blobs above a size limit.
Q4. Recommend the right shallow/partial strategy for engineer workstation versus CI runner.
Team J: 5 GB Terraform monorepo with 8 GB packfile. Engineer cold clone is 22 min; CI cold cache is 18 min. Team wants to cut both.
Passing score: 75%. Answers are checked in this browser.