Repository navigation
Improve moving commits across branch boundaries in a stack of branches - #6180
Open
stefanhaller wants to merge 8 commits into
Open
stefanhaller wants to merge 8 commits into
stefanhaller wants to merge 8 commits into
Conversation
When moving commits outside of a rebase, we will need to know where the branch boundaries of a stack are. These are the heads of the branches that the commits list marks, so we want to use the same rule there. Put the rule in the branchstack package. BranchesBelow had its own copy of it, so use it there too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
If a range of selected commits spans the boundary between two branches of a stack, moving it outside of a rebase moves each of its commits separately past the next commit. The update-ref todo inside the range stays behind. In the test, branch2 is left without any commits of its own after moving the range up, and its commits now belong to branch3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Outside of a rebase, we move commits by a number of rows, skipping the update-ref todos that we don't show. This can't move a commit past the update-ref todos only. We will need that for moving a commit to the end of the branch below it in a stack. It also moves each commit separately, so the update-ref todos between the moved commits stay behind. MoveCommitsTo names the commit that the moved commits are to sit on, and which of the branches that point at that commit are to point at the moved commits instead. The update-ref todos between the moved commits move along with them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
If a range of selected commits spans the boundary between two branches of a stack, moving it outside of a rebase leaves the update-ref todo between them behind. This is because each commit is moved past the next commit separately. As a result, the lower branch loses its commits to the one above it. Move the commits with MoveCommitsTo instead. It moves the update-ref todos between the commits along with them. It also needs to know which branches point at the commit that the moved commits go on top of. These are the branches that the commits list marks, except for those that git doesn't update in a rebase. Otherwise, moving commits up or down and dropping dragged commits work as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moving commits outside of a rebase now names the commit that they go on top of, so nothing moves them by a number of rows any more. Moving todos by a number of rows is left only for the rebase todo, where update-ref and exec todos are rows of their own. MoveTodosDown and MoveTodosUp of RebaseCommands were unused already; remove them too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
To add a commit at the end of a lower branch of a stack, the obvious way is to create it at the top of the stack and move it down. Outside of a rebase, pressing ctrl+j doesn't get it there. Once the commit is at the bottom of the second branch, the next ctrl+j moves it past the update-ref todo of the first branch and past that branch's last commit. We made it work like this deliberately in #4096. Moving the commit past the update-ref todo only would have required keeping the selection where it is, and this was hard to do. Now that the destination of a move is named explicitly, it is easy. So if the commit below the selected commits is the head of branches of the stack, ctrl+j now moves them past the update-ref todos of all these branches at once, and keeps them selected. The branch marker moves up to the bottom selected commit. The next ctrl+j moves them further into the lower branch. ctrl+k does the same the other way round: if the topmost selected commit is the head of branches, it moves the commits past their update-ref todos first, to the start of the branch above. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dragging the first commit above the view, or the last commit below the end of the list, must not offer to drop them there, because that wouldn't move them anywhere. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Outside of a rebase, dragging a commit of a stack down to below the last commit of the branch above puts it at the start of that branch. There is no way to drop it at the end of the branch below instead, because the update-ref todos between the two branches are not shown. Show a row for each of these update-ref todos while dragging, and let the drop indicator go between them. The row is a horizontal line across the hash column, followed by the name of the branch. This also makes it possible to drop a commit between the rows of two branches that point at the same commit. The rows appear only once the pointer has left the pressed row. Rows that appear above the pressed commit push it down, so a click with a slight sideways movement could otherwise offer to drop the commit somewhere else. We don't scroll the view to keep the pressed commit under the pointer. If the drag is canceled, this would leave the first commit of the list scrolled out of view, and this is easy to miss. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
stefanhaller
force-pushed
the
improve-moving-commits-across-branch-boundaries-in-stack
branch
from
November 8, 2026 13:28
2e76e16 to
53cf6f6
Compare
This branch has not been deployed
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.
When moving commits in a stack of branches, it can be unclear whether a moved commit goes before or after a branch head; in other words, whether it goes at the end of one branch or at the beginning of the next. The workaround is to type
ito enter an interactive rebase for the whole stack; this will show "update-ref" todos for the branch heads, which gives you control over where exactly a commit goes by moving it before or after those "update-ref" todos.This PR adds two improvements to doing this outside of a rebase:
<ctrl+j>or<ctrl+k>and you hit a branch boundary, the next keypress moves the commit only across the boundary. The commit's position in the list stays the same, only the branch icon moves. This is the opposite of what Fix moving a commit across a branch boundary in a stack of branches #4096 did, but it was mentioned there as one possible (and probably the preferred) option; we just didn't manage to implement it back then.This also fixes a bug: when moving a range selection of commits that spans a branch boundary, this broke the stack because it didn't move the update-ref todos along with the commits.