Skip to content

fix(worktrees): keep creation fast in large repositories - #24346

Merged
nwparker merged 4 commits into
mainfrom
nwparker/slow-worktree-create-3
Oct 2, 2026
Merged

nwparker merged 4 commits into
mainfrom
nwparker/slow-worktree-create-3

Conversation

@nwparker

@nwparker nwparker commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 33 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​3549 $\color{#cf222e}{\Huge{\mathbf{−}}}$​442 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​3107
Prod 36 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1470 $\color{#cf222e}{\Huge{\mathbf{−}}}$​359 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1111

ELI5

Creating a workspace should not repeatedly inspect every other workspace or fill the same checkout twice. This makes creation cheaper in large repositories and repairs the object lookup slowdown that builds up over time.

What Changed

  • Register and lock a prepared checkout while the shared base fetch runs, then fill its files once from the fetched commit. A create that arrives early waits for that same work. Finalization still checks the latest base and runs the checkout hook once.
  • Require the exact owner marker for preparation finalization, unlock and discard; finalization reuses its verified administrative path and rereads the marker before unlock. Let Git create the marker during registration when supported. Older Git uses an exclusive marker write; if locking fails after this operation successfully registered a previously absent checkout, bounded signal-free single-force cleanup reclaims it. Competing locks, existing targets and unknown add outcomes are preserved.
  • Verify the new checkout directly and reuse its current stored workspace instance for startup and setup terminals. Full workspace listing remains the fallback for stale or ambiguous evidence and folder workspaces.
  • Extend existing idle maintenance to write the object lookup index in fragmented native/WSL repositories. Use one bounded directory walk and one scheduling class with separate ref/index cooldowns. Preserve delayed requests and protect existing bitmaps, incremental indexes, user opt-outs and foreign locks. No packs are rewritten or deleted.

Why

The captured production requests took 40.3s and 62.0s with 1,730 registered worktrees, 31,191 tracked files and 11,424 packs. Most time went into preparation and finalization; extra full listings also delayed verification and terminal startup.

Keeping Git responsible for registering and moving checkouts preserves its path, collision and recovery checks. Direct verification removes redundant work around those commands. Reusing the idle scheduler avoids a second maintenance service, and an index-only repair avoids the cost and risk of mass pack rewrites.

Linked Issue

N/A — maintainer performance investigation; no issue supplied.

Benchmarks

Scenario Measurement boundary Samples Observed time
Original installed app Backend create request 2 40.30s, 61.95s
Rebuilt app, controlled cold base advance Submit after setup decision to rendered terminal and observed prompt 1 7.09s
Rebuilt app, subsequent stable creates Same UI boundary 2 4.68s, 3.08s

The large-repository measurements use 1,730 worktrees, 31,191 tracked files and 11,424 packs. The rebuilt samples include object-index repair, Blank Terminal and skipped setup. The before/after boundaries differ, so these samples do not establish a percentage speedup or a latency guarantee. Cold fetch and materialization remain real costs. The visual section records the detailed setup.

The review fix was separately measured using real Git 2.55 on macOS, a one-file scratch repository, and injected cancellation during lock-path discovery after successful registration. There are 10 serial samples per mode and version; the old-Git unsupported option is simulated or cached. Timing starts at the preparation-add function and ends after rejection and any cleanup; fixture setup and inspection are excluded. Concurrent reviewers may affect timing.

Fallback mode Before: median rejection / leftovers After: median rejection including cleanup / leftovers After: median cleanup
First unsupported-option fallback 7.3ms / 10 of 10 left registered 12.4ms / 0 of 10 5.6ms
Cached fallback 6.9ms / 10 of 10 left registered 12.7ms / 0 of 10 6.2ms

Before timings return with the leaked registration. Fixed timings include its removal. The permanent regression cases can be rerun with ORCA_BACKGROUND_LAUNCH=1 pnpm exec vitest run --config config/vitest.config.ts src/main/git/worktree-preparation-add.test.ts src/main/git/worktree-preparation-fallback-cleanup-real-git.test.ts.

The cleanup in b52b3dd30d6 was measured separately on macOS with real Git 2.55. Finalization uses a one-file repository with an unchanged base, 20 pairs with alternating before/after order, and excludes preparation, inspection and removal. Concurrent validation may affect timing; these measurements describe finalization, not end-to-end UI latency.

Cleanup measurement Before 646fc7b0cdf After b52b3dd30d6
Median finalization including owner unlock 37.3ms 32.7ms
Lock-path Git subprocesses per finalization 4 2
Directory walks in 11,424-pack iterator fixture 2 1
Directory entries visited in that fixture 91,392 45,696

The directory figures are deterministic count tests with four metadata entries per pack. Cancellation, activity changes during the walk and protected metadata still suppress the writer. Run ORCA_BACKGROUND_LAUNCH=1 pnpm test src/main/git/repo-pack-index-maintenance.test.ts src/main/git/worktree-preparation-lock-real-git.test.ts to verify these bounds.

Visual Proof

Measured before and after

Original create dialog Rebuilt workspace with observed shell prompt
Before After

The latency change is shown by recorded timings, not by a layout change. Production baseline numbers are backend request spans. Final rebuilt macOS daemon UI samples measure submit, after any setup trust decision, to observed PTY prompt output and a rendered terminal. Blank Terminal was selected and setup skipped; after measurements include the one-time object-index repair.

Final controlled samples: 7.09s cold, then 4.68s and 3.08s. The cold sample forces a base advance through a temporary local remote in the same large repository and verifies the fetched HEAD and exactly one materialization. Its fetch takes 3.65s and materialization 3.08s; finalization takes 1.10s. These are observed samples, not a five-second guarantee. The earlier ordinary-base UI samples were 3.63s and 1.48s. All disposable workspaces, the test remote and launched app processes were cleaned up.

Testing

  • Manually tested through the rebuilt, hidden Electron renderer using Playwright CDP; inspected screenshots and verified the shell cwd and fetched HEAD.
  • Automated tests added/updated.
  • Initial focused and adjacent suites: 413 passed, with 22 expected opt-in skips (real Git compatibility, physical WSL and cancellation benchmark). Additional focused ownership, routing and preparation gates passed.
  • Latest cleanup validation: 1,675 passed, 23 expected opt-in skips across 32 suites, including the full runtime suite. The Git compatibility tests were run separately against both real binaries below. The 41 fallback regression cases reproduce 12 failures before the fix and pass after it; real Git proves competing locks and user files survive.
  • Real Git compatibility: 20/20 on Linux Git 2.25.1 in Docker and 20/20 on native Git 2.55. Both real-binary contracts were rerun after the cleanup. They check the Git 2.33 lock-reason boundary and baseline fallback; the new cancellation cases use current Git with forced fallback.
  • pnpm tc, pnpm build, changed-code quality, reliability manifest and git diff --check pass.
  • Full pnpm lint passes the base lint and anti-slop stages, then stops at pre-existing mobile import cycles in host-client-hooks.ts, client-context.tsx, fit-scale.ts and mouse-report-cell.ts; those files are unchanged from main. The changed-code quality gate reports zero new findings.

Review

Two initial independent review rounds covered lock ownership, cancellation, failed creation, expiry/eviction, simultaneous fetch/consume, stale workspace instances, split authority, host routing, baseline Git and maintenance contention. Codex used gpt-6.1-sol at ultra; Claude used Orca orchestration with the effective opus launch model. Both reviewers assessed the full updated diff independently; the cleanup below received another independent pass from each.

Round Codex 6.1-sol ultra Claude Opus Result
1 No P0/P1; flagged fallback leak as P2 One P1 for the same fallback leak Treated at higher severity; fixed in 646fc7b0cdf
2 No actionable P0/P1; 346 focused tests passed No actionable P0/P1; 326 focused tests and 1,340 runtime tests passed P0/P1 clean

Two outdated runtime assertions that caused the original CI failure were corrected to verify startup instance evidence and direct WSL verification without an inventory scan. The full runtime suite now passes locally. The initial review workers and coordinator were released/closed after settlement. The cleanup Claude task succeeded; Orca reports its terminal retained after user takeover, so it was left alone.

The elegance pass removes single-use wrappers, unused ownership bypasses and the single-field barrier options type; it also initializes the pool entry with a checked type. Ownership/host/lineage guards and failure cleanup remain because they preserve behavior. Against the same base, net application-source additions fall from 1,034 to 983 lines, and the 227-line manifest addition is gone. Production changes span 34 files; regression tests and mocks account for most of the overall diff.

Cleanup review at b52b3dd30d6 Result
Codex 6.1-sol ultra No actionable P0/P1; 292 focused tests passed
Claude Opus via Orca orchestration No actionable P0/P1; 246 focused tests and node typecheck passed

Final direct-Codex adversarial audit cross-referenced Git source at ~/projects/git and passed 189 focused safety tests covering all 34 application-source paths. Two explicitly withdrawn bot findings are resolved. The outdated read/unlink race thread remains acknowledged: an exact ownership reread immediately before unlink narrows the interval, and Git's own unlock primitive also uses read-then-unlink. An atomic compare/delete operation is unavailable through this filesystem interface.

The audit follow-up #24945 is merged. Superseded queued MIDX/ref writers and delayed probes are fenced by newer activity; admitted writers finish. Ordinary preparation-lock discovery uses one Git query instead of two. The follow-up reuses the ownership reader and draft builder, preserves full SSH review context, and negotiates independently updated session-search catalogs. It adds 315 net application lines across 32 modules, with most overall additions in tests. Two independent direct Codex 6.1-sol ultra reviews verified all 78 final files against cloned Git source; the exact head passed 55 CI checks with nine intentional skips and a rebuilt isolated public CLI smoke. Benchmarks and the two remaining P2 limits/two residual risks are recorded in that PR. The benchmark results above describe this original PR.

Remaining confirmed P2 items:

Item Evidence and consequence
Missing checkout directory blocks stale cleanup Confirmed with real Git. Administrative lock annotation now recovers the reason, but discard still verifies through checkout-cwd Git; missing cwd prevents cleanup and leaves the locked registration. Current discard guard.
Transient opt-out probe errors defer maintenance for six hours A non-unset config error is treated as opted-out, including transport/admission failures; the engine assigns a six-hour cooldown. Current config probe.

Validation gaps remain for physically interrupted old-Git registration before successful settlement, external repack/metadata overlap, and physical Windows unlink sharing violations. Unknown registration ownership is deliberately preserved; simulations are not presented as reproduced production corruption. Targeted lock discovery remains a small cost, materially reduced in #24945.

Reliability contract (agent-session.provider-ownership and prepared checkout ownership): the same persisted instance and execution host must own startup. Matching marker ownership gates materialization and double-force cleanup. A successfully registered, initially absent unlocked fallback checkout may receive bounded single-force cleanup, which preserves competing locks. The motivating path is a large-repository create racing a fetched base advance or starting setup alongside its terminal. Oracles assert one materialization, one checkout hook, one cleanup, the latest HEAD, zero full listings for verified startup, and fallback for stale/foreign/folder evidence. Normal CI test discovery runs the regression files directly. Dedicated gate routing and CI soak remain accepted gaps. The unused new manifest entry was removed: its hand-entered commands and budgets did not schedule tests or enforce latency, and duplicated the evidence recorded here.

Provider/platform Evidence
macOS local and daemon Real Git/filesystem tests and rendered creation-to-prompt flow.
Linux Real baseline Git in Docker; live Linux terminal UI is an accepted gap.
Windows / WSL Deterministic path, owning-distro, capability and cancellation tests; physical execution is an accepted gap.
SSH / remote runtime Deterministic host-qualified instance, same-id collision, fetch sharing and startup routing tests; live and mixed-version UI are accepted gaps. Index maintenance remains on its execution host and does not touch SSH repos locally.
Mobile / relay Wire and lifecycle authority are unaffected; the startup evidence argument stays internal to the runtime.

Performance budget: existing three-checkout pool and five-minute lifetime remain bounded; maintenance probes at most 65,536 directory names or one second, admits one idle writer, and retains at most 64 directory hints. It respects activity/battery/agent gates, refreshes indexes at most hourly after a new arm, and backs off failures for 30 minutes. A running index writer does not block create's maintenance pause.

Diagnostics use existing creation-phase spans plus index outcome, pack-count floor and write-duration attributes. Residual gaps: live platform/provider runs and CI soak are not established, and external marker/bitmap replacement between a final filesystem check and a Git command remains non-atomic. This evidence establishes the listed tests and samples; long-running CI soak remains unestablished.

Agent skill upstream boundary

  • Not applicable; no skill-installer source or registry data is copied.

Notes

No RPC/preload signature or remote wire field was added. Provider ownership, workspace trust and terminal split authority remain in the launch path. The installed desktop app has not been replaced by this branch.

Checklist

  • Small diff — this focused creation-path fix spans preparation, verification, startup and idle maintenance; most additions are regression tests.
  • Explained the user-facing before/after, mechanism and alternatives.
  • Before/after evidence attached.
  • Self-reviewed for correctness, security and performance.
  • Cross-platform, SSH/remote and path impact considered.
  • Typecheck, focused tests and full build pass; changed quality passes, with the unrelated full-lint limitation recorded above.

@greptile-apps

greptile-apps Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[High risk] Refactors worktree creation and Git maintenance across many modules.

The PR appears safe to merge with respect to blocking findings, although three earlier non-blocking race or coverage concerns remain.

Findings

  1. P2 Large pack scans never finish ▶
  2. P2 Unlock can remove another lock ▶
  3. P2 Protected metadata can be missed ▶

Summary

The PR speeds worktree creation by registering and locking a preparation during fetch, materializing it once, verifying the created checkout directly, reusing creation evidence for startup terminals, and repairing fragmented object indexes during idle maintenance. Since the previous review, the scheduler now retains an index-only maintenance arm until ref maintenance is due.

Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Repository write arms idle maintenance] --> B[Quiet period and admission checks]
  B --> C{Index maintenance due?}
  C -- Yes --> D[Probe packs and maintain index if eligible]
  C -- No --> E{Ref maintenance due?}
  D --> E
  E -- No --> F[Retain arm until ref due]
  E -- Yes --> G[Count loose refs and pack if needed]
Loading

Reviews (4) · Last reviewed commit: "fix(git): keep ref maintenance armed aft..."

Comment thread src/shared/repo-ref-maintenance.ts Resolved
Comment thread src/main/git/repo-pack-index-state.ts Resolved
Comment on lines +92 to +93
const lockPath = await verifyWorktreePreparationLock(worktreePath, expectedLockReason, options)
await unlink(lockPath).catch((error: unknown) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Unlock can remove another lock Verification reads the lock marker, but removal is a separate operation on its path. If another Git process replaces the marker between those operations, this unlink removes the new owner’s lock instead. That leaves the worktree unprotected, including when finalization unlocks a newly attached checkout.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledged as an inherent limit. Filesystems offer no atomic compare-and-delete, and Git's own worktree unlock deletes the marker without checking it. This code narrows that gap: it reads the exact reason and checks cancellation immediately before unlink, and preparation paths are Orca-private hidden directories that no ordinary Git workflow locks.

@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 53627f1e-a33b-47ee-a1a2-801bf13f75e5

📥 Commits

Reviewing files that changed from the base of the PR and between b52b3dd and 8087fe6.

📒 Files selected for processing (2)
  • src/shared/repo-pack-index-scheduling.test.ts
  • src/shared/repo-ref-maintenance.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/shared/repo-pack-index-scheduling.test.ts
  • src/shared/repo-ref-maintenance.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

The pull request updates prepared-worktree creation and finalization to use lock-reason ownership checks and coordinate checkout materialization with fetch settlement. It adds direct created-worktree reconciliation and passes created-worktree evidence into terminal startup and split routing. It also adds multi-pack-index probing and maintenance, with configuration handling and separate scheduling for pack-index and ref maintenance.

Priority: ⬆️ High

Merge Risk: ⚪ Minimal · up to 8087f

Deferred repository maintenance remains scheduled after index work. The selected changes are mergeable after normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to b52b3

The change strengthens checkout ownership checks and guards background repository writes. A crash-recovery path can nevertheless leave a locked registration behind when its checkout directory is missing. Some terminal-routing and repository-authorization paths remain partially examined.

Retained concerns

  • Low · reliability · inferred: Stale-registration recovery now depends on the checkout directory existing. Ownership verification runs Git metadata lookup with the checkout as its working directory before registration removal; a missing checkout can therefore prevent reclamation, and stale cleanup suppresses that failure. Base attempted double-force removal from the repository directory without this dependency. Exact lock verification correctly protects competing owners, but recovery can strand the dead owner's locked registration.
Security review details

Security Blast Radius

  • inferred — The new index writer affects shared repository object metadata, potentially serving multiple linked worktrees. At the examined fetch caller, maintenance inherits the same repository path and native/WSL execution context already used for fetch. Upstream authorization of those arguments was not fully established; broader attacker-controlled reachability or privilege escalation is not proven.

Trust Boundaries and Controls

  • observed — The new index route honors maintenance and garbage-collection opt-outs, separately honors core.multiPackIndex=false, and protects bitmap, incremental-index and unsupported index forms. It derives the pack directory from Git's common directory and rechecks cancellation and write admission before invoking Git.

Resilience and Maintainability Implications

  • observed — Maintenance serializes attempts and rechecks suspension and activity after asynchronous probes. Admitted index writers finish before releasing the maintenance slot, while a create pause need not wait for the index writer; this differs from waiting for the packed-refs rewrite gate.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.05% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 84 functions across 61 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: improving worktree creation performance in large repositories.
Description check ✅ Passed The description is complete and closely follows the repository template. It explains the user impact, implementation, motivation, testing, visual evidence, review status, platform considerations, and …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — one rough edge inline.

Reviewed changes

  • Register during fetch. Prepared worktree add now runs while the shared base fetch is in flight, with a cancellable beforeMaterialization barrier that waits for settlement, resolves the current OID, then does a single reset --hard.
  • Prepared-checkout ownership lock. New .git/worktrees/<name>/locked marker; Git ≥2.33 writes it atomically via worktree add --lock --reason, older Git registers then writes it exclusively. Every mutate/unlock/discard re-verifies the exact reason and refuses to touch a foreign owner.
  • Queued tip refresh. An existing warm preparation is refreshed in place (one reset) instead of discarded, published before yielding so a racing create waits for the same work.
  • Direct create verification and terminal-start evidence. resolveCreatedWorktree reads the new checkout directly and lists only as a fallback; startup/setup terminals reuse the in-memory created Worktree when its path, host routing and persisted instanceId still agree.
  • Idle multi-pack-index maintenance. Bounded, opt-out-aware, bitmap/incremental/foreign-lock-protecting index-only repair scheduled independently from ref packing in RepoRefMaintenance.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

This incremental review covers the new commit 646fc7b0cd on top of the previously reviewed ea63633b6e. The only production change is src/main/git/worktree-preparation-add.ts; the rest is the reliability gate and tests.

  • Reclaimed unlocked fallback registrations. The older-Git path (add([]) then an exclusive marker write) now catches a failed lock and removes its just-registered worktree with a single --force, gated on the path having been initially absent and no competing owner being detected. This closes the stranded-registration gap raised in the prior review.
  • Hoisted the initial-absence probe. isAbsent now runs once before the capability fallback decision, so the fallback path can decide whether a failed preparation is safe to reclaim rather than leaving an unlocked registration behind.
  • Regression coverage. A new real-Git suite plus unit cases prove exactly one single-force removal, no reset, preservation of a competing lock, and preservation of a pre-existing empty target. The real-Git cases exercise both the cancellation and generic probe-failure windows.

The single-force removal is the correct lever here: Git's worktree remove refuses a locked worktree without a second --force, so a competing owner is preserved even when the marker probe itself fails. Cancellation cannot strand the cleanup because the discard path strips the signal and pins its own timeout. The author-acknowledged residual — an older-Git add interrupted before positive registration success — is preserved deliberately, which is the safe choice since ownership is unprovable in that window.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

🟡 Minor · Resolve lock ownership from administrative metadata when… · worktree-preparation-discard.ts:30-42

src/main/git/worktree-preparation-discard.ts:30-42
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Resolve lock ownership from administrative metadata when the checkout path is missing.

When stale cleanup selects a dead preparation owner, discardPreparedWorktree resolves the lock with worktreePath as Git's cwd. If the checkout directory was removed externally, git rev-parse --git-path locked cannot start. The code therefore never reaches git worktree remove --force.

Stale cleanup suppresses this error, and this direct call does not add the target to pendingDiscards. Later cleanup passes repeat the same failure, so the Git registration can remain indefinitely.

Use the registered administrative lock path for ownership verification, then remove the registration from repoPath. Do not bypass the ownership check.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 317a8c02-4c77-46e6-9bbd-e58617a32a3a

📥 Commits

Reviewing files that changed from the base of the PR and between 646fc7b and b52b3dd.

📒 Files selected for processing (25)
  • src/main/git/repo-pack-index-maintenance.test.ts
  • src/main/git/repo-pack-index-maintenance.ts
  • src/main/git/worktree-create-admission-tier.test.ts
  • src/main/git/worktree-create-preparation-real-git.test.ts
  • src/main/git/worktree-create-preparation-real-wsl.test.ts
  • src/main/git/worktree-create-preparation.ts
  • src/main/git/worktree-mutation-route-invalidation.test.ts
  • src/main/git/worktree-preparation-base-oid.test.ts
  • src/main/git/worktree-preparation-cancel-latency.bench.test.ts
  • src/main/git/worktree-preparation-lock-real-git.test.ts
  • src/main/git/worktree-preparation-lock.test.ts
  • src/main/git/worktree-preparation-lock.ts
  • src/main/ipc/worktrees/create/register-worktree-prefetch-handler.ts
  • src/main/runtime/orca-runtime-get-worktree-terminal-provisioning-host.ts
  • src/main/worktree-create-base-prefetch.test.ts
  • src/main/worktree-create-base-prefetch.ts
  • src/main/worktree-create-preparation-pool.ts
  • src/main/worktree-create-preparation-stale-cleanup.ts
  • src/main/worktree-create-preparation.test.ts
  • src/main/worktree-create-preparation.ts
  • src/main/worktree-preparation-fetch-barrier.test.ts
  • src/main/worktree-preparation-refresh-queue.ts
  • src/main/worktree-preparation-tip-refresh.test.ts
  • src/shared/repo-maintenance-schedule.ts
  • src/shared/repo-ref-maintenance.ts
💤 Files with no reviewable changes (1)
  • src/main/worktree-preparation-refresh-queue.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/runtime/orca-runtime-get-worktree-terminal-provisioning-host.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Comment thread src/shared/repo-ref-maintenance.ts Resolved

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

This incremental review covers b52b3dd30d since the prior pullfrog review at 646fc7b0cd — a cleanup and optimization pass over the prepared-checkout ownership and idle-maintenance code.

  • Single bounded walk for pack-index maintenance. The two objects/pack probes collapsed into one that both counts packs and detects protected metadata, and idle admission is now checked before walking, so a busy app spends no directory entries.
  • Lock path reused across finalization. finalizePreparedWorktree resolves the ownership lock once and reuses it after worktree move; unlockWorktreePreparationAtPath re-reads the owner before unlinking. This removes two rev-parse subprocesses per finalize and is safe because Git's worktree move preserves the linked administration directory (confirmed against real Git 2.55).
  • Required lock reason and verified failure cleanup. discardPreparedWorktree, unlockPreparedWorktree and finalizePreparedWorktree now require expectedLockReason, and failure cleanup double-forces only after re-verifying the marker, so a foreign owner is never clobbered.
  • Merged maintenance scheduling. RepoRefMaintenanceCooldown and RepoPackIndexSchedule folded into RepoMaintenanceSchedule with independent ref/index cooldowns preserved.
  • Cleanup. Dropped the single-use prepareCheckoutForEntry wrapper and WorktreeCreatePreparationOptions type, extracted the tip-refresh queue into worktree-preparation-refresh-queue.ts, and removed the unused reliability-gate manifest entry.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

An idle attempt that found the pack index due but refs still cooling down
returned without rescheduling, so loose refs from the arming fetch waited
for the next write instead of the ref cooldown.
@nwparker

nwparker commented Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

CodeRabbit's outside-diff note on worktree-preparation-discard.ts:30-42 (missing checkout directory) is valid and tracked as a follow-up. It requires a crash plus external deletion of Orca's hidden preparation directory. The result is a leftover locked, hidden registration; no user files or branches are affected. Resolving the administrative lock path from repoPath without bypassing the ownership check is a separate change.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

This incremental review covers 8087fe631b since the prior pullfrog review at b52b3dd30d — a one-commit refinement to idle ref-maintenance scheduling.

  • Re-armed an index-only attempt to its ref phase. When the pack index was due but refs were still cooling down, RepoRefMaintenance.packIfNeeded returned without rescheduling, so loose refs left by the arming write waited for an unrelated future fetch. It now re-inserts the tracked repo and schedules it at phases.refDueAt(key) - now(), bounded by !disposed && !tracked.has(key) so a concurrent arm is not clobbered.
  • Regression test. A new case in repo-pack-index-scheduling.test.ts proves two index passes run while refs stay untouched, then refs are re-probed once REF_MAINTENANCE_CLEAN_COOLDOWN_MS elapses — with no further arm. It fails against the pre-fix code.

The guard against a fresher arm and the positive-delay refDueAt - now() arithmetic (branch only entered when now < refDueAt) rule out the two ways this re-arm could misbehave. This addresses CodeRabbit's "keep ref attempt scheduled after index-only maintenance" finding.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@nwparker
nwparker merged commit 34ae093 into main Oct 2, 2026
54 of 55 checks passed
brennanb2025 added a commit that referenced this pull request Oct 2, 2026
Resolves the conflicts with #24346 (keep creation fast in large repositories)
in the prepared-checkout code. All of #24346's behavior is kept; the create
timing and spare recording are re-applied onto its new shape:
- finalize keeps main's lock-ownership checks and lock reason, and still
  reports whether the prepared checkout had to be reset;
- the failed-finalize discard is timed only when main actually runs it;
- a tip refresh of an existing spare counts as preparation work and extends
  its build timing (per-entry bookkeeping moved to
  worktree-create-preparation-activity.ts, the claim registry to
  worktree-create-preparation-claim-registry.ts, to keep the pool under the
  line limit; no behavior change);
- the create no longer lists worktrees, so the worktree count now comes from
  one listing of .git/worktrees in the existing post-create repo read.
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