Skip to content
Back to skills

Sparse Checkout

ASecurity

Personally hide files or directories from a git repo's working tree via git sparse-checkout — no .gitignore changes, invisible to teammates. Use whenever the user wants to ignore team-committed paths just for themselves (e.g. .claude/, dist/, generated docs), restore a hidden path, list what's hidden, or undo all hiding. Triggers on "hide X locally", "ignore X locally", "make git stop showing X", "restore hidden files", "what did I hide". Distinct from .gitignore (committed, team-wide) — this...

  • 19 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 6, 2026
developmentpythongogit

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 6, 2026

npx -y skills add mthli/skills --skill sparse-checkout --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Sparse Checkout?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Sparse Checkout
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mthli-sparse-checkout/badge)](https://www.skillsdirectory.com/skills/mthli-sparse-checkout)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: sparse-checkout
description: Personally hide files or directories from a git repo's working tree via git sparse-checkout — no .gitignore changes, invisible to teammates. Use whenever the user wants to ignore team-committed paths just for themselves (e.g. .claude/, dist/, generated docs), restore a hidden path, list what's hidden, or undo all hiding. Triggers on "hide X locally", "ignore X locally", "make git stop showing X", "restore hidden files", "what did I hide". Distinct from .gitignore (committed, team-wide) — this is per-clone, reversible, stays private.
---

# sparse-checkout

Locally hide files and directories that teammates committed, without modifying any tracked file. The exclusion lives in `.git/info/sparse-checkout`, which is per-clone state — your teammates never see it, and `git push` cannot carry it.

## When to use

- Teammates committed personal config / generated output that you don't want in your tree (e.g. `.claude/`, `dist/`, `vendor/`)
- You want a private exclusion without proposing a `.gitignore` change to the team
- The user asks to restore a previously hidden path, or to see what's currently hidden
- The user wants to undo all local hiding

## Mental model

Behind the scenes this uses `git sparse-checkout` in **non-cone mode**, which accepts gitignore-style patterns. A typical patterns file looks like:

```
/*
!.claude/
!docs/private/
```

Read as: "include everything at the root, except `.claude/` and `docs/private/`." The patterns file is `.git/info/sparse-checkout`; it lives inside `.git/`, so it's never pushed and never affects anyone else.

`git sparse-checkout disable` blows the whole thing away and the clone behaves like a normal one again.

## Operations

Use the helper script `scripts/sparse_checkout.py` (relative to this SKILL.md). Resolve its absolute path and run it from anywhere inside the target repo — the script discovers the repo root itself, and path arguments are interpreted relative to that root (not your cwd).

| Goal | Command |
|---|---|
| Hide one or more paths | `python <skill-dir>/scripts/sparse_checkout.py hide <path> [path...]` |
| Restore one or more paths | `python <skill-dir>/scripts/sparse_checkout.py restore <path> [path...]` |
| List what's hidden in this repo | `python <skill-dir>/scripts/sparse_checkout.py list` |
| Show status (enabled? what's hidden?) | `python <skill-dir>/scripts/sparse_checkout.py status` |
| Disable entirely (bring all files back) | `python <skill-dir>/scripts/sparse_checkout.py disable` |

The script auto-detects whether a path is a directory and appends a trailing `/` so the pattern unambiguously matches the whole subtree.

## Safety checks — perform these BEFORE running `hide`

Sparse-checkout removes **tracked** files in the excluded paths from the working tree, but leaves **untracked** files alone. Both behaviors can surprise users. Walk through this checklist:

1. **Check for uncommitted modifications under the target path.** Run `git status --short -- <path>`. If anything tracked shows up (`M` / `A` / `D` / `R`), stop and report — the script enforces this and will refuse the hide. (Background: `git sparse-checkout reapply` is permissive and would warn-but-succeed, leaving the dirty files on disk while the patterns file commits to hiding them — a silent half-applied state that risks losing the modifications on the next checkout. So the script does a hard pre-flight check.) Ask the user whether to commit, stash, or skip.

2. **Note untracked personal files under the target path.** Run `git ls-files --others --exclude-standard -- <path>`. If anything is listed, warn the user: those files **stay on disk** after hiding, so the directory won't fully disappear — it will contain only their personal junk. Usually fine, but they may want to move that content out first.

3. **Confirm it's a git repo.** The script bails with a clear error if not, but it's nicer to know upfront.

For `restore`, no special checks are needed — restored content comes from the git index and is canonical.

## Workflow

When the user asks to hide something:

1. Identify the target path(s). If ambiguous (e.g. "hide the claude stuff"), confirm the exact path.
2. Run the safety checks above and report any findings.
3. Run the `hide` command.
4. Confirm with the user by reading back the resulting state (the script prints it automatically).
5. Mention the inverse command they can use to undo (`restore <path>` or `disable`).

When the user asks to restore or undo:

1. Run `list` first if the path isn't clear, so you can show them options.
2. Run `restore <path>` (specific) or `disable` (everything).
3. Confirm the new state.

## Example interactions

**Example 1 — hide a noisy directory**

User: "hide `.claude/`, teammates keep committing stuff into it"

1. Run `git status --short -- .claude/` and `git ls-files --others --exclude-standard -- .claude/` to check the state.
2. Report findings — e.g. "you have 2 untracked files under `.claude/` (`agents/my-foo.md`, `settings.local.json`). They'll stay on disk after hiding; the directory will only contain those. Proceed?"
3. After confirmation, run `python <skill-dir>/scripts/sparse_checkout.py hide .claude/`.
4. Echo the resulting hidden list.
5. Mention `restore .claude/` undoes it.

**Example 2 — list and partial restore**

User: "I hid a few directories before — list them, then restore the docs one"

1. Run `... list` to show what's hidden.
2. From the list pick the `docs/*` entry the user means; if multiple, ask which.
3. Run `... restore docs/internal/` (or whichever).
4. Echo the new state.

**Example 3 — full undo**

User: "restore everything, I don't want sparse-checkout anymore"

1. Run `... disable`.
2. Confirm it's off; all files are back.

## Edge cases

- **Sparse-checkout already initialized**: the script reads the existing pattern file and merges new exclusions without duplicating.
- **Hiding a path that's already hidden**: no-op, the script reports `(already hidden: <path>)`.
- **Restoring a path that wasn't hidden**: no-op, reports `(not hidden: <path>)`.
- **Restoring the last remaining exclusion**: the script runs `git sparse-checkout disable` for a clean state instead of leaving a no-op patterns file.
- **Not a git repo**: the script exits with a clear error; surface it to the user.
- **Path doesn't exist in HEAD**: still allow hiding — it may exist in other branches the user will check out later.

## What not to do

- Don't edit `.git/info/sparse-checkout` by hand from the model. Use the script — it writes the patterns file and calls `git sparse-checkout reapply`, with a rollback on failure so the patterns file never diverges from the actual working tree.
- Don't propose adding the path to `.gitignore` instead. That's a different problem (preventing new commits of the path) and affects the whole team. This skill is for the opposite case: the path is already tracked, and you personally don't want it in your tree.
- Don't use this in CI / shared scripts. It's a developer-machine convenience.

Files in this skill

  • SKILL.md6.9 KB
  • scripts/sparse_checkout.py8.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…