Skip to content

test: share the temp-repo teardown fix across the git fixtures - #95

Merged
lbdremy merged 1 commit into
mainfrom
test/temp-repo-teardown-helper
Sep 9, 2026
Merged

test: share the temp-repo teardown fix across the git fixtures#95
lbdremy merged 1 commit into
mainfrom
test/temp-repo-teardown-helper

Conversation

@lbdremy

@lbdremy lbdremy commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Follow-up to the ENOTEMPTY flake fixed in completeRunArtifacts (merged in the previous PR). The same race was latent everywhere a test builds a real git repo in a temp dir.

The race

git commit — and receive-pack on the far side of a push — spawns a detached git maintenance run --auto --quiet. Confirmed under GIT_TRACE on git 2.41:

trace: run_command: git maintenance run --auto --quiet

That process can still be writing into .git when a test's teardown removes the tree. Node's recursive removal does not retry by default, so one entry appearing after its parent was enumerated fails the whole call with ENOTEMPTY. It is timing-dependent, which is why it surfaces on CI rather than locally.

The change

New tests/helpers/tempGit.ts holds both halves of the fix:

  • disableGitAutoMaintenance(repoDir) — sets maintenance.auto false and gc.auto 0, so no background process outlives the test.
  • removeTempDir(dir) — recursive removal with retries, covering any writer the config cannot reach (a clone made inside src/, say).

Applied to the nine fixtures that create git objects, plus tests/e2e/helpers/tempEnv.ts, which commits and so carried the race for every e2e test. Every repo each one builds is covered: working repos, bare remotes, and mid-test clones.

Deliberately not swept

Six files run git init and never commit — loadConfig, upgradeConfigSchema, initProject, cli/schemaUpgrade, repoRootedCli, loadConfigLayers. init creates no objects, so nothing spawns maintenance and there is no writer to race. Touching them would be churn, not a fix.

Verification

  • pnpm check:full green.
  • Reading the config back on a repo the helper touched gives maintenance.auto=false / gc.auto=0, so the suppression actually lands.

One caveat worth stating: I could not observe the spawn disappear inside vitestGIT_TRACE does not survive the worker env, so a control run with the helper call removed showed zero spawns too. The mechanism is confirmed by a standalone probe and the config is confirmed to apply, but that specific in-runner observation is missing.

🤖 Generated with Claude Code

https://claude.ai/code/session_0164hoKCjqGFeFQcPB66ThLn

Follow-up to the ENOTEMPTY flake fixed in completeRunArtifacts: the same
race — a detached `git maintenance run --auto` still writing into .git when
the teardown removes the tree — was latent everywhere a test builds a real
git repo in a temp dir.

Add tests/helpers/tempGit.ts with the two halves of that fix:
disableGitAutoMaintenance, so no background process outlives the test, and
removeTempDir, whose retries cover any writer the config cannot reach (a
clone made inside src/, say).

Applied to the nine fixtures that create git objects, plus the e2e tempEnv
helper, which commits and so carried the race for every e2e test. Every repo
each one builds is covered: working repos, bare remotes, and mid-test clones.

Not swept: six files (loadConfig, upgradeConfigSchema, initProject,
cli/schemaUpgrade, repoRootedCli, loadConfigLayers) run `git init` and never
commit. `init` creates no objects, so nothing spawns maintenance and there is
no writer to race — touching them would be churn, not a fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0164hoKCjqGFeFQcPB66ThLn
@lbdremy
lbdremy merged commit 1ba9bfe into main Sep 9, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant