Skip to content

Check a worktree's commits against its base branch before deleting it - #22

Merged
ZmeiGorynych merged 6 commits into
mainfrom
egor/dev-2222-worktree-term-check-a-worktrees-commits
Nov 9, 2026
Merged

ZmeiGorynych merged 6 commits into
mainfrom
egor/dev-2222-worktree-term-check-a-worktrees-commits

Conversation

@ZmeiGorynych

@ZmeiGorynych ZmeiGorynych commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

Fixes DEV-2222.

"Delete worktree" used to ask for confirmation whenever a worktree had commits outside the repo's default branch (local main and origin/main). That made every stacked worktree look risky: a branch created from feature-x whose commits were already merged into feature-x still got "N commits not in main or origin/main".

What changes

The daemon now finds the worktree's base branch, using only local git:

  1. its upstream (branch.<b>.remote / merge), when that is origin or . and names a branch other than its own;
  2. otherwise, the branch its reflog records it was created from (branch: Created from <ref>).

A candidate is skipped when it is not a valid branch name (HEAD, HEAD~1, a commit id, …), also names a tag, or exists neither locally nor as origin/<x>. When neither source gives a usable branch, as for a detached worktree or an expired reflog, the worktree has no base and is compared only with the default branch, as before.

Commits now count as at risk only when they are in none of the base's local branch, origin/<base>, the default branch and origin/<default>, each counted only when it exists. A commit that reached main is therefore never flagged, even when the local base is stale.

When commits are at risk and there is an origin, the daemon fetches origin/<default> as before. It also fetches origin/<base> when that ref already exists locally. The two fetches run concurrently with --no-write-fetch-head --no-auto-maintenance, so the wait is still bounded by one 20 s limit. Each failed fetch is reported separately.

Wire and UI

worktreeAtRisk now carries bases: string[] and fetchFailed: {ref, reason}[] in place of local / remote / a single nullable fetchFailed. Both protocol versions are raised (daemon 8 → 9, browser 11 → 12), so an upgraded hub restarts older daemons.

The confirmation names every base it compared with:

  • before: It has 1 commit not in main or origin/main.
  • after (stacked on feature-x): It has 1 commit not in feature-x, origin/feature-x, main or origin/main.
  • two failed fetches: It has 1 commit not in feature-x, origin/feature-x as last fetched, main or origin/main as last fetched; couldn't compare with a fresh origin/feature-x because the fetch failed: …; couldn't compare with a fresh origin/main because the fetch failed: ….
  • nothing to compare with: There is no base branch to check that its commits are merged.

The full spec is in openspec/changes/dev-2222-worktree-term-check-a-worktrees-commits/.

Summary by CodeRabbit

  • New Features
    • Worktree removal checks now compare commits against the worktree’s inferred base branch as well as the default branch, helping identify commits that may not be merged.
    • When needed, the app refreshes eligible remote branches before assessing removal risk and reports individual fetch failures.
    • Removal warnings list the branches checked, identify branches that could not be refreshed, and explain when no comparison branch is available.

@coderabbitai

coderabbitai Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

Worktree removal risk checks now infer a branch base from upstream configuration or a branch-creation reflog and compare commits against available base and default-branch refs. The daemon fetches eligible origin refs concurrently and reports failures per ref. The risk protocol and sidebar now carry ordered bases and fetch-failure lists; protocol versions increase to 10 and 13.

Changes: Worktree Removal Risk

