From 7cf0c2a5e23a2beddd2280f523b3a4e57c5ea2c2 Mon Sep 17 00:00:00 2001 From: OrcaWin Date: Thu, 15 Oct 2026 23:26:38 -0700 Subject: [PATCH] test: prove HEAD rename detection on the first polling tick (#29478) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> --- .../ipc/worktree-git-common-polling.test.ts | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/main/ipc/worktree-git-common-polling.test.ts b/src/main/ipc/worktree-git-common-polling.test.ts index 179b73e2c33..7a7aa1035ff 100644 --- a/src/main/ipc/worktree-git-common-polling.test.ts +++ b/src/main/ipc/worktree-git-common-polling.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { mkdir, mkdtemp, rename, rm, writeFile } from 'node:fs/promises' +import { mkdir, mkdtemp, rename, rm, utimes, writeFile } from 'node:fs/promises' import type * as NodeFsPromises from 'node:fs/promises' import { tmpdir } from 'node:os' import { join, sep } from 'node:path' @@ -145,32 +145,29 @@ describe('startGitCommonPolling fan-out bounds (#17828)', () => { it('detects a HEAD rewrite via lock+rename on the next tick', async () => { const commonDir = await makeCommonDir(1) dirsToRemove.push(commonDir) - const events: WorktreeBasePollEvent[][] = [] + const entryDir = join(commonDir, 'worktrees', 'wt-0') + // Ensure rename changes the directory signature even on coarse-mtime filesystems. + await utimes(entryDir, new Date(0), new Date(0)) + const received = Promise.withResolvers() const pollIntervalMs = 20 + vi.useFakeTimers() const sub = await startGitCommonPolling( commonDir, - (batch) => events.push(batch), + received.resolve, pollIntervalMs, alwaysVisible ) cleanups.push(() => sub.unsubscribe()) - // Let the bootstrap snapshot settle before mutating. - await new Promise((resolve) => setTimeout(resolve, pollIntervalMs)) - const entryDir = join(commonDir, 'worktrees', 'wt-0') const headPath = join(entryDir, 'HEAD') const headLockPath = join(entryDir, 'HEAD.lock') - // Every real git ref write goes through a lock file + rename inside the entry - // dir (never an in-place overwrite), which moves the entry dir's own signature. await writeFile(headLockPath, 'ref: refs/heads/feature\n') await rename(headLockPath, headPath) - await vi.waitFor( - () => { - expect(events.flat()).toContainEqual({ type: 'update', path: headPath }) - }, - { timeout: pollIntervalMs * 10 } - ) + readdirCalls.count = 0 + await vi.advanceTimersByTimeAsync(pollIntervalMs) + expect(await received.promise).toContainEqual({ type: 'update', path: headPath }) + expect(readdirCalls.count).toBe(1) }) it('detects an in-place gitdir rewrite only once the periodic backstop rescans it', async () => {