Skip to content

fix: doctor reclaim can delete the main/canonical worktree, cascading to all linked worktrees - #328

Closed
getappz wants to merge 1 commit into
masterfrom
task/348
Closed

fix: doctor reclaim can delete the main/canonical worktree, cascading to all linked worktrees#328
getappz wants to merge 1 commit into
masterfrom
task/348

Conversation

@getappz

@getappz getappz commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Auto-opened on item done for _GzH4smL3DbkwEULLXh5D.

Summary by CodeRabbit

  • Bug Fixes
    • Protected the main worktree from accidental reclamation, including when forced cleanup is used.
    • Prevented cleanup from unintentionally removing linked nested worktrees associated with the main worktree.
    • Improved worktree health reporting by identifying the canonical worktree.

reclaim() treated the main/canonical worktree exactly like any other
lane -- any HealthFlag it happened to pick up (MissingUpstream, Stale,
etc.) made it std::fs::remove_dir_all-eligible. Since linked worktrees
live nested under it (.worktrees/<name>), deleting the main worktree
cascaded and destroyed every linked worktree too, bypassing their own
per-lane dirty-check protection entirely.

git worktree list always lists the main worktree first; tag that lane
and hard-skip it in reclaim(), unconditionally, even under --force --
matching how real git worktree remove already refuses to ever remove
the main worktree.

Regression test reproduces the exact incident shape: a main worktree
flagged MissingUpstream (but clean) plus a dirty linked worktree
nested under it; asserts the main worktree, its .git, and the linked
worktree all survive reclaim(..., false).
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8c793eb4-99cb-4001-859d-522bc850bac3

📥 Commits

Reviewing files that changed from the base of the PR and between e88cccd and 76c97ad.

📒 Files selected for processing (1)
  • crates/flare-git-core/src/doctor.rs

📝 Walkthrough

Walkthrough

LaneHealth now records whether a lane is the canonical worktree. Scanning marks the first Git worktree as canonical, and reclaim always skips it. A regression test verifies that flagged main and linked nested worktrees remain intact.

Changes

Main worktree protection

Layer / File(s) Summary
Identify the canonical worktree
crates/flare-git-core/src/doctor.rs
LaneHealth exposes is_main_worktree, and scan populates it for missing-path and normal lane construction using the first worktree entry.
Protect the canonical worktree during reclaim
crates/flare-git-core/src/doctor.rs
reclaim skips the canonical lane regardless of flags or force mode; a regression test verifies the main and linked nested worktrees remain present.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch task/348

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

@getappz

getappz commented Jul 25, 2026

Copy link
Copy Markdown
Owner Author

Redundant — the real PR (#327) was already created manually and merged. Closing this auto-opened duplicate.

@getappz getappz closed this Jul 25, 2026
getappz added a commit that referenced this pull request Jul 25, 2026
… already merged (#329)

push_and_open_pr() unconditionally called pulls::create() for the
item's branch. GitHub's API only rejects a duplicate while an existing
PR is still open -- once it's merged (or manually closed), a second PR
against the same branch is perfectly legal, which is exactly how
item done re-running on an already-merged item opened a redundant PR
(2026-07-25: PR #328 duplicating already-merged #327).

Add pulls::find_existing() to check for any PR (open/merged/closed)
matching the branch before creating a new one, and use it in
push_and_open_pr -- if found, reuse its url instead of opening a
duplicate.
@getappz
getappz deleted the task/348 branch August 5, 2026 14:15
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