git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: merge-ort and --rebase-merges, was Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges

From
Elijah Newren <newren@gmail.com>
Date
Sep 13, 2021, 15:53 UTC
Message-ID
<CABPp-BHp+d62dCyAaJfh1cZ8xVpGyb97mZryd02aCOX=Qn=Ltw@mail.gmail.com>
In-Reply-To
<nycvar.QRO.7.76.6.2109131319020.55@tvgsbejvaqbjf.bet>

On Mon, Sep 13, 2021 at 4:24 AM Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

Show 10 quoted lines
>
> Hi Elijah,
>
> On Fri, 10 Sep 2021, Elijah Newren wrote:
>
> > On Fri, Sep 10, 2021 at 5:08 AM Johannes Schindelin
> > <Johannes.Schindelin@gmx.de> wrote:
> > >
> > > On Tue, 7 Sep 2021, Elijah Newren wrote:
> > >
[...snip...]
Show 27 quoted lines
> > If I've understood that all correctly, then my idea will give you the
> > following conflict to resolve:
> >
> > ==> rebase-of-original-merge, before conflict resolution:
> > int hi(void) {
> >     printf("Hello, world!\n");
> > }
> > /* main event loop */
> > void event_loop(void) {
> >     /* TODO: place holder for now */
> > }
> > /* caller */
> > void caller(void) {
> > <<<<<<< HEAD
> >     greeting();
> > ||||||| auto-remerge of original-merge
> >     core();
> > =======
> >     hi();
> > >>>>>>> original-merge
> > }
>
> That looks very intriguing! I would _love_ to play with this a bit, and I
> think you provided enough guidance to get going. I am currently preparing
> to go mostly offline for the second half of September, read: I won't be
> able to play with this before October. But I am definitely interested,
> this sounds very exciting.

If you start working on it, let me know. I was thinking of playing with it, but don't know exactly when I'll get time to do so; very unlikely before October, and reasonably likely not even before the end of the year.

While I've provided the high level details in this thread which are good enough to handle the simple cases, I think that the interesting bits are the non-simple cases. I have not thought all of them through, but I'll include below some notes of mine that might be helpful if you get to it first. Note that I focus below on the non-simple cases, and discuss content-based conflicts before covering path-based ones:

