Skip to content

Reorder commits (or rebase todos) by dragging with the mouse#5857

Open
stefanhaller wants to merge 7 commits into
drag-to-select-range-in-listsfrom
drag-to-reorder-commits
Open

Reorder commits (or rebase todos) by dragging with the mouse#5857
stefanhaller wants to merge 7 commits into
drag-to-select-range-in-listsfrom
drag-to-reorder-commits

Conversation

@stefanhaller

Copy link
Copy Markdown
Collaborator

Pressing the left button on the current selection now starts a drag that moves the selected commits, both in the normal commits view and for todos during an interactive rebase. A press on an unselected row still creates a range selection.

While dragging, a "drop here" indicator shows where the commits will be inserted.

Moving commits with the mouse is useful for the case that you want to move them a longer distance, because that's slow when doing it one by one with the keyboard, and also you don't want to resolve conflicts at every step. The standard workaround for that is to enter an interactive rebase first and then continue it afterwards, but that's a bit cumbersome; dragging solves that nicely.

Closes #5842.

@stefanhaller stefanhaller added the enhancement New feature or request label Jul 25, 2026
@stefanhaller
stefanhaller force-pushed the drag-to-reorder-commits branch from 0000be6 to 6ac2d43 Compare July 25, 2026 10:28
Merge the up/down variants of the move commands into one
direction-parameterized implementation. Dragging commits is about to
need moves over arbitrary distances, which we don't want to build twice.
Let the todo-move primitives take a distance instead of hardcoding a
single row, by iterating the one-row move in memory. Dropping a commit
several rows away thus rewrites the todo file once and, outside of an
interactive rebase, runs a single rebase rather than one per row.
Render the insertion point of a commit drag as a non-model item in the
commits list. It must be inserted at the right position relative to
the section headers, because the list renderer assumes non-model items
are ordered by their model index.
Pressing the left button on the current selection now starts a drag
that moves the selected commits, both in the normal commits view and
for todos during an interactive rebase. A press anywhere else falls
through to the usual click handling, so dragging from an unselected
line still creates a range selection, and releasing without having
moved collapses the selection to the pressed commit like a plain click
would.

While dragging, the insertion point follows the pointer: rows below
the dragged block insert after the pointed-at commit, rows above it
insert before it, and during a rebase the destination is limited to
the contiguous block of movable todos around the selection. gocui
moves the view cursor along with the pointer, so each drag event moves
it back to keep the original selection highlighted.

The move happens on release. The model may have been refreshed during
the drag, so the dragged commits are located again by their identity
(hash, subject, todo action); if they no longer form a unique
contiguous block, the drop is ignored rather than guessing.
Reuse the drag autoscroller for commit drags. Scrolling stops once the
insertion point reaches the end of the allowed range in the scroll
direction, so during a rebase the view doesn't keep scrolling once the
last insertion position among the todos has been reached.
While a commit drag is in progress, escape now aborts it: the drag
state and the drop indicator are discarded and the mouse capture is
released, so nothing happens when the button is eventually released.
Otherwise escape keeps its normal meaning.
Moving commits runs a rebase, which can take a while. Instead of
letting the drop indicator vanish the moment the button is released,
keep it in place and turn it into a "moving commits here" spinner once
the move takes longer than a short grace period, so that quick moves
stay free of flicker. The indicator is cleared when the post-move
refresh lands.
@stefanhaller
stefanhaller force-pushed the drag-to-select-range-in-lists branch from d952ae8 to cc47740 Compare July 25, 2026 16:15
@stefanhaller
stefanhaller force-pushed the drag-to-reorder-commits branch from 6ac2d43 to 0c44900 Compare July 25, 2026 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant