Worktree-prep rebase parks items that vanilla git rebases cleanly — every main advance costs a hand-rebase #533

Merged
toasterson merged 1 commit from claude/wi-019fd86c-worktree-prep-rebase-parks-items-that-va into main 2026-08-09 09:58:16 +00:00
Owner

Anima work item 019fd86c-3825-7763-9019-e3892e7cb08d.

Symptom

On 2026-08-06, five WIs parked rebase-conflict after main advanced. For three of them (PR #485, #491, #505) a plain git rebase origin/main on an operator machine replayed cleanly — no conflicts at all. Only #481 had real conflicts. The runner's worktree preparation rejects with PARKABLE:Rebase conflict … Conflicts in N file(s) where vanilla git succeeds, so every merge to main converts in-flight branches into parked items and operator toil (fetch → rebase → branch-swap push → resync_pr_state → unpark).

Suspected causes to investigate

  • Stale origin/main in the runner's cached repo/worktree (rebasing onto an old base that has since been superseded, or onto a mid-state fetched between two merges).
  • A different rebase strategy/flags than plain git rebase (e.g. --merge vs apply, rename detection limits, or a merge-tree based pre-check that is stricter than the actual rebase).
  • Conflict detection running against the wrong base (e.g. the branch's original fork point instead of the current merge-base).

Acceptance criteria

  • Reproduce: a branch that plain git rebase origin/main replays cleanly must not park as rebase-conflict.
  • The worktree-prep rebase fetches the current origin/main immediately before rebasing and uses the same default strategy as vanilla git.
  • When a rebase genuinely conflicts, the park message lists the conflicting files from the actual rebase attempt (this already works — keep it).
  • Log the base SHA the rebase was attempted against in the rejection, so a stale-base regression is diagnosable from the park message alone.
Anima work item `019fd86c-3825-7763-9019-e3892e7cb08d`. ## Symptom On 2026-08-06, five WIs parked `rebase-conflict` after main advanced. For three of them (PR #485, #491, #505) a plain `git rebase origin/main` on an operator machine replayed **cleanly** — no conflicts at all. Only #481 had real conflicts. The runner's worktree preparation rejects with `PARKABLE:Rebase conflict … Conflicts in N file(s)` where vanilla git succeeds, so every merge to main converts in-flight branches into parked items and operator toil (fetch → rebase → branch-swap push → resync_pr_state → unpark). ## Suspected causes to investigate - Stale `origin/main` in the runner's cached repo/worktree (rebasing onto an old base that has since been superseded, or onto a mid-state fetched between two merges). - A different rebase strategy/flags than plain `git rebase` (e.g. `--merge` vs apply, rename detection limits, or a merge-tree based pre-check that is stricter than the actual rebase). - Conflict detection running against the wrong base (e.g. the branch's original fork point instead of the current merge-base). ## Acceptance criteria - [ ] Reproduce: a branch that plain `git rebase origin/main` replays cleanly must not park as rebase-conflict. - [ ] The worktree-prep rebase fetches the current origin/main immediately before rebasing and uses the same default strategy as vanilla git. - [ ] When a rebase genuinely conflicts, the park message lists the conflicting files from the actual rebase attempt (this already works — keep it). - [ ] Log the base SHA the rebase was attempted against in the rejection, so a stale-base regression is diagnosable from the park message alone.
## Problem
On 2026-08-06, five WIs parked as "rebase-conflict" after main advanced.
For three of them (PR #485, #491, #505), a plain `git rebase origin/main`
on an operator machine replayed cleanly with no conflicts. The runner's
worktree-prep rebase was detecting conflicts that didn't exist, parking
items that should have proceeded normally.

## Root Causes Fixed

1. **Stale base fetch**: `git fetch origin <base_branch>` doesn't
   force-update the local tracking ref if it already exists. Changed to
   explicit refspec `<base>:refs/remotes/origin/<base>` which force-updates
   the ref to match the remote's current tip (git.rs:343-351).

2. **Overly broad conflict detection**: Any rebase failure that left
   unmerged files was classified as a conflict, even if the rebase never
   started. Added check for `.git/rebase-merge` or `.git/rebase-apply`
   to verify rebase was actually in progress before classifying as conflict
   (git.rs:288-289, 307-330).

3. **Missing diagnostics**: Park messages didn't include the base SHA,
   making stale-base regressions undiagnosable. Added `base_sha` field to
   `PrepareWorktreeError::RebaseConflict`, logged at rebase start/end, and
   included in park messages (git.rs:22-26, 252-262, slot.rs:200-211).

## Changes

**crates/anima-runner/src/git.rs:**
- Updated `PrepareWorktreeError::RebaseConflict` to include `base_sha`
- Modified `rebase_onto_base()` to log base SHA and check if rebase is
  actually in progress before classifying failures as conflicts
- Updated `prepare_worktree()` to use explicit refspec when fetching base

**crates/anima-runner/src/slot.rs:**
- Updated park message formatting to include base SHA

## Testing
All 115 existing runner tests pass, including continuation and rebase tests.

## Expected Impact
Branches that vanilla git can rebase cleanly will no longer park as
rebase-conflict. Only genuine conflicts (rebase in progress + unmerged
files) will park. Park messages now include base SHA for diagnosability.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
toasterson changed title from WIP: Worktree-prep rebase parks items that vanilla git rebases cleanly — every main advance costs a hand-rebase to Worktree-prep rebase parks items that vanilla git rebases cleanly — every main advance costs a hand-rebase 2026-08-08 18:54:19 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
toasterson/Anima!533
No description provided.