threads / discuss / 63973

Graphical tool to merge and reorder commits

Subject: Graphical tool to merge and reorder commits

## tl;dr

11 messages between Aug 17, 2025 and Aug 19, 2025.

replies: 10people: 7as markdown or json

R. Diez· Aug 17, 2025, 21:02 UTC · lore
Hi all:
I find merging and rewriting the commit history with Git difficult.
Is there some graphical tool to merge and reorder commits with the mouse? Or failing that, a good terminal interface with menus and the like which allows merging and reordering in an easy, visual fashion.
Here are more details about what I mean. Say I have this commit history:
  A - B - C [master]
I want to visually create a test branch first, by dragging commits B and C together (merging them), and then appending commit A afterwards:
  A - B - C [master]
  BC - A [test]
Maybe I need to manually merge or fix some commit in the middle of the test branch. I can do that with the normal Git tools and commands I already know. Then I want to keep visually adding commits to the test branch.
That is, I want to build the test branch mostly interactively with the mouse. While doing that, I would like to click on the nodes and see the commit messages and patches, like with git-gui.
If I manage to complete the test branch (and it compiles cleanly), I then want the test branch to become master, like this:
  A - B - C - D [now orphaned]
  BC - A [master]
Ideally, I could drag the tag, or right-click on one node and assign a tag.
I know I can probably find out all the relevant commit hashes by hand and do all the merging and rearranging with the command line, but even though I am normally a console and command-line fan, I find it especially hard with Git.
I have tried or investigated numerous Git tools: git-gui, gitk, Gittyup, GitUI, GitButler, SourceGit, git-cola, Guitar, gitg, tig, giggle, qgit, RabbitVCS, Magit, lazygit, ... They are all fine for normal commits and the like. However, most fall short fairly quickly. For example, the ability to highlight character or word-based changes inside a text line is rare. And none of them really appealed to me when merging, let alone rearrange commits visually.
Thanks in advance,
   rdiez
Konstantin Khomoutov· Aug 18, 2025, 18:04 UTC · re: R. Diez · lore

Re: Graphical tool to merge and reorder commits

(Sorry, I have nothing to say regarding the very question you have asked - as I personally do not need a tool you describe, but I have decided to chime in anyway in an attemt to correct what I perceive as a misunderstanding.)

On Sun, Aug 17, 2025 at 11:02:53PM +0200, R. Diez wrote:
[...]
Show 9 quoted lines
> Here are more details about what I mean. Say I have this commit history:
> 
>  A - B - C [master]
> 
> I want to visually create a test branch first, by dragging commits B and C
> together (merging them), and then appending commit A afterwards:
> 
>  A - B - C [master]
>  BC - A [test]

This is not merging, but rather is "squashing". Merging in Git (and in any other VCS I'm familiar with) is combining together one or more separate lines of history. In other words, something like

  A - B - C (master) - - M (new state of master)
                       /
  X - Y - Z (feature) -

would be a merge of the branch "feature" into the branch "master", with the commit M having two parent commits: C and Z.

Squasing, in turn, is combining textual changes introduced by multiple commits into a single textual change represented by a single commit.

[...]
> I have tried or investigated numerous Git tools
[...]
> They are all fine for normal commits and the like. However, most fall short
> fairly quickly. For example, the ability to highlight character or
> word-based changes inside a text line is rare. And none of them really
> appealed to me when merging, let alone rearrange commits visually.

Just a guess, but visual tools naturally tend to be tailored to the needs of inexperienced users - to lower the entry barrier, and what you're after, to me, appears to be a task not casually undertaken by the members of this group.

Creating such a tool properly - with some intuitive support for resolving cases when, - continuing your example - rearranging "BC" and "A" would make "A" fail to apply, and with unlimited undo expected from a GUI tool, wold not be an easy task.

Junio C Hamano· Aug 18, 2025, 18:34 UTC · re: R. Diez · lore

Re: Graphical tool to merge and reorder commits

"R. Diez" <rdiez-2006@rd10.de> writes:
Show 13 quoted lines
> Is there some graphical tool to merge and reorder commits with the
> mouse? Or failing that, a good terminal interface with menus and
> the like which allows merging and reordering in an easy, visual
> fashion.
> ...
> I have tried or investigated numerous Git tools: git-gui, gitk,
> Gittyup, GitUI, GitButler, SourceGit, git-cola, Guitar, gitg, tig,
> giggle, qgit, RabbitVCS, Magit, lazygit, ... They are all fine for
> normal commits and the like. However, most fall short fairly
> quickly. For example, the ability to highlight character or
> word-based changes inside a text line is rare. And none of them
> really appealed to me when merging, let alone rearrange commits
> visually.

It would be a fun little project to write a GUI front-end that emits "rebase -i" todo file and drives the interaction, if there is none already (which your research seems to indicate).

Sounds like you found a good starter project for the next GSoC or Outreachy students, I guess ;-)

