diff --git a/packages/context/src/core/git.service.test.ts b/packages/context/src/core/git.service.test.ts index ba1d9e0f..8ad74b22 100644 --- a/packages/context/src/core/git.service.test.ts +++ b/packages/context/src/core/git.service.test.ts @@ -1,4 +1,4 @@ -import { mkdtemp, realpath, rm, writeFile } from 'node:fs/promises'; +import { mkdtemp, readFile, realpath, rm, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; @@ -52,6 +52,13 @@ describe('GitService', () => { const after = await service.revParseHead(); expect(after).toBe(before); }); + + it('keeps git auto-maintenance attached for deterministic cleanup', async () => { + const config = await readFile(join(tempDir, '.git', 'config'), 'utf-8'); + + expect(config).toMatch(/\[gc]\n\s+autoDetach = false/); + expect(config).toMatch(/\[maintenance]\n\s+autoDetach = false/); + }); }); describe('commitFile `created` flag', () => { diff --git a/packages/context/src/core/git.service.ts b/packages/context/src/core/git.service.ts index 8d05a089..7db4863b 100644 --- a/packages/context/src/core/git.service.ts +++ b/packages/context/src/core/git.service.ts @@ -105,6 +105,12 @@ export class GitService { this.logger.log('Initialized git repository'); } + // Keep any auto-maintenance triggered by writes in-process. Detached maintenance can + // keep object-pack directories alive briefly after awaited git commands complete, + // which makes temp-project cleanup flaky in CI. + await this.git.addConfig('gc.autoDetach', 'false'); + await this.git.addConfig('maintenance.autoDetach', 'false'); + // Ensure HEAD always resolves to a commit so callers (e.g., the memory-agent squash flow) // can rely on `revParseHead()` returning a SHA. Idempotent: skip if HEAD already exists. const head = await this.revParseHead();