Re: [PATCH v5 0/3] Teach git-replay(1) to linearize merge commits
- From
Johannes Schindelin <johannes.schindelin@gmx.de>
- Date
- Jun 28, 2026, 12:20 UTC
- Message-ID
- <f8b520d1-edeb-9e45-c503-025c8b5833c3@gmx.de>
- In-Reply-To
- <20260626-toon-git-replay-drop-merges-v5-0-5e120738b9d0@iotcl.com>
Hi Toon,
On Fri, 26 Jun 2026, Toon Claes wrote:
Show 5 quoted lines
> - (BIGGEST CHANGE) When working on a refactor to undo the enum->bool > patch, I extended the code comments to explain how things work. This > made me realize the use of the "replayed_base" was incorrect when > multiple branches are rebased with --onto. This is fixed now and a > test is added for this scenario.
I am not quite certain that this results in the desired outcome when working with a single branch that contains a merge commit. Take for example this topology (master~2..master at the time of writing):
* 6c3d7b73556d Merge branch 'ps/t4216-tap-fix' |\ | * f0411a4c717e t4216: fix no-op test that breaks TAP output * | ab776a62a785 Git 2.55-rc2 o | 1ea786d14a1b Merge branch 'hn/macos-linker-warning' / o 08b6ae38c602 t4216: test changed path filters with high bit paths
Running `git replay --linearize --onto master~2 master~2..master` used to result in this:
* 3ec7cc3e73c0 t4216: fix no-op test that breaks TAP output * 8dca9f98dc05 Git 2.55-rc2 o 1ea786d14a1b Merge branch 'hn/macos-linker-warning'
which is what I would expect. But now, due to the dropped `replayed_base`, that tip commit is replayed directly on top of `onto` and the first replayed commit ("Git 2.55-rc2") is simply (and inadvertently) dropped:
* 5e4899a3e03c t4216: fix no-op test that breaks TAP output o 1ea786d14a1b Merge branch 'hn/macos-linker-warning'
I had originally introduced that `replayed_base` specifically to prevent this commit-dropping.
As to the question what should happen if multiple branches are replayed at the same time with `--linearize`: This is a very tricky problem. Naively, one would want all of those branches to be linearized _individually_. But that idea breaks down when you replay three branches, two of them with distinct commits, and the third branch a merge of the first two:
* Branch C: merge branches A and B |\ | * Branch B * | Branch A |/ o onto
What should the replayed branch C look like? Should it have A' and B' in that order? I.e. share the rewritten commit with the replayed branch A? But then B' could not be the replayed B because that needs to be directly on top of onto.
So I fear that the `replayed_base` design _is_ needed, and the only way `git replay --linearize` can work with multiple branches is by linearizing all of the replayed commits into one single, linear commit topology.
Obviously, there are ways one could _try_ to rescue the previous idea, so that at least replaying just branches A and B would keep the replayed commits non-reachable from each other, but I strongly suspect that any such design will invariably surprise users in nasty ways when the logic has to fall back to the simple idea I outlined anyway.
Ciao, Johannes