Patrick Steinhardt· Aug 19, 2025, 08:07 UTC · re: Junio C Hamano · lore

Re: Graphical tool to merge and reorder commits

On Mon, Aug 18, 2025 at 11:34:21AM -0700, Junio C Hamano wrote:
Show 22 quoted lines
> "R. Diez" <rdiez-2006@rd10.de> writes:
> 
> > Is there some graphical tool to merge and reorder commits with the
> > mouse? Or failing that, a good terminal interface with menus and
> > the like which allows merging and reordering in an easy, visual
> > fashion.
> > ...
> > I have tried or investigated numerous Git tools: git-gui, gitk,
> > Gittyup, GitUI, GitButler, SourceGit, git-cola, Guitar, gitg, tig,
> > giggle, qgit, RabbitVCS, Magit, lazygit, ... They are all fine for
> > normal commits and the like. However, most fall short fairly
> > quickly. For example, the ability to highlight character or
> > word-based changes inside a text line is rare. And none of them
> > really appealed to me when merging, let alone rearrange commits
> > visually.
> 
> It would be a fun little project to write a GUI front-end that emits
> "rebase -i" todo file and drives the interaction, if there is none
> already (which your research seems to indicate).
> 
> Sounds like you found a good starter project for the next GSoC or
> Outreachy students, I guess ;-)

I might have something related to that: I've got a patch series cooking that introduces a `git history` command. With this you can say:

  $ git history reorder $COMMIT_A --(before|after) $COMMIT_B
  $ git history drop $COMMIT
  $ git history split $COMMIT

It's only intended as a starting point, and there's additional commands we can eventually think about. I'll probably send an initial version of this series later today.

Patrick
R. Diez· Aug 19, 2025, 08:35 UTC · re: Patrick Steinhardt · lore

Re: Graphical tool to merge and reorder commits

Show 10 quoted lines
> I might have something related to that: I've got a patch series cooking
> that introduces a `git history` command. With this you can say:
> 
>    $ git history reorder $COMMIT_A --(before|after) $COMMIT_B
>    $ git history drop $COMMIT
>    $ git history split $COMMIT
> 
> It's only intended as a starting point, and there's additional commands
> we can eventually think about. I'll probably send an initial version of
> this series later today.
This is good news indeed, thanks for your feedback.
I guess some "git history squash" command would be useful too.
This is what frequently happens to me:
- I commit some code changes because the current project builds and tests fine.
- I start the "compile all projects" process, which takes about 1 hour.
- In the meantime, I commit other unrelated changes.
- After an hour, I realise that a silly mistake in the first commit makes compilation fail for some project.
   I fix that and I trigger a "compile all projects" again, which takes 1 hour again.
