Skip to content

Worktree list safety sweep skips unchanged worktrees instead of re-reading all of them every 30s - #31253

Merged
nwparker merged 2 commits into
mainfrom
nwparker/worktree-sweep-cache
Oct 20, 2026
Merged

nwparker merged 2 commits into
mainfrom
nwparker/worktree-sweep-cache

Conversation

@nwparker

@nwparker nwparker commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​164 $\color{#cf222e}{\Huge{\mathbf{−}}}$​20 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​144
Prod 3 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​114 $\color{#cf222e}{\Huge{\mathbf{−}}}$​12 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​102

ELI5

Orca keeps a list of every git worktree of each repo so the sidebar notices worktrees being added or removed. As a safety net it re-reads every worktree's metadata every 30 seconds, and that re-read skipped its own cache, so it read seven small files per worktree every time even when nothing had changed. On a repo with ~1,740 worktrees (many of them agent worktrees) that was about 12,000 file reads every 30 seconds. This PR lets the safety net use the cache.

What Changed

  • The 30-second sweep uses the per-worktree cache. An unchanged worktree is skipped based on its .git/worktrees/<name> folder's change time.
  • Files git rewrites in place are still checked every sweep. gitdir and logs/HEAD change without updating the folder's change time, so they are checked directly; if either changed, that worktree is fully re-read. (HEAD, config.worktree and index are written by rename and locked is only created or deleted, so the folder check covers them; verified against git 2.25 and 2.55 source.)
  • A full re-read of every worktree still runs every ~5 minutes (every 10th sweep) instead of every 30 seconds.
  • Automatic fallback. On file systems where a folder's change time doesn't move when files inside change, a re-read finds changes the cache missed; after misses on two separate sweeps, that repo goes back to full sweeps every time. A miss only counts if the folder still looks unchanged after the re-read, so a git rename landing mid-sweep doesn't trigger it.

Per sweep at 1,740 worktrees: about 12,180 file checks before; about 5,220 on a normal sweep after (3 per worktree), with the full ~12,180 every 10th sweep — about 5,900 on average.

Why

The full re-read every 30 seconds was a backstop for missed watch events, not something the sidebar needs at that rate. The cache it bypassed already existed; the gaps it has (in-place writes, file systems with unreliable folder change times) are covered explicitly instead of by re-reading everything. The 2-second fallback poller, the native watch, notifications and anything remote are unchanged. This code runs only in the local main process; SSH hosts don't use it.

Linked Issue

N/A (found while investigating high fseventsd and Orca activity on a machine with many agent worktrees).

Visual Proof

N/A: no visible change.

Testing

  • pnpm test src/main/ipc/worktree: 74 files / 868 tests pass. New tests: an unchanged worktree costs 3 checks per sweep; in-place gitdir/logs/HEAD changes are caught on the next sweep; the full sweep still runs periodically; the fallback triggers from a re-read set off by the in-place checks; a HEAD rename racing the scan (three times) does not trigger it; add/remove of worktrees is detected in both modes. Disabling each fix makes its test fail.

  • pnpm tc, pnpm run check:code-quality:changed, oxfmt --check pass.

  • Reviewed by GPT, including two rounds on the fallback detector.

  • Not manually tested in the app; macOS only.

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

AI Disclosure

Review

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

Ensure no issues in: Security, Cross-platoform support (Linux, Windows, Mac), Remote SSH, Mobile, general backwards compatibility, performance

Windows, Linux and network file systems with unreliable folder change times fall back to the previous full-sweep behaviour automatically.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

nwparker and others added 2 commits October 20, 2026 15:40
… entry's dir signature

The native-watch reconciliation forced an ungated stat of every leaf of every
worktree admin entry each tick (~7 stats/entry). It now uses the entry-dir
signature gate plus the two leaves git writes in place (gitdir, logs/HEAD),
runs the ungated sweep every 10 ticks (~5 min), and falls back to sweeping
every tick if a sweep ever finds a change the dir signature missed.

Co-Authored-By: Claude <noreply@anthropic.com>
…med, repeated miss

Detect a missed change on any entry rescan, including ones the in-place leaf
probes trigger, not just full sweeps. Re-stat the admin dir after the leaf
rescan so a rename racing the scan isn't counted, ignore transient missing
leaves, and require misses on two separate ticks before sweeping every tick.

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 223b4bd9-0e8b-4052-b60b-28de86f4fc72
📥 Commits

Reviewing files that changed from the base of the PR and between f812c67 and 5385f52.

📒 Files selected for processing: 4
  • src/main/ipc/worktree-git-common-entry-snapshot.ts
  • src/main/ipc/worktree-git-common-polling.test.ts
  • src/main/ipc/worktree-git-common-polling.ts
  • src/main/ipc/worktree-git-common-watch-reconciliation.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nwparker
nwparker merged commit 8e8698a into main Oct 20, 2026
54 of 56 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant