diff --git a/gitnexus/src/core/git-staleness.ts b/gitnexus/src/core/git-staleness.ts index 933ab8bf95..c90cef85ea 100644 --- a/gitnexus/src/core/git-staleness.ts +++ b/gitnexus/src/core/git-staleness.ts @@ -54,6 +54,8 @@ export async function checkStalenessAsync( lastCommit: string, ): Promise { try { + // Note: promisified execFile captures stdout/stderr by default (no stdio option needed, + // unlike the sync variant which requires explicit stdio: ['pipe','pipe','pipe']). const { stdout } = await execFileAsync('git', ['rev-list', '--count', `${lastCommit}..HEAD`], { cwd: repoPath, encoding: 'utf-8', diff --git a/gitnexus/test/unit/calltool-dispatch.test.ts b/gitnexus/test/unit/calltool-dispatch.test.ts index aa422327be..e2409e5eab 100644 --- a/gitnexus/test/unit/calltool-dispatch.test.ts +++ b/gitnexus/test/unit/calltool-dispatch.test.ts @@ -48,6 +48,7 @@ vi.mock('../../src/storage/repo-manager.js', () => ({ // tests don't shell out to git. vi.mock('../../src/core/git-staleness.js', () => ({ checkStaleness: vi.fn().mockReturnValue({ isStale: false, commitsBehind: 0 }), + checkStalenessAsync: vi.fn().mockResolvedValue({ isStale: false, commitsBehind: 0 }), checkCwdMatch: vi.fn().mockResolvedValue({ match: 'none' }), })); diff --git a/gitnexus/test/unit/staleness.test.ts b/gitnexus/test/unit/staleness.test.ts index 79c65516b6..1645d99871 100644 --- a/gitnexus/test/unit/staleness.test.ts +++ b/gitnexus/test/unit/staleness.test.ts @@ -109,6 +109,12 @@ describe('checkStalenessAsync', () => { expect(result.commitsBehind).toBe(0); }); + it('fails open with invalid commit hash', async () => { + const result = await checkStalenessAsync(process.cwd(), 'not-a-real-commit-hash'); + expect(result.isStale).toBe(false); + expect(result.commitsBehind).toBe(0); + }); + it('parallel calls complete faster than sequential', async () => { let headCommit: string; try {