diff --git a/src/main/git/status-read-coalescing.test.ts b/src/main/git/status-read-coalescing.test.ts index e0170f8d6a5..fae95130915 100644 --- a/src/main/git/status-read-coalescing.test.ts +++ b/src/main/git/status-read-coalescing.test.ts @@ -364,6 +364,7 @@ describe('getStatus', () => { const mutation = stageFile('/repo', 'src/file.ts') const duringMutation = getStatus('/repo', { signal: new AbortController().signal }) await vi.waitFor(() => expect(statusCommandCalls).toBe(2)) + await vi.waitFor(() => expect(releaseMutation).toBeTypeOf('function')) releaseMutation() await mutation const afterMutation = getStatus('/repo', { signal: new AbortController().signal }) diff --git a/src/shared/git-worktree-operation-lock.ts b/src/shared/git-worktree-operation-lock.ts index f60fa782569..acaefa19bf8 100644 --- a/src/shared/git-worktree-operation-lock.ts +++ b/src/shared/git-worktree-operation-lock.ts @@ -8,9 +8,11 @@ export async function runWithGitWorktreeOperationLock( signal: AbortSignal | undefined, run: () => Promise ): Promise { - // Async so a hung filesystem cannot freeze the main-process event loop; the - // extra yield is harmless because reads never take this lock and the lane - // chain serializes mutations whatever order they acquire it in. - const key = await realpath(worktreePath).catch(() => resolve(worktreePath)) + const fallbackKey = resolve(worktreePath) + // Async so a hung filesystem cannot freeze the main-process event loop. + const key = await Promise.resolve() + .then(() => realpath(worktreePath)) + .then((canonicalPath) => canonicalPath ?? fallbackKey) + .catch(() => fallbackKey) return runWithGitOperationLock(key, signal, run) }