Git sparse checkout lets you check out only a subset of your repository, which is a lifesaver for massive monorepos.

Let’s see it in action. Imagine you have a giant repository with multiple independent projects:

/
├── project-a/
│   ├── src/
│   │   └── index.js
│   └── package.json
├── project-b/
│   ├── src/
│   │   └── main.go
│   └── go.mod
├── shared-libs/
│   └── utils.js
└── README.md

You only want to work on project-a. Without sparse checkout, git clone would download everything, which could take ages and consume tons of disk space.

With sparse checkout, you can do this:

# First, clone the repository shallowly to get the history quickly
git clone --filter=blob:none --no-checkout <repository_url>
cd <repository_name>

# Now, enable sparse checkout
git sparse-checkout init --cone

# Tell Git which directories you want
git sparse-checkout set 'project-a/'

# Finally, perform the actual checkout
git checkout main # or your branch name

After these commands, your working directory will only contain project-a/ and the root README.md (because the root is implicitly included unless you explicitly exclude it). The project-b/ and shared-libs/ directories will be completely absent from your filesystem.

The magic here is that Git doesn’t just ignore files; it actively prunes them from your working tree. Your .git directory still contains the full history of the entire repository, but your working directory is surgically sculpted to contain only what you’ve specified.

The core problem sparse checkout solves is the unmanageability of extremely large Git repositories. Monorepos, by their nature, can grow to hundreds of gigabytes and contain millions of files. Cloning, fetching, and even basic operations like git status can become prohibitively slow or even impossible on standard hardware. Sparse checkout allows developers to interact with a manageable subset of the repository, drastically improving performance and reducing resource consumption.

Internally, sparse checkout works by manipulating the .git/info/sparse-checkout file and the index. When you git sparse-checkout set, Git updates this file with patterns defining what should be in the working directory. It then prunes files and directories from the index that don’t match these patterns, and finally, it updates the working tree to reflect the pruned index. The --cone mode is a more efficient, directory-based mode where you specify directories, and Git automatically includes all files within those directories.

You can manage sparse checkout patterns with commands like:

  • git sparse-checkout list: Shows the current patterns.
  • git sparse-checkout add <pattern>: Adds a new pattern.
  • git sparse-checkout disable: Disables sparse checkout and checks out everything.

For instance, to add project-b to your existing checkout:

git sparse-checkout add 'project-b/'
git checkout main # or your branch name, to update the working tree

Now, both project-a/ and project-b/ will be present.

It’s worth noting that the --cone mode is generally preferred for its performance benefits. It operates on directory prefixes, which Git can process more efficiently than complex path-based patterns. If you use --cone, you specify directories, and Git implicitly includes everything within them. For example, git sparse-checkout set --cone 'project-a/' will include project-a/src/ and project-a/package.json.

A common point of confusion is how the root directory is handled. By default, when you enable sparse checkout (especially with --cone), the root directory of the repository is implicitly included. This means files directly in the root, like README.md in our example, will be checked out even if you only specify project-a/. If you want to exclude files from the root or other directories, you can use negative patterns (e.g., !README.md) or more complex non-cone patterns, but this can be less performant.

The next hurdle you’ll likely encounter is understanding how sparse checkout interacts with submodules, as managing sparse submodules requires additional configuration.

Want structured learning?

Take the full Git course →