Skip to content

Commit 95030dc

Browse files
t3dotggclaude
andauthored
fix(server): background git status fetches no longer fill the disk with failed repacks (#13812)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 295d7cb commit 95030dc

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

‎apps/server/src/vcs/GitVcsDriverCore.test.ts‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,6 +1918,35 @@ it.layer(TestLayer)("GitVcsDriver core integration", (it) => {
19181918
}),
19191919
);
19201920

1921+
it.effect("does not start Git auto-maintenance from background upstream fetches", () =>
1922+
Effect.gen(function* () {
1923+
const cwd = yield* makeTmpDir();
1924+
const remote = yield* makeTmpDir("git-vcs-driver-remote-");
1925+
const { initialBranch } = yield* initRepoWithCommit(cwd);
1926+
yield* git(remote, ["init", "--bare"]);
1927+
yield* git(cwd, ["remote", "add", "origin", remote]);
1928+
yield* git(cwd, ["push", "-u", "origin", initialBranch]);
1929+
yield* git(cwd, ["repack", "-d"]);
1930+
yield* writeTextFile(cwd, "second.txt", "second\n");
1931+
yield* git(cwd, ["add", "second.txt"]);
1932+
yield* git(cwd, ["commit", "-m", "second commit"]);
1933+
yield* git(cwd, ["push"]);
1934+
yield* git(cwd, ["repack", "-d"]);
1935+
// Two packs make `git gc --auto` due, and without detaching it would run inside the fetch.
1936+
yield* git(cwd, ["config", "gc.autoPackLimit", "1"]);
1937+
yield* git(cwd, ["config", "gc.autoDetach", "false"]);
1938+
yield* git(cwd, ["config", "maintenance.autoDetach", "false"]);
1939+
const packCount = git(cwd, ["count-objects", "-v"]).pipe(
1940+
Effect.map((stdout) => stdout.match(/^packs: (\d+)$/m)?.[1]),
1941+
);
1942+
assert.equal(yield* packCount, "2");
1943+
1944+
yield* (yield* GitVcsDriver.GitVcsDriver).statusDetailsRemote(cwd);
1945+
1946+
assert.equal(yield* packCount, "2");
1947+
}),
1948+
);
1949+
19211950
it.effect("uses origin HEAD for default-branch detection with a non-origin upstream", () =>
19221951
Effect.gen(function* () {
19231952
const cwd = yield* makeTmpDir();

‎apps/server/src/vcs/GitVcsDriverCore.ts‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1127,10 +1127,14 @@ export const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function*
11271127
): Effect.Effect<void, GitCommandError> => {
11281128
const fetchCwd =
11291129
path.basename(gitCommonDir) === ".git" ? path.dirname(gitCommonDir) : gitCommonDir;
1130+
// `--no-auto-gc` (a synonym of `--no-auto-maintenance` that older Git also knows) keeps
1131+
// this poll from starting `git gc --auto`. When that gc fails, for example on a repository
1132+
// with missing objects, Git retries it on every fetch and leaves a full-size `tmp_pack_*`
1133+
// behind each time, so a background poll could fill the disk.
11301134
return executeGit(
11311135
"GitVcsDriver.fetchRemoteForStatus",
11321136
fetchCwd,
1133-
["--git-dir", gitCommonDir, "fetch", "--quiet", "--no-tags", remoteName],
1137+
["--git-dir", gitCommonDir, "fetch", "--quiet", "--no-tags", "--no-auto-gc", remoteName],
11341138
{
11351139
env: STATUS_UPSTREAM_REFRESH_ENV,
11361140
fallbackErrorDetail: "Background Git fetch exited with a non-zero status.",

0 commit comments

Comments
 (0)