Git Sparse Checkout
git sparse-checkout checks out part of a repository, for monorepos where you only ever need one directory.
sparse-checkout tells Git to populate only part of the working tree. The other
files are still tracked, still in history, and still on disk in the object
database — they are just not checked out, so they cost you nothing in disk space,
build time or editor indexing.
The problem it solves is a monorepo. On a repository where your work touches one directory, a full checkout is a lot of files you never open, every tool scanning every time, and a working tree that is slow before you have done anything.
Turning it on
git sparse-checkout init --cone
git sparse-checkout set frontend
init --cone switches the repository into sparse mode with cone mode, which is
the mode you want. Cone mode understands whole directories and always includes
the files at the top level of the repository, so a README.md and a
package.json at the root are always present.
Without --cone you get "non-cone" mode, where the patterns are plain
gitignore-style pathspecs and you are responsible for including everything the
repository needs to function. It is more precise and considerably easier to get
wrong.
Adjusting it
git sparse-checkout add shared/ui
git sparse-checkout set frontend shared/ui # replace the set
git sparse-checkout list # what is currently included
git sparse-checkout disable # back to a full checkout
Everything already in the set stays; add widens it. disable removes the
sparse pattern file and restores a normal checkout, and nothing is lost.
What is actually on disk
git sparse-checkout list
ls
Files outside the cone are absent from the working tree, so an editor, a build
tool and ls all agree on the same set. They are not deleted from history and
they are not lost — check them out with git show HEAD:path/to/file without
changing anything.
Rules that still apply
Some tools want everything. A tool that walks the repository root to find config, or that shells out to a binary in another package, will not see what is not checked out. Monorepo tooling varies in how well it copes, so check that your build works before committing to a sparse checkout.
The index is complete. git status, git grep and git diff operate on
the index, not the working tree, so they still see the whole repository. That is
the feature: your mental model of the codebase does not shrink just because the
disk usage did.
It is a local setting. The patterns live in
.git/info/sparse-checkout, which is not committed. Everybody sets up their own,
and nothing about a pull request is affected.
Related
- Git Worktree is the other answer to "I need two directories", and it is better when you need two checkouts rather than a partial one
- Submodules for dependencies that belong in separate repositories