Monorepo
One-liner¶
Git monorepo patterns — sparse checkout, partial clone, and path ownership — make large single-repository architectures performant.
Why it matters¶
A monorepo gives you atomic cross-service changes, a single CI pipeline, and shared tooling. But git wasn't designed for repositories with thousands of developers and hundreds of services. Without specific patterns, clone takes 30 minutes, status is slow, and logs are noisy. The right techniques make git scale to monorepo size.
Core concept¶
Imagine a massive library. Checking out every book (full clone) is absurd when you only read from one shelf. Sparse checkout is like having a library card that only materializes the shelves you need on your desk. Partial clone goes further — the library doesn't even ship books to your house until you actually open them. You get the catalogue (history) instantly, and content arrives on demand.
These patterns reduce what git downloads and materializes, while keeping the full repository logically unified.
How it works¶
- Sparse checkout —
git sparse-checkout set <paths>materializes only specified directories; everything else exists in git but isn't on disk. - Partial clone —
git clone --filter=blob:nonedownloads commit and tree objects but fetches file content (blobs) only when you access them. - Shallow clone —
git clone --depth=1fetches only recent commits; ideal for CI jobs that don't need full history. - Path-based ownership —
CODEOWNERSfile maps directories to teams, ensuring the right reviewers see changes. - Scoped commits — prefixing commit messages with service names (
auth: add OAuth) makesgit logfilterable.
Key terms¶
- Sparse checkout — git feature that limits which directories are materialized in the working tree
- Partial clone (
--filter=blob:none) — clone that downloads blobs lazily on demand instead of upfront - Shallow clone (
--depth=N) — clone limited to N commits of history; no access to older history withoutgit fetch --unshallow CODEOWNERS— file defining path-to-team ownership; used by GitHub/GitLab for automatic reviewer assignment- Affected-path CI — CI pattern that only builds/tests services whose files changed in a given commit
Common misconceptions¶
- "Git can't handle large repos" — It handles them fine with the right patterns. Google, Meta, and Microsoft all use git-based monorepos with custom tooling on top.
- "Sparse checkout means I lose access to other code" — You can add paths at any time without network access. The full history is still there; you're just choosing what to materialize.
- "Monorepo means slower CI" — With affected-path detection (
git diff --name-only), CI only builds what changed. This is often faster than multi-repo CI that triggers full pipelines.
When to use / not use¶
✓ Use when: you need atomic changes across services, shared libraries change frequently, you want a single source of truth, or cross-team coordination overhead is high in multi-repo.
✗ Don't use when: teams are fully independent with no shared code, access control requires repo-level isolation, or the team lacks tooling investment to manage scale.
Example¶
# Efficient monorepo clone
git clone --filter=blob:none --sparse https://github.com/org/monorepo.git
cd monorepo
git sparse-checkout set services/auth shared/config tools/
# Find affected services in CI
git diff --name-only origin/main...HEAD | grep "^services/" | cut -d'/' -f2 | sort -u
Next steps¶
- Set up sparse checkout profiles per team (
git sparse-checkout set $(cat .sparse/team-platform.txt)) - Implement affected-path CI detection to only build changed services
- Explore
git maintenance startfor background repo optimization (prefetch, commit-graph, incremental-repack)