Skip to content
masterclass Buddy

Git · Command

git sparse-checkout

git sparse-checkout limits your working tree to a chosen subset of tracked files. You can also use it to change that subset later or to bring back the full checkout.

Last updated

How it works

Git keeps your chosen directories or patterns in $GIT_DIR/info/sparse-checkout. Whenever Git updates the working tree, it uses that file to set or clear the skip-worktree bit on each index entry. Files with the bit set are left out of the working tree, and Git does not treat them as missing. In cone mode, which is the default, you list directories and Git turns them into recursive and parent patterns that it can match quickly with hashing. The set and add subcommands write the file and then update the working tree to match.

Syntax

git sparse-checkout (init | list | set | add | reapply | disable | check-rules | clean) [<options>]

Parameters

NameTypeDescription
set <dir>...subcommandTurns on the required config settings, replaces the sparsity definition with the given directories or patterns, and updates the working tree to match.
add <dir>...subcommandAdds more directories (cone mode) or patterns (non-cone mode) to the current definition.
listsubcommandShows the directories or patterns in the sparse-checkout file.
reapplysubcommandApplies the current rules to the working tree again. It also accepts --[no-]cone and --[no-]sparse-index, so you can switch modes without listing your paths again.
disablesubcommandTurns off core.sparseCheckout and checks out every file again.
check-rulessubcommandReads paths from stdin and prints the ones that match the sparsity rules. Options: --rules-file <file> to test other rules, and -z for NUL-terminated input and output.
cleansubcommandDeletes leftover files that are outside the sparse definition. It only works in cone mode and needs -f/--force unless clean.requireForce is false. Also accepts --dry-run and --verbose.
initsubcommandDeprecated. Works like set with no paths and may be removed in the future.
--stdinoptionFor set or add: read directories or patterns from standard input, one per line, instead of from the arguments.
--[no-]coneoptionChoose directory-based cone mode (the default) or gitignore-style pattern (non-cone) mode.
--[no-]sparse-indexoptionTurn the experimental sparse index on or off. It is off by default.

Returns

Most subcommands change config, the sparse-checkout file and the working tree. list prints the directories that are included (cone mode), and check-rules prints the input paths that match the rules.

Key points

  • In cone mode you get everything at any depth under each listed directory. You also get the files that sit directly inside each of its parent directories, including the repository root.
  • Even when you list no directories, files at the top level of the repository stay in the working tree.
  • Sparsity is set per worktree. The set subcommand turns on worktree-specific config so that other linked worktrees keep their own settings.
  • Other commands respect the sparse definition. Switching branches leaves files outside it alone, and commit -a does not record those missing files as deleted.
  • add extends an existing definition. It is not a way to start one, so run set first.
  • A merge or rebase can bring files outside your cone back into the working tree, for example to show a conflict. Once you have resolved it, run reapply to make the tree sparse again.
  • A sparse index stores directory entries in place of the files beneath them. This can make commands like status and add much faster.
  • Changing the sparse rules never initializes or removes a submodule's checkout, because removing one could lose unpushed or untracked work.

Common mistakes

  • Non-cone (pattern) mode is officially deprecated. It scales poorly and makes it easy to pass shell-expanded globs by mistake, so use cone mode.
  • Narrowing the selection with set can silently delete ignored files, such as build output, in directories that drop out of the cone.
  • If a directory outside the cone holds untracked files that are not ignored, Git leaves the directory in place and prints a warning.
  • Older Git versions and external tools may not understand a sparse index. To rewrite the index as a normal one, run init --no-sparse-index.

Example: Narrow a repo to two directories, inspect, extend, and restore

set -e
rm -rf demo && mkdir demo && cd demo && git init -q
mkdir -p MY/DIR1 MY/other SUB/DIR2 docs
for f in README MY/a MY/DIR1/b MY/other/c SUB/DIR2/d docs/e; do echo x > "$f"; done
git add . && git -c user.name=me -c user.email=me@x commit -qm init

# Keep only MY/DIR1 and SUB/DIR2 (cone mode is the default)
git sparse-checkout set MY/DIR1 SUB/DIR2
git sparse-checkout list          # MY/DIR1, SUB/DIR2
find . -path ./.git -prune -o -type f -print | sort

# Which of these paths would be included?
printf 'docs/e\nMY/DIR1/b\n' | git sparse-checkout check-rules

# Grow the cone, then go back to a full checkout
git sparse-checkout add docs
git sparse-checkout disable
ls MY/other                       # c is back

The script builds a small repository, limits it to two directory cones, checks paths against the rules, adds a third directory, and then restores the full working tree.

When to use it

Monorepo team focus

A developer on one service in a large monorepo checks out only that service's directory and the shared libraries it needs, so status and checkout stay fast.

CI jobs on a subset

A CI pipeline that builds or tests one component uses set --stdin to read the directories it needs from a generated list, so it only puts those files on disk.

Recovering after a conflicted merge

After a rebase writes conflicted files outside the cone, the engineer resolves them and runs reapply, then clean -f, to make the tree sparse again.

Validating sparsity rules in tooling

A script runs check-rules with --rules-file on a list of changed paths to see whether a proposed sparse definition would include them.

Interview questions

QHow does Git implement a sparse checkout internally?

Each index entry has a skip-worktree bit. When Git updates the working tree, it sets or clears that bit according to the rules in $GIT_DIR/info/sparse-checkout. Files with the bit set are left out of the working tree, and Git treats their absence as expected rather than as a deletion. They are still tracked, so commits contain the full tree.

Follow-up: Why does git sparse-checkout list show only directories in cone mode when the file contains many patterns? Answer: In cone mode Git writes the expanded recursive and parent patterns to the file, but list shows only the directories that define the recursive patterns.

QWhat is the difference between cone mode and non-cone mode, and which should you use?

In cone mode you list directories, and Git includes everything below them plus the files directly inside their parent directories. Because the rules are this limited, Git can match them quickly with hashing. Non-cone mode accepts any gitignore-style pattern, which costs O(N*M) pattern matches, does not work with --sparse-index, and is deprecated. Use cone mode, which is the default.

Follow-up: What happens if a hand-edited sparse-checkout file no longer fits the cone pattern format? Answer: Git prints a warning and falls back to non-cone matching, whatever core.sparseCheckoutCone is set to.

QAfter a rebase with conflicts, files outside your sparse cone appear in the working tree. How do you clean this up?

Resolve the conflicts and commit or undo any changes to those files, then run git sparse-checkout reapply to apply the rules again. If directories outside the cone still contain leftover files, run git sparse-checkout clean, which only deletes with -f/--force. Run it with --dry-run or --verbose first to see what it would remove.

Follow-up: Why might clean still leave a directory in place? Answer: Merge conflicts or modified files outside the definition can keep files that would otherwise be removed. --verbose lists the files in each directory being considered, which helps explain why one is still there.

  • git-read-tree
  • git-update-index
  • git-worktree
  • git-config
  • gitignore
  • git-clone
  • git-submodule

Source: Git - git-sparse-checkout Documentation. Checked 2026-11-02.