Layer / File(s) Summary
Base discovery and risk assessment
src/daemon/worktrees/base.ts, src/daemon/worktrees/base.test.ts, src/daemon/worktrees/git.ts, src/daemon/worktrees/git.test.ts, src/daemon/server/daemon.test.ts, test/process/daemon-worktrees.test.ts, openspec/specs/daemon/spec.md, openspec/changes/archive/...
The daemon selects a candidate base from an eligible upstream or branch-creation reflog, combines it with default-branch refs, and counts commits absent from those refs. When commits are ahead and an origin is available, it fetches eligible refs concurrently and reports failures by ref. Specifications and tests cover candidate selection, comparisons, fetch outcomes, and removal cases.
Risk message contract
src/protocol/constants.ts, src/protocol/values.ts, src/protocol/messages.ts, src/protocol/test-samples.ts, src/protocol/wire.golden.json, src/protocol/*test.ts, src/cli/run.test.ts, test/process/{cli,connect,daemon-server-startup,install-local}.test.ts, openspec/specs/protocol/spec.md, openspec/changes/archive/...
The worktreeAtRisk message replaces local and remote with a bounded bases array and replaces nullable fetchFailed with a bounded list. The protocol versions increase to 10 and 13. Schemas, samples, golden cases, and tests use the new fields and constraints.
Removal confirmation wording
src/web/ui/sidebar.ts, src/web/ui/sidebar.test.ts, test/e2e/sidebar.spec.ts, openspec/specs/web/spec.md, openspec/changes/archive/...
The sidebar names bases in order, marks bases with failed fetches as “as last fetched,” and adds a clause for each fetch failure. It uses generic wording when no base is available. Web specifications and tests cover the updated messages.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Removal as Worktree removal
  participant Risks as worktreeRisks
  participant Git as Git refs and origin
  Removal->>Risks: assess removal risk
  Risks->>Git: resolve base and default refs
  Git-->>Risks: available refs and ahead count
  Risks->>Git: fetch eligible origin refs concurrently
  Git-->>Risks: updated refs or per-ref failures
  Risks->>Git: recalculate comparison and changes
  Risks-->>Removal: bases, ahead, fetchFailed, and changes
Loading

Possibly related PRs

  • MotleyAI/worktree-term#15: PR #15 introduced the worktreeAtRisk fields that this change replaces with ordered bases and a list of fetch failures.
Merge Risk: Minimal · up to eb6c1

The change makes worktree removal checks compare commits against the base branch as well as the default branch, with per-ref fetch failure reporting. No concrete merge-blocking risk was found.

Pre-merge checks: Passed 5

Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: checking a worktree's commits against its base branch before deletion.
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
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.
Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 21 files. (11 skipped: 11 unsupported.)

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between ed8558a and eb6c18e.

Files selected for processing: 32

  • openspec/changes/archive/2026-11-09-dev-2222-worktree-term-check-a-worktrees-commits/.openspec.yaml
  • openspec/changes/archive/2026-11-09-dev-2222-worktree-term-check-a-worktrees-commits/design.md
  • openspec/changes/archive/2026-11-09-dev-2222-worktree-term-check-a-worktrees-commits/proposal.md
  • openspec/changes/archive/2026-11-09-dev-2222-worktree-term-check-a-worktrees-commits/specs/daemon/spec.md
  • openspec/changes/archive/2026-11-09-dev-2222-worktree-term-check-a-worktrees-commits/specs/protocol/spec.md
  • openspec/changes/archive/2026-11-09-dev-2222-worktree-term-check-a-worktrees-commits/specs/web/spec.md
  • openspec/changes/archive/2026-11-09-dev-2222-worktree-term-check-a-worktrees-commits/tasks.md
  • openspec/specs/daemon/spec.md
  • openspec/specs/protocol/spec.md
  • openspec/specs/web/spec.md
  • src/cli/run.test.ts
  • src/daemon/server/daemon.test.ts
  • src/daemon/worktrees/base.test.ts
  • src/daemon/worktrees/base.ts
  • src/daemon/worktrees/git.test.ts
  • src/daemon/worktrees/git.ts
  • src/protocol/constants.test.ts
  • src/protocol/constants.ts
  • src/protocol/messages.test.ts
  • src/protocol/messages.ts
  • src/protocol/test-samples.ts
  • src/protocol/values.ts
  • src/protocol/wire.golden.json
  • src/protocol/wire.golden.test.ts
  • src/web/ui/sidebar.test.ts
  • src/web/ui/sidebar.ts
  • test/e2e/sidebar.spec.ts
  • test/process/cli.test.ts
  • test/process/connect.test.ts
  • test/process/daemon-server-startup.test.ts
  • test/process/daemon-worktrees.test.ts
  • test/process/install-local.test.ts

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.

@ZmeiGorynych

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@sonarqubecloud

sonarqubecloud Bot commented Nov 9, 2026

Copy link
Copy Markdown

@ZmeiGorynych
ZmeiGorynych merged commit 10db1f0 into main Nov 9, 2026
11 of 12 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