fix(server): keep large sparse checkouts on the fast checkpoint path#12154
2 unresolved threads · Jump to file
apps/server/src/vcs/GitVcsDriver.ts · Earlier revision c9f15114 · right 825
Original diff
@@ -789,26 +802,62 @@ export const makeVcsDriverShape = Effect.fn("makeGitVcsDriverShape")(function* (
yield* execute({
operation,
cwd: input.cwd,
- args: ["-c", "core.fsmonitor=false", "read-tree", "--reset", "HEAD"],
+ args: [...indexConfig, "read-tree", "--reset", "HEAD"],
env: commitEnv,
});
// read-tree can rewrite the index, so restore its racy timestamp afterward.
yield* fileSystem.utimes(tempIndexPath, indexTime, indexTime);
- const entries = yield* execute({
+ let specialFlags = false;
+ let recordStart = true;
+ yield* vcsProcess.run({
operation,
+ command: "git",
cwd: input.cwd,
- args: ["ls-files", "-v"],
+ args: [...indexConfig, "ls-files", "--sparse", "-v", "-z"],
env: commitEnv,
- maxOutputBytes: WORKSPACE_FILES_MAX_OUTPUT_BYTES,
+ maxOutputBytes: 4_096,
+ outputMode: "truncate",
+ // Inspect every tag without retaining paths or stopping at the output cap.
+ onStdoutChunk: (chunk) => {
+ for (const byte of chunk) {
+ if (
+ recordStart &&
+ ((byte >= 97 && byte <= 122) || (!sparseCheckout && byte === 83))P2 Badge Reset manual skip-worktree entries in sparse checkouts
When a sparse checkout also has a manually skip-worktree path inside the selected cone and that file is deleted, this condition treats its S record as an ordinary sparse exclusion. I reproduced this with git sparse-checkout set --cone included, git update-index --skip-worktree included/manual, and then deleting the file: git ls-files --sparse -v still reports S included/manual, while git add --sparse -A—whose -h text only says it permits updating entries outside the sparse-checkout cone—leaves the file in write-tree. The checkpoint therefore silently retains the deleted file and can resurrect it during restore; distinguish sparse-derived S entries from manual flags or reset the latter before reusing the index.
AGENTS.md reference: AGENTS.md:L145-L145
Useful? React with 👍 / 👎.
Confirmed and fixed in 13c26084e. Added the reported manual skip-worktree deletion to the root and nested two-capture regressions; both failed before the fix. Capture now checks skipped file paths against Git sparse-checkout check-rules and falls back if a skipped file is inside the selected rules. Collapsed sparse directories do not need that extra check. The 460,000-file synthetic benchmark still shows about 4x faster captures.
apps/server/src/vcs/GitVcsDriver.ts · Earlier revision c9f15114 · right 870
Original diff
@@ -817,14 +866,15 @@ export const makeVcsDriverShape = Effect.fn("makeGitVcsDriverShape")(function* (
yield* execute({
operation,
cwd: input.cwd,
- args: ["add", "-A", "--", "."],
+ // Preserve absent skipped entries, but capture present nonignored files outside the cone.
+ args: [...indexConfig, "add", ...(sparseCheckout ? ["--sparse"] : []), "-A", "--", "."],P2 Badge Fall back when Git predates add --sparse
git add --sparse is unavailable in Git 2.25 even though that release supports git sparse-checkout; its git-add help does not list the option, while current help describes it as allowing updates outside the sparse-checkout cone. On such server or remote environments, the preceding unsupported ls-files --sparse invocation merely selects the fallback path, but this uncaught command then exits with unknown option 'sparse', so every sparse-checkout checkpoint fails. Since docs/user/source-control.md:8 requires Git without declaring a newer minimum, feature-detect this option or retain a compatible staging path.
AGENTS.md reference: AGENTS.md:L145-L145
Useful? React with 👍 / 👎.
Confirmed and fixed in 13c26084e. Capture checks whether git add supports --sparse and retains the previous capture path if it does not. Added a regression that rejects unsupported sparse options. I also built Git 2.25.0 locally and ran a synthetic sparse-workspace capture through the driver: the edit was captured and the real index stayed byte-identical. This preserves compatibility with the old path; it does not backport modern sparse-index semantics to Git 2.25.