- In the meantime, I commit yet another unrelated change.
- After yet another hour, the build process notifies me that I made yet another little mistake, and yet another project fails now.
The commit history looks like this:
- A - B - fixA1 - C - fixA2 - D - E
I only do a "git push" when the 1-hour compilation process succeeds. Before the "git push", I want to reorganise that into:
- A+fixA1+fixA2 - B - C - D - E
I know I can work with branches, but branches make everything more complicated. A linear history is easier, especially when you are working alone. Besides, it is not often that I make such silly mistakes. ;-)
Sometimes, fixing something in the Git repository is so complicated that it is not worth the trouble, so I leave an "unclean" history behind. For example, sometimes I have fixed merge problems by manually overwriting the code with the final new version, losing commit history in the process, in order to avoid having to deal with Git's idiosyncrasies.
Would it be possible to provide a "safe" way to do this "git history" operations? This is what I am thinking about:
1) Start with the messed up history:
- A - B - fixA1 - C - fixA2 - D - E [head]
2) Duplicate it:
- A - B - fixA1 - C - fixA2 - D - E [head]
| A - B - fixA1 - C - fixA2 - D - E [attempt]
3) Try to clean the history of [attempt] with the new "git history reorder" etc.
4) If successful, move [head] to [attempt], and we are done.
5) If not successful, drop [attempt] and possibly leave the messed up history in [head], because the cost of fixing it would be too high.
The first duplication step is what gives me the peace of mind that, if I screw something badly, I can always drop [attempt] and go back to my original state.
I know it would be better to learn Git "properly" and do things "right", but Git is often not very user friendly, and there are other priorities in life.
Regards,
   rdiez
Bernd Petrovitsch· Aug 19, 2025, 09:51 UTC · re: R. Diez · lore

Re: Graphical tool to merge and reorder commits

On 19.08.25 10:35, R. Diez wrote: [...]

Show 20 quoted lines
> I guess some "git history squash" command would be useful too.
> 
> This is what frequently happens to me:
> - I commit some code changes because the current project builds and tests fine.
> - I start the "compile all projects" process, which takes about 1 hour.
> - In the meantime, I commit other unrelated changes.
> - After an hour, I realise that a silly mistake in the first commit makes compilation fail for some project.
>    I fix that and I trigger a "compile all projects" again, which takes 1 hour again.
> - In the meantime, I commit yet another unrelated change.
> - After yet another hour, the build process notifies me that I made yet another little mistake, and yet another project fails now.
> 
> The commit history looks like this:
> 
> - A - B - fixA1 - C - fixA2 - D - E
> 
> I only do a "git push" when the 1-hour compilation process succeeds. Before the "git push", I want to reorganise that into:
> 
> - A+fixA1+fixA2 - B - C - D - E
> 
> I know I can work with branches, but branches make everything more complicated. A linear history is easier, especially when you are working alone. Besides, it is not often that I make such silly mistakes. ;-)
- `git rebase -i HEAD~11` (or so;-)
- move fixA1 and fixA2 under A and change "pick" to "fixup" for fixA1 and fixA2
- save and exit the editor
And done.
Kind regards,
	Bernd
-- 
Bernd Petrovitsch                  Email : bernd@petrovitsch.priv.at
      There is NO CLOUD, just other people's computers. - FSFE
                      LUGA : http://www.luga.at
Patrick Steinhardt· Aug 19, 2025, 11:05 UTC · re: Bernd Petrovitsch · lore

Re: Graphical tool to merge and reorder commits

On Tue, Aug 19, 2025 at 11:51:42AM +0200, Bernd Petrovitsch wrote:
Show 28 quoted lines
> On 19.08.25 10:35, R. Diez wrote:
> [...]
> > I guess some "git history squash" command would be useful too.
> > 
> > This is what frequently happens to me:
> > - I commit some code changes because the current project builds and tests fine.
> > - I start the "compile all projects" process, which takes about 1 hour.
> > - In the meantime, I commit other unrelated changes.
> > - After an hour, I realise that a silly mistake in the first commit makes compilation fail for some project.
> >    I fix that and I trigger a "compile all projects" again, which takes 1 hour again.
> > - In the meantime, I commit yet another unrelated change.
> > - After yet another hour, the build process notifies me that I made yet another little mistake, and yet another project fails now.
> > 
> > The commit history looks like this:
> > 
> > - A - B - fixA1 - C - fixA2 - D - E
> > 
> > I only do a "git push" when the 1-hour compilation process succeeds. Before the "git push", I want to reorganise that into:
> > 
> > - A+fixA1+fixA2 - B - C - D - E
> > 
> > I know I can work with branches, but branches make everything more complicated. A linear history is easier, especially when you are working alone. Besides, it is not often that I make such silly mistakes. ;-)
> 
> - `git rebase -i HEAD~11` (or so;-)
> - move fixA1 and fixA2 under A and change "pick" to "fixup" for fixA1 and fixA2
> - save and exit the editor
> 
> And done.

