feat(reorder): add squash/fixup commands and autosquash for fixup! commits#709
Conversation
…mmits Add squash (s) and fixup (f) commands to av reorder, matching git rebase -i behavior. squash folds the cherry-picked commit into the previous one and opens the editor with combined messages; fixup does the same but silently keeps the previous commit's message. Commits created with git commit --fixup (fixup! prefix) or git commit --squash (squash! prefix) are automatically repositioned after their target commit and pre-assigned the appropriate action when the plan is generated, matching git's --autosquash behavior. Also handles conflict continuation correctly: when av reorder --continue is run after a squash/fixup conflict, the folding step is performed before advancing past the interrupted command. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Current Aviator status
This PR was merged using Aviator.
See the real-time status of this PR on the
Aviator webapp.
Use the Aviator Chrome Extension
to see the status of your PR within GitHub.
|
There was a problem hiding this comment.
Code Review
This pull request introduces support for squash and fixup commands within the reorder workflow, including an "autosquash" feature that automatically reorders commits with "fixup!" or "squash!" prefixes. The changes include updates to the command parser, the addition of a PerformSquash method to handle commit amending via git reset --soft, and logic in the plan generation to support automatic reordering. Feedback was provided regarding the PerformSquash implementation, specifically noting that it should strip comment lines from the edited commit message to align with standard Git behavior.
golangci-lint v2.10.1 nolintlint no longer accepts //nolint: <linter> (with space); use //nolint:<linter> instead. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Track SquashPending in Continuation so --continue only calls PerformSquash when a squash/fixup was actually interrupted, preventing double-squash when users resolve conflicts manually - Guard PerformSquash against squash/fixup as first commit in a branch - Fix os.Stat calls to distinguish IsNotExist from real filesystem errors - Add explicit switch with default error case in PerformSquash to reject unknown PickMode values - Return ErrInterruptReorder (with --continue hint) when squash message is empty, instead of hard-failing and losing reorder state - Wrap git reset/amend errors with commit hash and mode for context - Wrap getCommitMessage errors with the failing revision - Annotate unmatched fixup!/squash! commits with a visible warning in the reorder editor - Add behavioral tests: PerformSquash fixup path, first-commit guard, JSON round-trip for squash/fixup modes, Execute fixup mode, and autosquash edge cases (fixup before target, mixed fixup+squash) Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
✅ FlexReview StatusCommon Owner:
Review SLO: |
…oundaries Replace per-branch autosquashPickCmds with a global autosquashCmds that operates on the full []Cmd slice. This allows a fixup!/squash! commit in one branch to be moved right after its target commit in any other branch of the stack, rather than being left at the end of the branch it originated in. Also removes the two-pass stackTitles collection that was added as an intermediate step. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Two critical safety fixes for the squash/fixup reorder feature: 1. Guard against cherry-pick abort/skip before PerformSquash: when --continue is called after a squash/fixup conflict, verify that HEAD has advanced past state.Head before calling PerformSquash. If HEAD hasn't moved (user ran 'git cherry-pick --abort' or '--skip'), PerformSquash would amend the wrong commit — now an explicit error directs the user to 'av reorder --abort' instead. 2. Guard against folding across the branch boundary: PerformSquash now accepts a branchBase parameter (populated from State.BranchBase, set by StackBranchCmd). If HEAD~1 equals the branch base commit, the cherry-picked commit is the first pick in its branch section and folding would amend the parent branch's tip — now an explicit error is returned instead of silently rewriting the wrong commit. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
| // annotated with a warning so the user can see the problem in the editor. | ||
| for _, fixIdx := range unplaced { | ||
| fixPick := cmds[fixIdx].(PickCmd) | ||
| fixPick.Mode = fixups[fixIdx].mode |
There was a problem hiding this comment.
Perhaps this is better to be PickModePick so that it won't accidentally amend the commit prior to that branch?
When a fixup!/squash! commit has no matching target in the stack, fall back to PickModePick instead of keeping the fixup/squash mode to avoid accidentally squashing into an unrelated commit. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Add squash (s) and fixup (f) commands to av reorder, matching git rebase -i behavior. squash folds the cherry-picked commit into the previous one and opens the editor with combined messages; fixup does the same but silently keeps the previous commit's message.
Commits created with git commit --fixup (fixup! prefix) or git commit --squash (squash! prefix) are automatically repositioned after their target commit and pre-assigned the appropriate action when the plan is generated, matching git's --autosquash behavior.
Also handles conflict continuation correctly: when av reorder --continue is run after a squash/fixup conflict, the folding step is performed before advancing past the interrupted command.
Fixes #706