claude-code - 💡(How to fix) Fix [BUG] git-subdir plugin install leaks sparse-checkout into the session's working repo, silently collapsing the tree

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Installing or refreshing a plugin whose marketplace source is git-subdir runs git sparse-checkout set --cone <path> that is not scoped to its temp clone — it also applies to the git repository at the session's current working directory. That sets core.sparseCheckout=true plus a cone pattern for the plugin's subpath (e.g. providers/claude/plugin) on the user's own project worktree, so every file outside that (nonexistent-in-this-repo) path silently disappears from the working tree. No error is shown.

Error Message

Installing or refreshing a plugin whose marketplace source is git-subdir runs git sparse-checkout set --cone <path> that is not scoped to its temp clone — it also applies to the git repository at the session's current working directory. That sets core.sparseCheckout=true plus a cone pattern for the plugin's subpath (e.g. providers/claude/plugin) on the user's own project worktree, so every file outside that (nonexistent-in-this-repo) path silently disappears from the working tree. No error is shown.

Root Cause

  • The user's working tree collapses — src/, .claude/, etc. vanish, with exit-0 git behavior. It looks like data loss / a broken checkout.
  • While sparse-checkout is active, a plain git add <path> silently refuses to stage paths outside the cone (it's only a hint, exit stays 0), so a subsequent git commit --amend / push can ship incomplete content without warning.
  • Hits multi-worktree tooling (Conductor, plain git worktree) hardest, because the session cwd is a real repo. It recurs on every marketplace re-sync.

Fix Action

Workaround

In the affected repo:

git sparse-checkout disable
rm -f "$(git rev-parse --git-dir)/info/sparse-checkout"

Recurs on the next marketplace refresh until fixed.

Code Example

{"source":"git-subdir","url":"https://github.com/stripe/ai.git","path":"providers/claude/plugin","ref":"main","sha":"a34795211da530a168f581122011bb5ceb2e4bd0"}

---

git sparse-checkout disable
rm -f "$(git rev-parse --git-dir)/info/sparse-checkout"
RAW_BUFFERClick to expand / collapse

Summary

Installing or refreshing a plugin whose marketplace source is git-subdir runs git sparse-checkout set --cone <path> that is not scoped to its temp clone — it also applies to the git repository at the session's current working directory. That sets core.sparseCheckout=true plus a cone pattern for the plugin's subpath (e.g. providers/claude/plugin) on the user's own project worktree, so every file outside that (nonexistent-in-this-repo) path silently disappears from the working tree. No error is shown.

Impact

  • The user's working tree collapses — src/, .claude/, etc. vanish, with exit-0 git behavior. It looks like data loss / a broken checkout.
  • While sparse-checkout is active, a plain git add <path> silently refuses to stage paths outside the cone (it's only a hint, exit stays 0), so a subsequent git commit --amend / push can ship incomplete content without warning.
  • Hits multi-worktree tooling (Conductor, plain git worktree) hardest, because the session cwd is a real repo. It recurs on every marketplace re-sync.

Environment

  • Claude Code v2.1.156
  • macOS 26.3.1 (Darwin 25.3.0), Apple Silicon
  • Trigger plugin: stripe@claude-plugins-official, source:
    {"source":"git-subdir","url":"https://github.com/stripe/ai.git","path":"providers/claude/plugin","ref":"main","sha":"a34795211da530a168f581122011bb5ceb2e4bd0"}
  • Sessions running inside Conductor-managed git worktrees of an unrelated project.

Reproduction

  1. Open a project in Claude Code where the working directory is a git repo / worktree.
  2. Install (or let the official marketplace auto-refresh) a plugin with a git-subdir source that points at a subpath of an external monorepo — e.g. stripe@claude-plugins-official (github.com/stripe/aiproviders/claude/plugin).
  3. Inspect the project repo (not the plugin cache):
    • git config core.sparseCheckouttrue
    • <git-dir>/info/sparse-checkout now contains a cone pattern for providers/claude/plugin — a path that does not exist in the project.
  4. All files outside that path are gone from the working tree.

Evidence

  • The polluting <project-worktree>/.git/.../info/sparse-checkout is byte-identical to the plugin's temp clone at ~/.claude/plugins/cache/temp_subdir_*.clone/.git/info/sparse-checkout — i.e. the same git sparse-checkout operation wrote both.
  • Only repositories that were the session cwd during a git-subdir install/refresh are affected. The plugin's own temp clone is correct. Other source types never touch sparse-checkout and never leak:
    • source: "./plugins/<name>" (a subfolder of the already-cloned marketplace repo) → no fetch, no sparse.
    • whole-repo github/url sources → plain clone, no sparse.
  • Reproduced across three separate worktrees of the same project; never affected the non-Conductor main checkout (which wasn't a session cwd when a git-subdir install ran).

Root cause (inferred — harness is closed source)

The git-subdir fetch path's git sparse-checkout invocation runs against the inherited process working directory instead of being confined to the temp clone directory.

Suggested fix

Scope every git operation in the git-subdir fetch to the temp clone directory — e.g. git -C <tempCloneDir> sparse-checkout … (or set the child process cwd to the temp dir) — so a plugin install can never mutate the user's working repository. Optionally assert the target repo is the temp dir before running sparse-checkout.

Workaround

In the affected repo:

git sparse-checkout disable
rm -f "$(git rev-parse --git-dir)/info/sparse-checkout"

Recurs on the next marketplace refresh until fixed.

Related

  • #58199 — git-subdir install creates an empty destination directory. Same install path, different symptom; suggests this code path is fragile.
  • #40864 / #28426 — the "use sparse checkout for plugin installs" feature this mis-scopes.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] git-subdir plugin install leaks sparse-checkout into the session's working repo, silently collapsing the tree