Skip to content

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

Merged
stefanhaller merged 7 commits into
masterfrom
drag-to-reorder-commits
Jul 31, 2026
Merged

Reorder commits (or rebase todos) by dragging with the mouse#5857
stefanhaller merged 7 commits into
masterfrom
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
@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
@stefanhaller
stefanhaller force-pushed the drag-to-select-range-in-lists branch from cc47740 to 8bb3563 Compare July 26, 2026 06:03
@stefanhaller
stefanhaller force-pushed the drag-to-reorder-commits branch from 0c44900 to 7c22021 Compare July 26, 2026 06:03
@stefanhaller
stefanhaller force-pushed the drag-to-select-range-in-lists branch from 8bb3563 to 42a52c0 Compare July 26, 2026 12:42
@stefanhaller
stefanhaller force-pushed the drag-to-reorder-commits branch from 7c22021 to 36aa165 Compare July 26, 2026 12:42
@stefanhaller
stefanhaller force-pushed the drag-to-select-range-in-lists branch from 42a52c0 to fee0560 Compare July 31, 2026 06:04
@stefanhaller
stefanhaller force-pushed the drag-to-reorder-commits branch from 36aa165 to f80d104 Compare July 31, 2026 06:04
@stefanhaller
stefanhaller force-pushed the drag-to-select-range-in-lists branch from fee0560 to 1443401 Compare July 31, 2026 06:32
Base automatically changed from drag-to-select-range-in-lists to master July 31, 2026 06:37
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.

Not used yet, we'll hook it up to the drag gesture in the next commit.
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-reorder-commits branch from f80d104 to 104fdf3 Compare July 31, 2026 06:37
@stefanhaller
stefanhaller enabled auto-merge July 31, 2026 06:37
@stefanhaller
stefanhaller merged commit 91dcd4c into master Jul 31, 2026
13 checks passed
@stefanhaller
stefanhaller deleted the drag-to-reorder-commits branch July 31, 2026 06:41
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Aug 11, 2026
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [jesseduffield/lazygit](https://github.com/jesseduffield/lazygit) | minor | `v0.63.1` → `v0.64.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>jesseduffield/lazygit (jesseduffield/lazygit)</summary>

### [`v0.64.0`](https://github.com/jesseduffield/lazygit/releases/tag/v0.64.0)

[Compare Source](jesseduffield/lazygit@v0.63.1...v0.64.0)

<!-- Release notes generated using configuration in .github/release.yml at v0.64.0 -->

#### What's Changed

This release has massive changes, but most of them should hopefully not be visible: I completely overhauled lazygit's concurrency model, which was, let's say, less than robust; there were lots of data races, and we were just lucky that this didn't result in crashes or misbehavior more often. We now have a robust concurrency model with no known data races, and in fact we run our integration test suite on CI with the `-race` flag to prove that. The user visible part of this is that some operations run a little more smoothly now; for example, there used to be an ugly spinner freeze at the end of checking out a branch, which is now gone.

However, since the changes were so massive there's a higher-than-usual chance of regressions, so please report any that you find.

Apart from that, we also have a few useful enhancements; the most notable one is probably that we now show the Github checks status of pull requests in the branches panel.

##### Enhancements 🔥

- Show a spinner for more long-running operations by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5765](jesseduffield/lazygit#5765)
- Remove the BLOCK\_UI refresh mode by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5790](jesseduffield/lazygit#5790)
- Support a `{{diffContext}}` template variable in external diff command by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5841](jesseduffield/lazygit#5841)
- Some small UI polish by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5853](jesseduffield/lazygit#5853)
- Auto-scroll when dragging to create range selection in staging view by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5855](jesseduffield/lazygit#5855)
- Create a range selection in list views by dragging with the mouse by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5856](jesseduffield/lazygit#5856)
- Reorder commits (or rebase todos) by dragging with the mouse by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5857](jesseduffield/lazygit#5857)
- Rework the custom pager config (rename to diff renderer) by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5870](jesseduffield/lazygit#5870)
- Show a Github MR's combined checks state in branches list (and main view for selected branch) by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5874](jesseduffield/lazygit#5874)

##### Fixes 🔧

- Fix stuck inline status when pushing/fetching by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5768](jesseduffield/lazygit#5768)
- Escape the merge conflicts view before prompting to continue the rebase by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5822](jesseduffield/lazygit#5822)
- Fix side panel rendering when branches/commits are not their panel's first tab by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5825](jesseduffield/lazygit#5825)
- Suppress output from a few git commands that pollute the command log by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5834](jesseduffield/lazygit#5834)
- Fix stall with ctrl+z and fg by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5830](jesseduffield/lazygit#5830)
- Fix more problems related to concurrent repo switch and background refresh by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5839](jesseduffield/lazygit#5839)
- Fix Windows crash when switching to fullscreen mode with a custom pager by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5838](jesseduffield/lazygit#5838)
- Fix multi-selection of files with common prefix not working in commit files panel by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5868](jesseduffield/lazygit#5868)
- Support absolute paths when detecting edit preset from EDITOR env var by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5876](jesseduffield/lazygit#5876)
- Exclude more commit trailers from auto-wrapping by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5871](jesseduffield/lazygit#5871)
- Prevent stale index.lock files from diffs rendered through a pty on Windows by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5888](jesseduffield/lazygit#5888)
- Fix orphaned processes on Windows when quickly navigating between commits by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5885](jesseduffield/lazygit#5885)

##### Maintenance ⚙️

- Perform refresh model and view updates on the UI thread instead of using mutexes by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5767](jesseduffield/lazygit#5767)
- Fix data race with status string by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5777](jesseduffield/lazygit#5777)
- Fix data race with command log by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5779](jesseduffield/lazygit#5779)
- Make integration tests using commits more robust by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5782](jesseduffield/lazygit#5782)
- Synchronize ViewBufferManager.Close with a starting task by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5786](jesseduffield/lazygit#5786)
- Make model<->view index conversions independent of rendering by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5785](jesseduffield/lazygit#5785)
- Fix idle notification deadlock by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5821](jesseduffield/lazygit#5821)
- Bump tcell to an unreleased snapshot to fix a shutdown race by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5824](jesseduffield/lazygit#5824)
- Fix command log streaming race by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5789](jesseduffield/lazygit#5789)
- Synchronize async view rendering by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5791](jesseduffield/lazygit#5791)
- Run tests with race detection on CI by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5792](jesseduffield/lazygit#5792)
- Gocui mouse event fixes by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5854](jesseduffield/lazygit#5854)
- Move Github MR cache out of state.yml into a separate file by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5884](jesseduffield/lazygit#5884)
- Make justfile commands available in the Nix development shell by [@&#8203;TyceHerrman](https://github.com/TyceHerrman) in [#&#8203;5890](jesseduffield/lazygit#5890)

##### Docs 📖

- Clarify contribution policy by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5809](jesseduffield/lazygit#5809)

##### I18n 🌎

- Update translations from Crowdin by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5891](jesseduffield/lazygit#5891)

##### Performance Improvements 📊

- Make scrolling down a very long diff with the scroll wheel much smoother by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5780](jesseduffield/lazygit#5780)

#### New Contributors

- [@&#8203;TyceHerrman](https://github.com/TyceHerrman) made their first contribution in [#&#8203;5890](jesseduffield/lazygit#5890)

**Full Changelog**: <jesseduffield/lazygit@v0.63.1...v0.64.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yODguMCIsInVwZGF0ZWRJblZlciI6IjQzLjI4OC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWlub3IiXX0=-->
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.

reorder commits using mouse drag

1 participant