It's not really that this isn't doable. It's just not all that obvious for people who aren't experts, and it's not a straight-forward thing to do. I think the Git project could certainly use better tooling to make common workflows obvious and easy.

Anyway, the patch series is out now and can be found at [1].
Patrick
[1]: https://lore.kernel.org/git/20250819-b4-pks-history-builtin-v1-0-9b77c32688fe@pks.im/T/#t
R. Diez· Aug 19, 2025, 11:14 UTC · re: Bernd Petrovitsch · lore

Re: Graphical tool to merge and reorder commits

> - `git rebase -i HEAD~11` (or so;-)
> - move fixA1 and fixA2 under A and change "pick" to "fixup" for fixA1 and fixA2
> - save and exit the editor
I actually did not want to count commits or look at hashes, I wanted to comfortably click around to see the diffs etc. while I make the decisions.
After such posts, I wish people like you had to buy their next online plane or train ticket with curl. }8-)
But let's stay on the command line. I could learn new tricks.
> And done.
OK, git rebase was happy, everything is done.
And now it does not compile anymore.
You'd want to go back to the initial commit sequence and try another approach. But now it's gone, or at least it does not come up anymore in your git-gui. Or is it really gone? Maybe I can dig up the old commit sequence if I find the right Git commands... But that is what I wanted to avoid in the first place!
So I guess I should branch beforehand, just in case. And then move the head back, and rebase the commits there. Or the like. And don't squash yet, just in case. And then squash later, after everything compiles. My keyboard is on fire.
Ben Knoble· Aug 19, 2025, 12:08 UTC · re: R. Diez · lore

Re: Graphical tool to merge and reorder commits

Show 19 quoted lines
> Le 19 août 2025 à 07:28, R. Diez <rdiez-2006@rd10.de> a écrit :
> 
> 
>> - `git rebase -i HEAD~11` (or so;-)
>> - move fixA1 and fixA2 under A and change "pick" to "fixup" for fixA1 and fixA2
>> - save and exit the editor
> 
> I actually did not want to count commits or look at hashes, I wanted to comfortably click around to see the diffs etc. while I make the decisions.
> 
> After such posts, I wish people like you had to buy their next online plane or train ticket with curl. }8-)
> 
> But let's stay on the command line. I could learn new tricks.
> 
> 
>> And done.
> 
> OK, git rebase was happy, everything is done.
> 
> And now it does not compile anymore.
Perhaps there were conflicts? Reordering patches doesn’t guarantee any semantics about the code :)
> 
> You'd want to go back to the initial commit sequence and try another approach. But now it's gone, or at least it does not come up anymore in your git-gui. Or is it really gone? Maybe I can dig up the old commit sequence if I find the right Git commands... But that is what I wanted to avoid in the first place!
Try “git reflog <branch>”: it will show you that old commit.
> So I guess I should branch beforehand, just in case. And then move the head back, and rebase the commits there. Or the like. And don't squash yet, just in case. And then squash later, after everything compiles. My keyboard is on fire.
Exactly: this is what I call “defensive Git.” The objects are immutable, so when you spoke of duplicating head to attempt upthread, the best way to do so is to write down the commit hash (e.g., by labelling it with a branch). That’s “all” you have to do to duplicate.
Then you can rebase or perform some other history rewrite, which creates a brand new set of objects. If happy, abandon the old hash (e.g., delete the branch, which notably does not immediately delete the objects). Or if not, reset to the old commit and try again.
PS Have you tried using something like “commit --fixup/squash” and “rebase --autosquash [@{upstream}]” (or possibly “@{push}”—upstream is the default)? For me that automates most of the typical reordering I would do, although again conflicts are a possibility. 
Junio C Hamano· Aug 19, 2025, 16:33 UTC · re: Bernd Petrovitsch · lore

