Skip to content

fix(transaction): roll back what a refused rebase already changed - #296

Merged
narnaud merged 1 commit into
mainfrom
fix-preflight-rollback
Sep 22, 2026
Merged

narnaud merged 1 commit into
mainfrom
fix-preflight-rollback

Conversation

@narnaud

@narnaud narnaud commented Sep 21, 2026

Copy link
Copy Markdown
Owner

roll_back_failed_rebase skipped the whole rollback whenever the rebase never
started, on the grounds that a pre-flight refusal autostashed nothing and the
index was never loom's. That holds for the callers that only build a weave
first, but not for commit, which makes its commit and empties the index
before the rebase exists, nor for absorb, which makes its fixup! commits.
Both left those commits stranded and their staging and working tree behind,
with the state file deleted so loom abort had nothing to read.

A recorded reset_mixed_to or reset_hard_to is exactly the mark of a caller
that moved HEAD itself before the rebase, so it is what decides now. With
neither, the shortcut stands: the index is the user's and replaying the saved
patch over it would double their staging.

Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
Change-Id: If2e9e05c0031a4d1a48d01ce6117fcde71664c38

Summary by CodeRabbit

  • Bug Fixes
    • Improved recovery when operations cannot begin because the target branch is checked out in another worktree.
    • Failed operations now more reliably restore commits, working-tree changes, staged changes, and transaction state.
    • Abort handling now distinguishes between operations that made no repository changes and those that moved commits.
    • Existing staged changes are preserved when no rollback reset is required.
  • Documentation
    • Documented rollback behavior for failed rebase attempts.

`roll_back_failed_rebase` skipped the whole rollback whenever the rebase never
started, on the grounds that a pre-flight refusal autostashed nothing and the
index was never loom's. That holds for the callers that only build a weave
first, but not for `commit`, which makes its commit and empties the index
before the rebase exists, nor for `absorb`, which makes its `fixup!` commits.
Both left those commits stranded and their staging and working tree behind,
with the state file deleted so `loom abort` had nothing to read.

A recorded `reset_mixed_to` or `reset_hard_to` is exactly the mark of a caller
that moved HEAD itself before the rebase, so it is what decides now. With
neither, the shortcut stands: the index is the user's and replaying the saved
patch over it would double their staging.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Change-Id: If2e9e05c0031a4d1a48d01ce6117fcde71664c38
@coderabbitai

coderabbitai Bot commented Sep 21, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Understand this PR’s impact

Explore downstream dependencies and potential security impact with Blast Radius.

View 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: 35df0ef3-593b-4246-bb30-2e50a009ac91

📥 Commits

Reviewing files that changed from the base of the PR and between bd487de and 3ad5db3.

📒 Files selected for processing (5)
  • CLAUDE.md
  • specs/014-continue-abort.md
  • src/absorb_test.rs
  • src/commit_test.rs
  • src/core/transaction.rs

Included review availability: Your plan provides up to 10 included reviews per hour; 5 remain after this review.


📝 Walkthrough

Walkthrough

Failed rebase cleanup now distinguishes refusals before HEAD movement from failures that require a full rollback. Specifications and documentation define the rules. Regression tests verify restoration of commits, staged changes, working-tree content, and transaction state.

Changes

Failed rebase rollback behavior

Layer / File(s) Summary
Rollback rules and implementation
specs/014-continue-abort.md, src/core/transaction.rs, CLAUDE.md
Rollback detects mixed or hard reset targets. Pre-flight refusals without a reset target preserve existing staged changes, while operations that moved HEAD use the full rollback path.
Pre-flight refusal regression coverage
src/absorb_test.rs, src/commit_test.rs, src/core/transaction.rs
Tests verify restoration of HEAD, working-tree content, staged changes, and removal of loom/state.json after rebase refusal.

Priority: ⬇️ Low

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

Change: Bug fix

Suggested reviewers: dfaure-kdab

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
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: rolling back changes made before a rebase refusal.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 3 files. (2 skipped: 2 …
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.

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

@narnaud
narnaud merged commit 1a2e3c1 into main Sep 22, 2026
6 checks passed
@narnaud
narnaud deleted the fix-preflight-rollback branch September 22, 2026 09:46
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.

2 participants