Improve git worktree operation lock robustness

- Refactor async path resolution to be explicit and reliable
- Add test guard ensuring release function is available before use
This commit is contained in:
Jinjing
2026-09-02 21:18:08 -07:00
parent 4bd0ee6ee2
commit 033f33bc07
2 changed files with 7 additions and 4 deletions
@@ -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 })
+6 -4
View File
@@ -8,9 +8,11 @@ export async function runWithGitWorktreeOperationLock<T>(
signal: AbortSignal | undefined,
run: () => Promise<T>
): Promise<T> {
// 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)
}