Re: Graphical tool to merge and reorder commits

Bernd Petrovitsch <bernd@petrovitsch.priv.at> writes:
Show 26 quoted lines
> On 19.08.25 10:35, R. Diez wrote:
> [...]
>> I guess some "git history squash" command would be useful too.
>> This is what frequently happens to me:
>> - I commit some code changes because the current project builds and tests fine.
>> - I start the "compile all projects" process, which takes about 1 hour.
>> - In the meantime, I commit other unrelated changes.
>> - After an hour, I realise that a silly mistake in the first commit makes compilation fail for some project.
>>    I fix that and I trigger a "compile all projects" again, which takes 1 hour again.
>> - In the meantime, I commit yet another unrelated change.
>> - After yet another hour, the build process notifies me that I made yet another little mistake, and yet another project fails now.
>> The commit history looks like this:
>> - A - B - fixA1 - C - fixA2 - D - E
>> I only do a "git push" when the 1-hour compilation process
>> succeeds. Before the "git push", I want to reorganise that into:
>> - A+fixA1+fixA2 - B - C - D - E
>> I know I can work with branches, but branches make everything more
>> complicated. A linear history is easier, especially when you are
>> working alone. Besides, it is not often that I make such silly
>> mistakes. ;-)
>
> - `git rebase -i HEAD~11` (or so;-)
> - move fixA1 and fixA2 under A and change "pick" to "fixup" for fixA1 and fixA2
> - save and exit the editor
>
> And done.

I hope we all know that ;-). But the question was if there is a GUI tool to let you do so without knowing how to move lines in your editor or how to edit "pick" and change it to "fixup", I think.

Johannes Sixt· Aug 19, 2025, 19:09 UTC · re: Junio C Hamano · lore

Re: Graphical tool to merge and reorder commits

Am 19.08.25 um 18:33 schrieb Junio C Hamano:
Show 15 quoted lines
> Bernd Petrovitsch <bernd@petrovitsch.priv.at> writes:
>> On 19.08.25 10:35, R. Diez wrote:
>>> - A - B - fixA1 - C - fixA2 - D - E
>>> [...]
>>> - A+fixA1+fixA2 - B - C - D - E
>>
>> - `git rebase -i HEAD~11` (or so;-)
>> - move fixA1 and fixA2 under A and change "pick" to "fixup" for fixA1 and fixA2
>> - save and exit the editor
>>
>> And done.
> 
> I hope we all know that ;-).  But the question was if there is a GUI
> tool to let you do so without knowing how to move lines in your
> editor or how to edit "pick" and change it to "fixup", I think.

Half-GUI is to keep `gitk --branches HEAD &` open for easy diff inspection and `git gui` next to it for easy staging of (partial) changes. The workflow is then

    # fix bugs
    # git gui: stage all or partial changes
    # gitk: search commit
    git commit --fixup 123abc
    # git gui: stage more changes
    # gitk: search commit
    git commit --fixup def456
    git rebase -i --autosquash HEAD~11   # or so ;)
    # fixup commits are already at the correct positions

Bonus feature: After staging, press F5 in gitk, select the green commit ("Local changes check in to the index..."), right-click in the diff panel on a removed line[*], select "Show origin of this line", and you are right at the commit that you want to fix up.

[*] works also for context lines, but it is less obvious which one to choose.

This workflow requires useful commit message summary lines. If you have only identical silly summaries like "fix bug" or "new feature", --autosquash doesn't know which one you mean.

-- Hannes

← back to recent threads