On Mon, Apr 18, 2022 at 9:52 AM Tao Klerks <tao@xxxxxxxxxx> wrote: > > Hi folks, > > The discussion around Edmundo Carmona Antoranz's recent "git replay" > proposal ([1]) led me down a rabbit-hole reminding me I really don't > understand where we stand with rebasing merges, and I don't think I'm > alone. > > I understand the standard advice at the moment to be something like: > --- > Use a recent git client, use the '--rebase-merges' option (avoid the > --preserve-merges option if you find it), and re-resolve any textual > and/or semantic conflicts manually (possibly using rerere if you know > what you're doing). > --- > Is this correct? > > This current state/advice seems... suboptimal, at best, because it > ignores any information encoded in the original merge commit, as > clearly documented in the help. It will often result in you having to > resolve conflicts that you already resolved, *where nothing relevant > to that merge/commit has changed in your rebase*. If you have rerere, > and you know what you are doing, and you were the one that performed > the merge, in this repo, then maybe you're ok; similarly if it's a > clean merge of course. > > Elijah Newren describes this problem/opportunity quite carefully in > [2], and mentions a bunch of WIP that I have a hard time getting my > head around. > > Similarly, Sergey Organov refers to a thread/discussion four years ago > [3], largely involving a debate around two implementations (his and > that of Phillip Wood?) that are largely theoretically-equivalent (in a > majority of cases), with a lovely explanation of the theory behind the > proposal by Igor Djordjevic / Buga [4], but that discussion appears to > have dried up; I can't tell whether anything came of it, even if only > a manually-usable "rebase a merge" script. > > Finally, Martin von Zweigbergk mentions his git-like VCS [5] which > stores conflict data in some kinds of commit as part of a general > "working state is always committable and auto-committed" > state-management strategy; Just so there's no misunderstanding, the "auto-committed working copy" idea is not a requirement for storing conflict objects in trees. > I may be misunderstanding something, but I > *think* the resulting conflict-resolution information ends up being > reusable in a manner theoretically equivalent to the strategy > described by Buga as referenced above. I think it's more similar to what Elijah suggested, actually. For example, my VCS lets you rebase a merge commit (the "evil" part of it) even if you don't rebase all its ancestors. Consider this case: X / A---B---C \ \ D---E---F If you now want to rebase E onto X, and then F onto E' and C, then Elijah's suggestion (and what my VCS does) will work correctly. If I understood Sergey's proposal, on the other hand, the utility merge would bring in the changes from D as well. Or, put another way, that algorithm is only useful for rebasing "internal" merges, where the merge commit is being rebased along with both (all of) its legs (again, if I understood it correctly). With the "rebase changes compared to auto-merged parents" idea, you can even change the number of parents of a commit as you rebase it. > > These kinds of discussions frequently seem to feature git experts > saying "I have a script for my version of this problem" (Elijah, > Junio, Johannes Schindelin, ...), or even "I have a VCS for this > problem" :), but I seem to be too stupid or impatient to dig > through/understand whether or when these things will work for a > regular joe and how to use them. > > The temptation, obviously(?), is to write a "rebase a merge" script to > do something like Sergey Organov's V2 proposal referenced above... but > it feels like I'd be spending a bunch of time and ultimately just > making things worse for the community, rather than better - helping > myself based on my (very limited, but still above average) > understanding of merge mechanics, in a way that leaves the general > public message / status just as unsatisfactory/unhelpful. > > Does anyone have an existing simpler answer? Ideally I'm looking for > something like: > --- > * When you have a merge in your history, and you are rebasing, follow > steps XXXXXX, involving this publicly available gist, or contrib > script, or experimental flag, and it will probably do what you want. > If there is a (new) conflict when rebasing the merge commit, you can > expect conflicts to be presented as YYYYY, because rebasing a merge in > this "informed" way can fundamentally involve multiple different > steps/phases of conflict resolution - rebase conflicts vs merge > conflicts. > * Something like this will likely be introduced as a new rebase option > in a future release, something like "--reapply-merges", or > "--rebase-merges-better", because it will always require the user to > understand that the three-way conflicts presented as part of such an > "informed" merge rebase are subtly different to regular rebase or > merge conflicts. > --- > > Is it possible to get that sort of simplistic message for this complex topic? > > My apologies if this request is a duplicate - obviously a pointer to > some sort of existing summary would be perfect. > > Thanks, > Tao > > [1]: https://lore.kernel.org/git/20220413164336.101390-1-eantoranz@xxxxxxxxx/ > [2]: https://lore.kernel.org/git/CABPp-BE=H-OcvGNJKm2zTvV3jEcUV0L=6W76ctpwOewZg56FKg@xxxxxxxxxxxxxx/ > [3]: https://public-inbox.org/git/87r2oxe3o1.fsf@xxxxxxxxx/ > [4]: https://public-inbox.org/git/a0cc88d2-bfed-ce7b-1b3f-3c447d2b32da@xxxxxxxxx/ > [5]: https://github.com/martinvonz/jj