DubStack
Commands

dub reorder

Interactively reorder or drop commits within the current branch, with cascading restack and undo.

dub reorder opens an interactive picker for the commits on the current branch and lets you move them up/down or mark them as drop. After the rebase, descendant branches are restacked onto the new tip and an undo entry is recorded so the whole operation rolls back in one step.

The picker is intentionally limited to reorder and drop. Editing, squashing, and rewording commits are out of scope:

  • Edit a commit's contents → dub modify --pop
  • Combine adjacent commits → dub squash
  • Reword a message → dub modify --amend -e

Usage

dub reorder

There are no flags — the command always opens a picker against the current branch.

What it does

  1. Validates the working tree is clean and the current branch is tracked.

  2. Lists commits between the branch's parent (per the tracked stack) and HEAD, newest first.

  3. Opens the picker. You can:

    • Move a commit up/down in the order.
    • Toggle drop on a commit to skip it during the rebase.
    • Finish to apply your changes.
    • Cancel to bail without rewriting history.
  4. If the picker exits unchanged, the command no-ops — no rebase runs.

  5. Otherwise, builds a custom git rebase --interactive todo with only pick and drop actions and runs the rebase with that todo applied.

  6. On rebase conflict, prompts with the same three-option dialog used by dub restack:

    • Continue resolving — leaves files in their conflicted state. The conflict happened inside the reorder rebase, so no restack-progress.json exists; resolve files, then run git rebase --continue, then dub restack to rebase descendants.
    • Cancel and roll back — aborts the rebase and resets the branch to its pre-reorder tip via the undo snapshot.
    • Exit — leaves the operation in its current state for manual handling.

    If instead the cascading restack of descendants hits a conflict (after the reorder itself completed cleanly), the standard dub continue / dub abort recovery applies, because that path did write a restack-progress.json.

  7. After a clean rebase, runs the standard restack to rebase descendants.

  8. Saves a reorder undo entry so dub undo reverts both the reordered branch and any descendants the cascading restack rewrote.

Examples

Reorder three commits (A, B, C → C, B, A) on the current branch:

dub reorder
# Picker:
#   [pick] ghi9012 C
#   [pick] def5678 B
#   [pick] abc1234 A
# Move each commit to the desired position, then "Finish".

Drop the middle commit:

dub reorder
# Picker:
#   [pick] ghi9012 C
#   [drop] def5678 B    <- toggled
#   [pick] abc1234 A
# Finish.

Roll back the most recent reorder:

dub undo
# ✔ Undid 'reorder': Restored N branches to pre-reorder state

Errors

SituationBehavior
Working tree has uncommitted changesFail with a hint to commit or stash.
Current branch is not trackedFail with a hint to run dub track.
Current branch is the stack rootFail — root branches don't carry commits to reorder.
Branch has zero commits beyond its parentFail — nothing to reorder.
Branch has exactly one commitFail — use dub modify for single-commit edits.
All commits marked as drop in the pickerPicker rejects the choice and loops; the rebase would otherwise empty the branch.
Rebase conflict (interactive TTY)Prompts with the standard dub restack three-option dialog (continue / cancel / exit).
Rebase conflict (non-interactive: CI, MCP, piped stdin)Resolves silently to "continue" — the rebase is paused mid-flight and dub reorder returns status: "conflict". Resolve manually then run git rebase --continue + dub restack (or git rebase --abort + dub undo to bail).
  • dub modify — edit, amend, or pop the latest commit.
  • dub restack — rebase descendants after a parent moves.
  • dub move — relocate a branch within its stack (not commits).
  • dub undo / dub redo — multi-level undo and redo of mutating commands (20-entry ring).

On this page