Git Sparse-Checkout — A Friendly Guide (with --cone vs non-cone)

From Qiki
Jump to navigation Jump to search

1) Introduction

What is sparse-checkout?

Sparse-checkout lets you check out only part of a repository to your working directory. You still have the full commit history locally, but you only download or materialize certain folders/files to save time and disk space.

Why use it?

  • Large/monorepos: You don’t need everything.
  • Faster operations: Less to index, build, and search.
  • Clear focus: Only the folders you care about appear in your working tree.



2) Setting up Sparse-Checkout

We’ll create a fresh clone and then turn on sparse-checkout. (You can also enable it in an existing clone.)

Example repo layout (imaginary)

repo/
  app/
  libs/
    utils/
    api/
  docs/
  tools/
  tests/

A) New clone (faster with partial clone)

git clone --filter=blob:none --no-checkout https://example.com/your/large-repo.git
cd large-repo

Explanation: --filter=blob:none avoids downloading all file contents up front. --no-checkout postpones writing files to disk.

B) Enable sparse-checkout

git sparse-checkout init

Explanation: Turns on sparse-checkout in “pattern” mode by default (we’ll cover --cone soon). It prepares your repo to show only selected paths.

To pick what you want to see:

git sparse-checkout set docs

Explanation: Shows only docs/ in your working tree. Everything else is hidden (but still in history).

Expected output (typical): Git will say it updated the working directory and write a sparse-checkout file.


3) Using Sparse-Checkout Without --cone (pattern mode)

What is pattern mode?

Pattern mode uses gitignore-like patterns. It’s very flexible: you can include/exclude individual files, use wildcards (*, **), and use negation (!).

Example: pick a folder and some files

git sparse-checkout set \
  "libs/utils/*" \
  "docs/" \
  "!docs/old/**"

Explanation:

  • libs/utils/* → include all files inside libs/utils/ (but not other parts of libs/).
  • docs/ → include the whole docs folder.
  • !docs/old/** → exclude everything under docs/old/ even though docs/ is included.

Another example: single files

git sparse-checkout set \
  "app/Makefile" \
  "tools/build.sh"

Explanation: You can target individual files in pattern mode.

Pattern syntax quick notes

  • dir/ includes that folder.
  • foo/* matches direct children only.
  • ** matches any depth (e.g., docs/**).
  • !pattern excludes something that would otherwise be included.
  • You can mix many lines to describe exactly what you want.

Pros (pattern mode):

  • Very flexible (files, wildcards, negation).
  • Good when you need surgical control.

Cons:

  • More complex to write and maintain.
  • Can be slower on huge repos (patterns are more work for Git).



4) Using Sparse-Checkout With --cone (cone mode)

What is cone mode?

Cone mode is a simpler, folder-based way to use sparse-checkout. You don’t write complex patterns. You just list the top-level directories (and subdirectories) you want.

Why it was introduced:

To make sparse-checkout easy and fast for the most common case: “I want these folders.”

Enable cone mode

git sparse-checkout init --cone
git sparse-checkout set src docs

Explanation:

  • --cone switches to directory-based matching.
  • set src docs shows src/ and docs/ (recursively) in your working tree.

Key rule in cone mode

  • Only directories (no file-level patterns, no wildcards).
  • You list directories you want; Git includes them recursively.

Example: monorepo packages

git sparse-checkout set packages/app-a packages/app-b

Explanation: Shows only those two package directories.

Everyday tasks become simple

  • Add another folder:

    git sparse-checkout add tests
    
  • Replace the set entirely:

    git sparse-checkout set tools
    

Benefits (cone mode):

  • Much simpler commands.
  • Usually faster on large repos.
  • Pairs nicely with partial clone (--filter=blob:none) for big speedups.
  • Works well with sparse-index (Git can treat skipped folders more efficiently).

Trade-off:

  • You can’t pick single files or write fancy include/exclude patterns. It’s directory-only.



5) Comparison: Cone vs. Non-Cone

Aspect Cone mode (--cone) Non-cone (pattern mode)
Syntax Directory names only Full gitignore-style patterns
Wildcards (*, **) Not supported Supported
Include/exclude single files No Yes (file, !file)
Ease of use Very simple More complex
Typical performance on large repos Faster Slower (patterns cost more)
Best for Monorepos, folder-based work Advanced “surgical” selection

Recommendation:

  • Use cone mode for 90% of cases (choose folders, be productive, go fast).
  • Use pattern mode only when you really need file-level control or complex wildcards/negations.



6) Common Use Cases

A) Working in a monorepo (cone mode)

git clone --filter=blob:none --no-checkout https://example.com/mono.git
cd mono
git sparse-checkout init --cone
git sparse-checkout set packages/app-a docs

Explanation: You get just packages/app-a and docs. Builds and searches are quicker.

B) Pull only a subdirectory to test something (cone mode)

git sparse-checkout set tests/integration

Explanation: Quickly switch your focus to integration tests only.

C) Documentation-only checkout (cone mode)

git sparse-checkout set docs

Explanation: Great for writing docs without pulling the whole repo.

D) Advanced selection (pattern mode)

git sparse-checkout set \
  "libs/**" \
  "!libs/legacy/**" \
  "tools/build.*" \
  "README.md"

Explanation: Include all of libs/ except libs/legacy/, plus build scripts and README.md.

E) Switching between sets

  • Replace the current set (cone or pattern):

    git sparse-checkout set src
    
  • Add to the current set:

    git sparse-checkout add docs
    
  • See what’s active:

    git sparse-checkout list
    



7) Troubleshooting Tips

See current sparse paths

git sparse-checkout list

Explanation: Shows which directories/patterns are active.

Reset your choices (keep sparse on)

git sparse-checkout set

Explanation: With no args, it clears the set; you can then add again.

Disable sparse-checkout (back to full repo)

git sparse-checkout disable

Explanation: Turns sparse-checkout off and checks out everything.

Re-apply after changing branches or config

git sparse-checkout reapply

Explanation: Re-applies your sparse rules if the working tree got out of sync.

Common error: “not a sparse checkout” Run git sparse-checkout init first, then set/add.

Tip for speed on big repos Combine partial clone and cone mode:

git clone --filter=blob:none --no-checkout https://example.com/big.git
cd big
git sparse-checkout init --cone
git sparse-checkout set src docs

8) Conclusion

  • Sparse-checkout helps you work faster by showing only the parts of a repo you need.
  • Cone mode (--cone) is the simple and fast choice for directory-based work.
  • Pattern mode is powerful when you need fine control (wildcards, negation, single files), but it’s more complex and can be slower.

Quick summary table

Use this when… Choose
“I just want these folders.” Cone mode (git sparse-checkout init --cone)
“I need specific files or complex rules.” Pattern mode (no --cone)



Mini “Cheat Sheet”

# Turn on sparse-checkout (cone mode)
git sparse-checkout init --cone

# Show only these folders
git sparse-checkout set src docs

# Add another folder without replacing
git sparse-checkout add tests

# List what’s active
git sparse-checkout list

# Switch to a different set
git sparse-checkout set tools

# Turn off sparse-checkout (full checkout)
git sparse-checkout disable

Explanation: These are the commands you’ll use most of the time.