fix(server): keep worktrees containing nested repositories#24061

open1
main
GitHub fork: codex/fix-23866-nested-repository-cleanup
opened6d agobyNnateEc
View on GitHubTwo-way sync enabledPR last imported 2d ago

Problem

Storage cleanup can remove ignored nested repositories and linked worktrees, including their uncommitted files, even though the outer worktree has a clean Git status. Fixes #23866. This is a focused data-loss guard for the existing cleanup policy, not a new cleanup policy or feature.

Change

Inspect for nested .git entries during the existing worktree traversal, before either git clean -ffdx or worktree removal. Keep the outer worktree when an independent nested repository is found. Registered submodules retain the existing recursive safety checks and remain removable when clean.

The traversal now must finish successfully before removal: unreadable directories, inspection limits, or a timeout keep the worktree. The orphan-reporting path remains measurement-only. pnpm virtual-store files remain excluded from reclaimed-byte totals, but their directories are inspected before deletion.

Verification

  • Red first: four real temporary Git fixtures (nested clone / linked worktree × tracked-only / default uncommitted-changes policy) were deleted on main despite the outer status being clean.
  • vp test run apps/server/src/storageCleanup.test.ts: focused cleanup integration suite covers preservation of nested content, independent repositories inside registered submodules, repositories under a pnpm virtual store, and failed directory inspection. Existing clean-submodule, symlink, hardlink, pnpm accounting, and activity-during-measurement coverage remains enabled. The final run passed all 124 tests.
  • vp run check:changed: formatting, lint, knip, GraphQL generation, both affected typechecks and all 124 adjacent tests passed.

Runtime evidence (real Git and filesystem, temporary fixture roots only):

text
1Before: outer git status --porcelain => empty
2 cleanup runNow => removed (both keep policies, clone and linked worktree)
3After: cleanup runNow => kept: Contains a nested Git repository
4 nested/uncommitted.txt => original contents preserved
5 nested git rev-parse --show-toplevel => original nested checkout
6Read failure => kept: Worktree could not be fully inspected

No production cleanup was run. Verified on macOS with Node 26.12.1; Windows and Linux were not run. This remains a pre-removal check, not an atomic guarantee against external filesystem changes after inspection. Large pnpm trees now require directory inspection instead of skipping the whole store; existing time/entry limits conservatively retain a worktree when inspection cannot finish.

Model: GPT-5-based Codex. Harness: Codex desktop.

Checks

22 successful · 10 skipped
All checks passed
1b2a549

Added 1 commit

  • fix(server): 清理工作树前保护嵌套仓库1b2a549
Synced from GitHub

Approvability

Verdict: Approved at 1b2a549

Macroscope's review found this PR approvable — This focused server bug fix prevents existing cleanup from deleting nested repositories and preserves worktrees when filesystem inspection is incomplete. The accompanying integration tests cover nested repositories, pnpm stores, submodules, and failed inspection paths.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between d7a8d6f32001444e013aa07c8a468ce3e987f9cf and 1b2a549c1daa2d9b45314a1f15b7175530c9d309.

📒 Files selected for processing: 2
  • apps/server/src/storageCleanup.test.ts
  • apps/server/src/storageCleanup.ts

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

📝 Walkthrough

Storage cleanup now inspects worktrees for nested Git repositories and incomplete scans. It retains a worktree when inspection finds a nested repository or cannot determine its contents.

Changes: Storage cleanup

Layer / File(s)Summary
Repository-aware worktree measurement
apps/server/src/storageCleanup.ts
measureWorktree can inspect nested repositories and registered submodules. It returns a structured result with byte measurements and an inspection reason. It reports incomplete inspection for scan limits, timeouts, truncated submodule output, and other scan failures.
Cleanup decisions and validation
apps/server/src/storageCleanup.ts, apps/server/src/storageCleanup.test.ts
Cleanup retains worktrees when inspection reports a reason, and orphan-worktree size caching reads the result’s bytes field. Tests cover nested repositories in ignored directories, the pnpm virtual store, and submodules, plus unreadable worktrees.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: t3dotgg, juliusmarminge, maria-rcks

Merge Risk: ⚪ Minimal · up to 1b2a5

Cleanup now keeps worktrees that contain nested Git repositories or that cannot be fully inspected, which addresses the reported data-loss case. No concrete merge-blocking issue remains after review. Windows and Linux were not exercised by the author.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the main change: preventing cleanup from removing worktrees that contain nested repositories.
Description checkPassedThe description covers the problem, implementation, scope rationale, verification results, platform coverage, limitations, and agent attribution. It also references issue #23866 and explains why this …
Linked Issues checkPassedIssue #23866 requires cleanup to keep an outer worktree when it contains an ignored nested Git repository or linked worktree. The diff adds repository inspection before removal and before destructive …
Out of Scope Changes checkPassedThe changes stay within the storage-cleanup data-loss guard for issue #23866. The structured measurement result, pnpm virtual-store traversal, submodule handling, inspection limits, timeout handling, …
Full details: Description check

Explanation

The description covers the problem, implementation, scope rationale, verification results, platform coverage, limitations, and agent attribution. It also references issue #23866 and explains why this focused bug fix does not require broader approval.

Full details: Linked Issues check

Explanation

Issue #23866 requires cleanup to keep an outer worktree when it contains an ignored nested Git repository or linked worktree. The diff adds repository inspection before removal and before destructive cleanup. It detects nested .git entries, keeps the worktree with Contains a nested Git repository, and keeps it when traversal fails, times out, or exceeds limits. The added tests cover nested clones and linked worktrees under both cleanup policies, preserve uncommitted files, and verify the clean outer status case. The existing removal path therefore covers idle and deletion-triggered cleanup calls that reach this pre-removal check.

Full details: Out of Scope Changes check

Explanation

The changes stay within the storage-cleanup data-loss guard for issue #23866. The structured measurement result, pnpm virtual-store traversal, submodule handling, inspection limits, timeout handling, and updated failure test support safe pre-removal inspection or preserve existing accounting behavior. The added tests directly verify these safety cases. No unrelated production feature or unrelated test change is evident.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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