mirror of
https://github.com/stablyai/orca.git
synced 2026-09-29 16:02:50 +00:00
Sequence git worktree operations to preserve stage/commit order
Back-to-back operations (stage, then commit) must execute in call order. Use an order key to sequence them synchronously while keeping realpath async to avoid blocking on hung network paths (9P/UNC lookups).
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { realpathSync } from 'node:fs'
|
||||
import { realpath } from 'node:fs/promises'
|
||||
import { resolve } from 'node:path'
|
||||
import { runWithGitOperationLock } from './git-operation-lock'
|
||||
|
||||
@@ -8,13 +8,17 @@ export async function runWithGitWorktreeOperationLock<T>(
|
||||
signal: AbortSignal | undefined,
|
||||
run: () => Promise<T>
|
||||
): Promise<T> {
|
||||
// Why: the key must resolve synchronously so back-to-back callers (stage, then commit)
|
||||
// join the lane in call order. An async realpath is not ordered and can run a commit first.
|
||||
let key = resolve(worktreePath)
|
||||
try {
|
||||
key = realpathSync.native(worktreePath) || key
|
||||
} catch {
|
||||
// A missing or temporarily unreachable worktree still gets serialized.
|
||||
}
|
||||
return runWithGitOperationLock(key, signal, run)
|
||||
const fallbackKey = resolve(worktreePath)
|
||||
// Why: back-to-back callers (stage, then commit) must join the canonical lane in call order.
|
||||
// realpath is async and unordered, so sequence it under a lane keyed by the raw path, which
|
||||
// needs no I/O. realpath stays async because a hung 9P/UNC lookup must not block the process.
|
||||
return runWithGitOperationLock(`order\0${fallbackKey}`, signal, async () => {
|
||||
let key = fallbackKey
|
||||
try {
|
||||
key = (await realpath(worktreePath)) || fallbackKey
|
||||
} catch {
|
||||
// A missing or temporarily unreachable worktree still gets serialized.
|
||||
}
|
||||
return runWithGitOperationLock(key, signal, run)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user