Reorder commits (or rebase todos) by dragging with the mouse - #5857
Merged
Conversation
stefanhaller
force-pushed
the
drag-to-reorder-commits
branch
from
July 25, 2026 10:28
0000be6 to
6ac2d43
Compare
stefanhaller
force-pushed
the
drag-to-select-range-in-lists
branch
from
July 25, 2026 16:15
d952ae8 to
cc47740
Compare
stefanhaller
force-pushed
the
drag-to-reorder-commits
branch
from
July 25, 2026 16:17
6ac2d43 to
0c44900
Compare
stefanhaller
force-pushed
the
drag-to-select-range-in-lists
branch
from
July 26, 2026 06:03
cc47740 to
8bb3563
Compare
stefanhaller
force-pushed
the
drag-to-reorder-commits
branch
from
July 26, 2026 06:03
0c44900 to
7c22021
Compare
stefanhaller
force-pushed
the
drag-to-select-range-in-lists
branch
from
July 26, 2026 12:42
8bb3563 to
42a52c0
Compare
stefanhaller
force-pushed
the
drag-to-reorder-commits
branch
from
July 26, 2026 12:42
7c22021 to
36aa165
Compare
stefanhaller
force-pushed
the
drag-to-select-range-in-lists
branch
from
July 31, 2026 06:04
42a52c0 to
fee0560
Compare
stefanhaller
force-pushed
the
drag-to-reorder-commits
branch
from
July 31, 2026 06:04
36aa165 to
f80d104
Compare
stefanhaller
force-pushed
the
drag-to-select-range-in-lists
branch
from
July 31, 2026 06:32
fee0560 to
1443401
Compare
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
force-pushed
the
drag-to-reorder-commits
branch
from
July 31, 2026 06:37
f80d104 to
104fdf3
Compare
stefanhaller
enabled auto-merge
July 31, 2026 06:37
1 task
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 [@​stefanhaller](https://github.com/stefanhaller) in [#​5765](jesseduffield/lazygit#5765) - Remove the BLOCK\_UI refresh mode by [@​stefanhaller](https://github.com/stefanhaller) in [#​5790](jesseduffield/lazygit#5790) - Support a `{{diffContext}}` template variable in external diff command by [@​stefanhaller](https://github.com/stefanhaller) in [#​5841](jesseduffield/lazygit#5841) - Some small UI polish by [@​stefanhaller](https://github.com/stefanhaller) in [#​5853](jesseduffield/lazygit#5853) - Auto-scroll when dragging to create range selection in staging view by [@​stefanhaller](https://github.com/stefanhaller) in [#​5855](jesseduffield/lazygit#5855) - Create a range selection in list views by dragging with the mouse by [@​stefanhaller](https://github.com/stefanhaller) in [#​5856](jesseduffield/lazygit#5856) - Reorder commits (or rebase todos) by dragging with the mouse by [@​stefanhaller](https://github.com/stefanhaller) in [#​5857](jesseduffield/lazygit#5857) - Rework the custom pager config (rename to diff renderer) by [@​stefanhaller](https://github.com/stefanhaller) in [#​5870](jesseduffield/lazygit#5870) - Show a Github MR's combined checks state in branches list (and main view for selected branch) by [@​stefanhaller](https://github.com/stefanhaller) in [#​5874](jesseduffield/lazygit#5874) ##### Fixes 🔧 - Fix stuck inline status when pushing/fetching by [@​stefanhaller](https://github.com/stefanhaller) in [#​5768](jesseduffield/lazygit#5768) - Escape the merge conflicts view before prompting to continue the rebase by [@​stefanhaller](https://github.com/stefanhaller) in [#​5822](jesseduffield/lazygit#5822) - Fix side panel rendering when branches/commits are not their panel's first tab by [@​stefanhaller](https://github.com/stefanhaller) in [#​5825](jesseduffield/lazygit#5825) - Suppress output from a few git commands that pollute the command log by [@​stefanhaller](https://github.com/stefanhaller) in [#​5834](jesseduffield/lazygit#5834) - Fix stall with ctrl+z and fg by [@​stefanhaller](https://github.com/stefanhaller) in [#​5830](jesseduffield/lazygit#5830) - Fix more problems related to concurrent repo switch and background refresh by [@​stefanhaller](https://github.com/stefanhaller) in [#​5839](jesseduffield/lazygit#5839) - Fix Windows crash when switching to fullscreen mode with a custom pager by [@​stefanhaller](https://github.com/stefanhaller) in [#​5838](jesseduffield/lazygit#5838) - Fix multi-selection of files with common prefix not working in commit files panel by [@​stefanhaller](https://github.com/stefanhaller) in [#​5868](jesseduffield/lazygit#5868) - Support absolute paths when detecting edit preset from EDITOR env var by [@​stefanhaller](https://github.com/stefanhaller) in [#​5876](jesseduffield/lazygit#5876) - Exclude more commit trailers from auto-wrapping by [@​stefanhaller](https://github.com/stefanhaller) in [#​5871](jesseduffield/lazygit#5871) - Prevent stale index.lock files from diffs rendered through a pty on Windows by [@​stefanhaller](https://github.com/stefanhaller) in [#​5888](jesseduffield/lazygit#5888) - Fix orphaned processes on Windows when quickly navigating between commits by [@​stefanhaller](https://github.com/stefanhaller) in [#​5885](jesseduffield/lazygit#5885) ##### Maintenance ⚙️ - Perform refresh model and view updates on the UI thread instead of using mutexes by [@​stefanhaller](https://github.com/stefanhaller) in [#​5767](jesseduffield/lazygit#5767) - Fix data race with status string by [@​stefanhaller](https://github.com/stefanhaller) in [#​5777](jesseduffield/lazygit#5777) - Fix data race with command log by [@​stefanhaller](https://github.com/stefanhaller) in [#​5779](jesseduffield/lazygit#5779) - Make integration tests using commits more robust by [@​stefanhaller](https://github.com/stefanhaller) in [#​5782](jesseduffield/lazygit#5782) - Synchronize ViewBufferManager.Close with a starting task by [@​stefanhaller](https://github.com/stefanhaller) in [#​5786](jesseduffield/lazygit#5786) - Make model<->view index conversions independent of rendering by [@​stefanhaller](https://github.com/stefanhaller) in [#​5785](jesseduffield/lazygit#5785) - Fix idle notification deadlock by [@​stefanhaller](https://github.com/stefanhaller) in [#​5821](jesseduffield/lazygit#5821) - Bump tcell to an unreleased snapshot to fix a shutdown race by [@​stefanhaller](https://github.com/stefanhaller) in [#​5824](jesseduffield/lazygit#5824) - Fix command log streaming race by [@​stefanhaller](https://github.com/stefanhaller) in [#​5789](jesseduffield/lazygit#5789) - Synchronize async view rendering by [@​stefanhaller](https://github.com/stefanhaller) in [#​5791](jesseduffield/lazygit#5791) - Run tests with race detection on CI by [@​stefanhaller](https://github.com/stefanhaller) in [#​5792](jesseduffield/lazygit#5792) - Gocui mouse event fixes by [@​stefanhaller](https://github.com/stefanhaller) in [#​5854](jesseduffield/lazygit#5854) - Move Github MR cache out of state.yml into a separate file by [@​stefanhaller](https://github.com/stefanhaller) in [#​5884](jesseduffield/lazygit#5884) - Make justfile commands available in the Nix development shell by [@​TyceHerrman](https://github.com/TyceHerrman) in [#​5890](jesseduffield/lazygit#5890) ##### Docs 📖 - Clarify contribution policy by [@​stefanhaller](https://github.com/stefanhaller) in [#​5809](jesseduffield/lazygit#5809) ##### I18n 🌎 - Update translations from Crowdin by [@​stefanhaller](https://github.com/stefanhaller) in [#​5891](jesseduffield/lazygit#5891) ##### Performance Improvements 📊 - Make scrolling down a very long diff with the scroll wheel much smoother by [@​stefanhaller](https://github.com/stefanhaller) in [#​5780](jesseduffield/lazygit#5780) #### New Contributors - [@​TyceHerrman](https://github.com/TyceHerrman) made their first contribution in [#​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=-->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.