fix(core): retry snapshot capture when concurrent Git writes collide on Windows (#56190)

This commit is contained in:
Filip 2026-10-16 19:11:11 +02:00 • committed by GitHub
parent 0a03b4bc9c
commit bc5ebf00a4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -367,6 +367,22 @@ const layer = Layer.effect(
})
})
/**
* On Windows, Git exits non-zero instead of reusing a loose object that another process is finalizing at the
* same moment. Objects are content-addressed, so one of at most two retries finds that copy in place. Only a Git
* exit is retried, never a failure to start Git, and other platforms fail on the first attempt.
*/
const retryConcurrentObjectWrite = <A, R>(effect: Effect.Effect<A, OperationError, R>) =>
process.platform === "win32"
? effect.pipe(
Effect.retry({
times: 2,
schedule: Schedule.spaced("50 millis"),
while: (error) => error.cause === undefined,
}),
)
: effect
/**
* A new store is initialized in a temporary sibling directory and renamed into
* place, so processes racing to create the same store never observe or write a
@ -505,11 +521,13 @@ const layer = Layer.effect(
{ concurrency: 8 },
)).filter((item): item is RelativePath => item !== undefined)
if (added.length)
yield* repositoryOperation(
"refresh",
input.repository,
["update-index", "--add", "--remove", "--replace", "-z", "--stdin"],
{ stdin: [...added, ...embedded].join("\0") + "\0", index: input.index },
yield* retryConcurrentObjectWrite(
repositoryOperation(
"refresh",
input.repository,
["update-index", "--add", "--remove", "--replace", "-z", "--stdin"],
{ stdin: [...added, ...embedded].join("\0") + "\0", index: input.index },
),
)
return { skipped }
})
@ -561,7 +579,9 @@ const layer = Layer.effect(
})
const writeTree = Effect.fn("Git.tree.write")(function* (repository: Repository, index?: string) {
const tree = (yield* repositoryOperation("write_tree", repository, ["write-tree"], { index })).text.trim()
const tree = (yield* retryConcurrentObjectWrite(
repositoryOperation("write_tree", repository, ["write-tree"], { index }),
)).text.trim()
if (/^[0-9a-f]{40,64}$/.test(tree)) return TreeID.make(tree)
return yield* new OperationError({
operation: "write_tree",