fix(watcher): ignore callbacks from replaced git-common watches

This commit is contained in:
Brennan Benson
2026-07-16 17:15:00 -07:00
parent ed5ffab439
commit 15ab42c6e8
2 changed files with 15 additions and 2 deletions
@@ -128,6 +128,17 @@ describe('worktree git-common narrow watch (darwin)', () => {
await vi.waitFor(() => {
expect(subscribeMock).toHaveBeenCalledTimes(2)
})
const receivedAfterRearm = received.length
childSubscriptions[0].callback(new Error('late error from replaced watcher'), [])
childSubscriptions[0].callback(null, [
{ type: 'create', path: join(worktreesDir, 'late-old-event') }
])
childSubscriptions[0].hooks.onInterruption?.()
// A replaced watch cannot tear down its successor or report stale events.
expect(received).toHaveLength(receivedAfterRearm)
expect(childSubscriptions[1].unsubscribe).not.toHaveBeenCalled()
})
it('reports a structural change after a watcher-child interruption', async () => {
+4 -2
View File
@@ -162,12 +162,14 @@ async function startGitCommonNarrowWatch(
return false
}
let errored = false
let active = true
// Why: parcel tears its native stream down when the watched root is
// deleted (e.g. `git worktree prune` removing an empty worktrees dir) —
// sometimes surfaced as an error, sometimes as a delete event for the
// root. Either way: notify, drop the dead stream, and let the existence
// poll re-arm when a future worktree add recreates the dir.
const teardownAndRearm = (): void => {
active = false
errored = true
const current = subscription
subscription = null
@@ -180,7 +182,7 @@ async function startGitCommonNarrowWatch(
const sub = await subscribeViaWatcherProcess(
worktreesDir,
(error, events) => {
if (disposed) {
if (disposed || !active) {
return
}
if (error) {
@@ -203,7 +205,7 @@ async function startGitCommonNarrowWatch(
// Why: a watcher-child crash drops events during the automatic
// resubscribe gap; report a structural change so worktrees re-sync.
onInterruption: () => {
if (!disposed) {
if (!disposed && active) {
onEvents([{ type: 'update', path: worktreesDir }])
}
}