Repository navigation
Checkpoint index reuse falls back on large sparse checkouts and still fails after #10792 #12080
Description
Activity
Triage: real server checkpoint bug. Confirmed on current
mainand on your0.0.41-nightly.20260916.1795(both include #10792). Shipping0.0.42does not include #10792 and is worse (always takes the fresh-index path). Not fixed by #10792, and not a wash of #3646.What you hit. On a large cone-mode sparse checkout, capture copies the index, runs
read-tree --reset HEAD, then inspectsgit ls-files -v. Reuse only runs when that listing is under 16 MiB and has no assume-unchanged / skip-worktree flags (!entries.stdoutTruncated && !/^[a-zS] /m.test(...)). Your probe had ~40 MiB of listing and ~212kSentries — reuse rejected twice. Fallbackread-tree HEADleft every entryH, thengit add -A -- .hit the unchanged 30s deadline (31.1s). With a longer timeout the sameaddexits 1 because untracked files exist outside the sparse cone.Why #10792 does not save this. That PR intentionally falls back when
S/ lowercase flags remain or the listing is truncated — it was protecting manualupdate-index --skip-worktree/ assume-unchanged. Cone-mode sparse-checkout is thoseSbits. So sparse monorepos never reuse, and the fallback expands the full tree.The add is also wrong, not just slow.
git add -A -- .exits 1 on outside-cone untracked paths (reproduced on current Git for both workspace and fallback temp indexes). Raising the timeout alone would not make capture succeed while those artifacts exist. Fallback without reapplying skip-worktree is also semantically wrong: excluded paths become liveHentries and can look like deletions. Open #11665 only retries transient exit failures (not timeouts) and would not fix this sparse-path exit.Related, not duplicates. #3646 is the umbrella large-repo 30s
add -Atimeout. #10792 is the partial reuse optimization that correctly opts out of this shape. #11665 is exit retries only. No open PR teaches capture about sparse-checkout.Suggested fix (in
GitVcsDriver.checkpoints.captureCheckpoint). Detect sparse-checkout and keep / reuse skip-worktree (thoseSflags are the cone). Stop dumping a 40 MiBls-files -vto decide reuse. Makegit addsparse-safe (in-cone pathspecs or reapply sparse on the temp index; do not fail capture on outside-cone untracked warnings). If fallback still runs, reapply skip-worktree beforeadd. Tests: cone-mode + sparse index + outside-cone untracked + in-cone edit; capture under 30s; workspace index unchanged; tree has the in-cone change and not 211k excluded deletions.Workaround. None in-app. Removing the six outside-cone files would only expose the 30s fallback timeout; reuse would still be rejected. Disabling sparse-checkout is not realistic here. Do not treat “update to 0.0.42”, “bump the timeout”, or “land #11665” as closing this.
- addedbugSomething is broken or behaving incorrectly.Something is broken or behaving incorrectly.acceptedfeature request acceptedfeature request acceptedvia-triageFiled through npx t3 triageFiled through npx t3 triage
on Sep 16, 2026 Opened #12154 to address this. It preserves sparse-checkout index reuse, removes the listing-size cutoff from the reuse decision, and handles files outside the sparse rules. Synthetic regression tests and benchmarks are in the PR.
What happened
T3 Code's Windows desktop app with a WSL2 backend repeatedly fails to capture checkpoints in a large sparse-checkout monorepo. The failure persists after updating to a nightly containing #10792:
Diagnosis
I reproduced the installed backend's checkpoint preparation using a temporary index and isolated Git object storage.
After copying the real index and running:
the temporary index contained:
skip-worktreeentries.git ls-files -voutput.The merged optimization accepts index reuse only when the output is not truncated and contains no special flags:
The inspection limit is 16,777,216 bytes. Both the listing size and the surviving
skip-worktreeflags reject reuse in this reproduction.The fallback's
git read-tree HEADthen left all 458,319 entries markedH. The followinggit add -A -- .took 31.1 seconds, exceeding T3's unchanged 30-second deadline.With a longer diagnostic timeout, that command finished with exit code 1 because six untracked files existed outside the sparse-checkout definition. A longer timeout alone would therefore not make checkpoint capture succeed in this checkout's current state.
Steps to reproduce
The diagnostic reproduction followed the installed backend's index-copy, reset, inspection, fallback, and add sequence. This is an existing private-repository reproduction, not a minimal public fixture.
Version
0.0.41-nightly.20260916.1795, containing #10792.Environment
6.6.114.1-microsoft-standard-WSL2.2.52.0.vfs.0.5.Evidence
Redacted Git error:
Ordinary status previously completed in 0.173 seconds for tracked changes and 1.884 seconds including untracked files.
The real index remained byte-for-byte unchanged throughout the diagnostic probe.
Related issues
Related to #3646 and its fix #10792. This report isolates the confirmed index-reuse fallback on a large sparse checkout and the sparse-path error revealed when
git addis allowed to finish.Fix applied or workaround
None. The investigation used temporary index and object storage without changing working files or the real staging area.
Filed by
OpenCode, model
github-copilot/gpt-6-astra, following thet3 triageplaybook.