* We're doing a three way merge of merges: pre-M, M, and N to get R; M
is the original merge, pre-M is (automatic) remerge of M, and N is
automatic merge of rebased parents of M.
* Note that N is what current rebase-merges uses, so we have all
information from that merge and can provide it to the user when or if
it is helpful.
* Both pre-M and N may themselves have conflicts.
* We need to programmatically handle conflict marker length when pre-M
and/or N have nested conflicts.  (must modify merge routines to return
the maximal conflict marker depth used)
* Special case that pre-M matches N (per hunk): If both pre-M and N
have conflict markers, but they happen to match, then we know to take
the version from M and the result IS clean (at least for that hunk).
So, you can still get a clean merge even if there are conflicts in
both pre-M and N.
* Special case that pre-M matches M (per hunk): Usually in the
three-way merge of "Base, Left, Right => Result", if Base matches
either side then you get a clean merge.  However, if pre-M matches M
but N has conflicts, the result is NOT clean.  Another way to look at
this is that conflict markers are special and should be treated
differently than other lines.  (And path-based conflicts probably need
special handling too, as discussed below.)
* In the case of complicated conflicts, consider providing user with
both R:resulting-file and N:resulting-file (and point them at `git log
-1 --remerge-diff M [-- resulting-file]`)
* Having either binary files or path-based conflicts (e.g.
modify/delete, file vs. directory vs. submodule, switch to symlink vs.
switch to executable, rename/add, rename/rename -- either 1to2 or
2to1, directory rename detection, etc.) in either pre-M or N -- or
both -- are going to need special care.
* One example of path-based conflicts:  Let's say pre-M had no
conflict at path P, and that pre-M:P and M:P matched.  Let's say that
N:P had a modify/delete conflict.  Note that for modify/delete
conflicts we tend to print a message to the console and leave the
modified version of the file in the working tree.  Here, despite the
fact that pre-M:P and M:P matched, we cannot just take the modified
file from N at P as the merge result.  The modify/delete conflict
should persist and the user given an opportunity to resolve it.
Representing the modify/delete might be an interesting question,
though since...
* If both pre-M and N have conflicts, then pre-M would have had up to
three versions of file in the index at higher stages, N would have had
up to three versions of file in the index at higher stages, and M
would have one.  We cannot represent all 7 versions of the file in the
index at the end, which means conflict representation might be tricky.
content-based conflicts are easier to handle here than path-based
ones, since content-based conflicts can just do similar to what
rename/rename(2to1) conflicts do today: just stick the result of the
preliminary three-way merges into the index.  path-based conflicts get
more interesting because you can't do a preliminary merge of binary
files or a preliminary merge of a modify/delete, etc.
* If both pre-M and N have path-based conflicts, but of different
types, how exactly do we mention that to the user?  Just list all the
types?  (This probably qualifies as a case of a "complicated" conflict
where we want to (also?) provide the user with N:resulting-file
instead of (just?) R:resulting-file.)  We may also need to modify
merge machinery to return types of conflicts per-path, an extension of
what my "merge-into" series (not yet submitted) provides.
Previous: Johannes SchindelinNext: Ævar Arnfjörð Bjarmason
Message 55 of 78 in “Drop support for git rebase --preserve-merges”
  1. 0/8 Drop support for git rebase --preserve-mergesJohannes Schindelin via GitGitGadget, Nov 23, 2019
  2. 1/8 t5520: do not use `pull.rebase=preserve`Johannes Schindelin via GitGitGadget, Nov 23, 2019
  3. 2/8 remote: warn about unhandled branch.<name>.rebase valuesJohannes Schindelin via GitGitGadget, Nov 23, 2019
  4. 4/8 pull: remove support for `--rebase=preserve`Johannes Schindelin via GitGitGadget, Nov 23, 2019
  5. 6/8 git-svn: drop support for `--preserve-merges`Johannes Schindelin via GitGitGadget, Nov 23, 2019
  6. Eric WongNov 23, 2019
  7. Johannes SchindelinNov 24, 2019
  8. Eric WongNov 25, 2019
  9. 3/8 tests: stop testing `git rebase --preserve-merges`Johannes Schindelin via GitGitGadget, Nov 23, 2019
  10. 8/8 remote: no longer claim that branch.*.rebase=preserve is a thingJohannes Schindelin via GitGitGadget, Nov 23, 2019
  11. 7/8 rebase: drop the internal `rebase--interactive` commandJohannes Schindelin via GitGitGadget, Nov 23, 2019
  12. 5/8 rebase: drop support for `--preserve-merges`Johannes Schindelin via GitGitGadget, Nov 23, 2019
  13. 0/7 Drop support for git rebase --preserve-mergesJohannes Schindelin via GitGitGadget, Sep 1, 2021
  14. 1/7 t5520: do not use `pull.rebase=preserve`Johannes Schindelin via GitGitGadget, Sep 1, 2021
  15. 2/7 remote: warn about unhandled branch.<name>.rebase valuesJohannes Schindelin via GitGitGadget, Sep 1, 2021
  16. 4/7 pull: remove support for `--rebase=preserve`Johannes Schindelin via GitGitGadget, Sep 1, 2021
  17. 3/7 tests: stop testing `git rebase --preserve-merges`Johannes Schindelin via GitGitGadget, Sep 1, 2021
  18. Ævar Arnfjörð BjarmasonSep 1, 2021
  19. 6/7 git-svn: drop support for `--preserve-merges`Johannes Schindelin via GitGitGadget, Sep 1, 2021
  20. Ævar Arnfjörð BjarmasonSep 1, 2021
  21. Johannes SchindelinSep 2, 2021
  22. Johannes SchindelinSep 2, 2021
  23. 5/7 rebase: drop support for `--preserve-merges`Johannes Schindelin via GitGitGadget, Sep 1, 2021
  24. Ævar Arnfjörð BjarmasonSep 1, 2021
  25. Johannes SchindelinSep 2, 2021
  26. Ævar Arnfjörð BjarmasonSep 2, 2021
  27. Ævar Arnfjörð BjarmasonSep 1, 2021
  28. Johannes SchindelinSep 2, 2021
  29. Ævar Arnfjörð BjarmasonSep 2, 2021
  30. Ævar Arnfjörð BjarmasonSep 2, 2021
  31. Ævar Arnfjörð BjarmasonSep 2, 2021
  32. Ævar Arnfjörð BjarmasonSep 2, 2021
  33. Ævar Arnfjörð BjarmasonSep 2, 2021
  34. Johannes SchindelinSep 4, 2021
  35. Ævar Arnfjörð BjarmasonSep 5, 2021
  36. Junio C HamanoSep 5, 2021
  37. Phillip WoodSep 6, 2021
  38. Johannes SchindelinSep 7, 2021
  39. Phillip WoodSep 7, 2021
  40. Johannes SchindelinSep 7, 2021
  41. 7/7 rebase: drop the internal `rebase--interactive` commandJohannes Schindelin via GitGitGadget, Sep 1, 2021
  42. Phillip WoodSep 6, 2021
  43. Johannes SchindelinSep 7, 2021
  44. Ævar Arnfjörð BjarmasonSep 1, 2021
  45. Johannes SchindelinSep 2, 2021
  46. Ævar Arnfjörð BjarmasonSep 2, 2021
  47. Junio C HamanoSep 1, 2021
  48. Johannes SchindelinSep 2, 2021
  49. Johannes SixtSep 2, 2021
  50. Johannes SchindelinSep 7, 2021
  51. Elijah NewrenSep 7, 2021
  52. Johannes SchindelinSep 10, 2021
  53. Elijah NewrenSep 10, 2021
  54. merge-ort and --rebase-merges, was Re: [PATCH v2 0/7] Drop support for git rebase --preserve-mergesJohannes Schindelin, Sep 13, 2021
  55. Elijah NewrenSep 13, 2021
  56. Ævar Arnfjörð BjarmasonSep 6, 2021
  57. Junio C HamanoSep 7, 2021
  58. Ævar Arnfjörð BjarmasonSep 7, 2021
  59. Alban GruinSep 4, 2021
  60. Phillip WoodSep 6, 2021
  61. Johannes SchindelinSep 7, 2021
  62. 00/11 Drop support for git rebase --preserve-mergesJohannes Schindelin via GitGitGadget, Sep 7, 2021
  63. 01/11 t5520: do not use `pull.rebase=preserve`Johannes Schindelin via GitGitGadget, Sep 7, 2021
  64. 02/11 remote: warn about unhandled branch.<name>.rebase valuesJohannes Schindelin via GitGitGadget, Sep 7, 2021
  65. 03/11 tests: stop testing `git rebase --preserve-merges`Johannes Schindelin via GitGitGadget, Sep 7, 2021
  66. 04/11 pull: remove support for `--rebase=preserve`Johannes Schindelin via GitGitGadget, Sep 7, 2021
  67. 06/11 git-svn: drop support for `--preserve-merges`Johannes Schindelin via GitGitGadget, Sep 7, 2021
  68. 05/11 rebase: drop support for `--preserve-merges`Johannes Schindelin via GitGitGadget, Sep 7, 2021
  69. Ævar Arnfjörð BjarmasonSep 10, 2021
  70. re-mentioning --preserve-merges in the docs (was: [PATCH v3 05/11] rebase: drop support for `--preserve-merges`)Ævar Arnfjörð Bjarmason, Jul 21, 2022
  71. Junio C HamanoJul 21, 2022
  72. Johannes SchindelinJul 29, 2022
  73. 07/11 rebase: drop the internal `rebase--interactive` commandJohannes Schindelin via GitGitGadget, Sep 7, 2021
  74. 08/11 rebase: remove obsolete code commentJohannes Schindelin via GitGitGadget, Sep 7, 2021
  75. 09/11 rebase: stop mentioning the -p option in commentsJohannes Schindelin via GitGitGadget, Sep 7, 2021
  76. 10/11 rebase: remove a no-longer-used functionJohannes Schindelin via GitGitGadget, Sep 7, 2021
  77. 11/11 sequencer: restrict scope of a formerly public functionJohannes Schindelin via GitGitGadget, Sep 7, 2021
  78. Ævar Arnfjörð BjarmasonSep 8, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.