Thread (61 messages) 61 messages, 7 authors, 6d ago

Re: [PATCH v5 0/3] Teach git-replay(1) to linearize merge commits

From: Johannes Schindelin <hidden>
Date: 2026-06-28 12:20:20

Hi Toon,

On Fri, 26 Jun 2026, Toon Claes wrote:
- (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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help