From 19f941c3fc595289bc9d1bbcc35dfc43d2ad22e4 Mon Sep 17 00:00:00 2001 From: Josh Crites Date: Mon, 2 Mar 2026 16:21:33 -0500 Subject: [PATCH] fix: disable gc.auto after blobless clones to prevent race condition Blobless clones with sparsePathOverrides trigger on-demand blob fetches, each of which runs `git gc --auto`. Concurrent gc processes collide with "unable to write new index file" errors. Setting gc.auto=0 right after clone prevents this. Safe for read-only clones used only for code search. Co-Authored-By: Claude Opus 4.6 --- src/utils/git.ts | 3 +++ tests/utils/git.test.ts | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/utils/git.ts b/src/utils/git.ts index 7d10117..3cc7c13 100644 --- a/src/utils/git.ts +++ b/src/utils/git.ts @@ -76,6 +76,7 @@ export async function cloneRepo( ]); const repoGit = simpleGit(repoPath); + await repoGit.raw(["config", "gc.auto", "0"]); await repoGit.raw(["sparse-checkout", "set", ...config.sparse]); await repoGit.fetch(["origin", config.commit]); await repoGit.checkout(config.commit); @@ -87,6 +88,7 @@ export async function cloneRepo( ]); const repoGit = simpleGit(repoPath); + await repoGit.raw(["config", "gc.auto", "0"]); await repoGit.raw(["sparse-checkout", "set", ...config.sparse]); await repoGit.fetch(["--depth=1", "origin", `refs/tags/${config.tag}:refs/tags/${config.tag}`]); await repoGit.checkout(config.tag); @@ -117,6 +119,7 @@ export async function cloneRepo( ]); const repoGit = simpleGit(repoPath); + await repoGit.raw(["config", "gc.auto", "0"]); await repoGit.raw(["sparse-checkout", "set", ...config.sparse]); } diff --git a/tests/utils/git.test.ts b/tests/utils/git.test.ts index 8b79f89..4f5175f 100644 --- a/tests/utils/git.test.ts +++ b/tests/utils/git.test.ts @@ -132,6 +132,7 @@ describe("cloneRepo", () => { expect.stringContaining("aztec-packages"), expect.arrayContaining(["--filter=blob:none", "--sparse", "--no-checkout"]) ); + expect(mockGitInstance.raw).toHaveBeenCalledWith(["config", "gc.auto", "0"]); expect(mockGitInstance.raw).toHaveBeenCalledWith([ "sparse-checkout", "set", @@ -240,6 +241,7 @@ describe("cloneRepo", () => { expect.any(String), expect.arrayContaining(["--filter=blob:none", "--sparse", "--no-checkout"]) ); + expect(mockGitInstance.raw).toHaveBeenCalledWith(["config", "gc.auto", "0"]); expect(mockGitInstance.fetch).toHaveBeenCalledWith(["origin", "abc123def"]); expect(mockGitInstance.checkout).toHaveBeenCalledWith("abc123def"); }); @@ -256,6 +258,7 @@ describe("cloneRepo", () => { expect.any(String), expect.arrayContaining(["--filter=blob:none", "--sparse", "--depth=1", "-b", "master"]) ); + expect(mockGitInstance.raw).toHaveBeenCalledWith(["config", "gc.auto", "0"]); }); it("non-sparse + tag: clones without sparse-checkout", async () => {