Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Sep 7, 2021 at 11:51 AM Johannes Schindelin
<Johannes.Schindelin@xxxxxx> wrote:
>
> Hi Hannes,
>
> On Thu, 2 Sep 2021, Johannes Sixt wrote:
>
> > Am 02.09.21 um 16:18 schrieb Johannes Schindelin:
> > > On Wed, 1 Sep 2021, Junio C Hamano wrote:
> > >> A good goal.  There is no remaining use case where (a fictitious and
> > >> properly working version of) "--preserve-merges" option cannot be
> > >> replaced by "--rebase-merges", is it?  I somehow had a feeling that
> > >> the other Johannes (sorry if it weren't you, j6t) had cases that the
> > >> former worked better, but perhaps I am mis-remembering things.
> > >
> > > I think that I managed to address whatever concerns there were about the
> > > `--rebase-merges` backend in the meantime.
> >
> > That was either my suggestion/desire to make no-rebase-cousins the
> > default. That has been settled.
> >
> > Or my wish not to redo the merge, but to replay the first-parent
> > difference. The idea never got traction, and I've long since abandoned
> > my implementation of it.
>
> Thank you for clarifying.
>
> Yes, I remember how that idea came up, and I even tried that strategy for
> a couple of merging rebases of Git for Windows' branch thicket. Sadly, it
> did not work half as well as I had hoped.
>
> The best idea I had back then still is in want of being implemented: sort
> of a "four-way merge". It is basically the same as a three-way merge, but
> allows for the pre-images to differ in the context (and yes, this cannot
> be represented using the current conflict markers). Definitely not
> trivial.

merge-ort opens a new possibility (since it does merges without
touching the index or working tree): Take the merge commit, M, that
you are trying to transplant.  Hold on to it for a minute.  Do what
rebase-merges does now; namely, do a simple merge of the desired new
branches that otherwise ignores M to get your new merge commit N.
Hang on to N too for a minute.  Now use merge-ort to auto-remerge M
(much like AUTO_MERGE or --remerge-diff does) to get a new merge
commit that we'll call pre-M.  If M was a clean merge that the user
didn't amend, then pre-M will match M.  If M wasn't a clean merge or
was amended, then pre-M will otherwise differ from M by not including
any manual changes the user made when they originally created M --
such as removing conflict markers, fixing semantic conflicts, evil
changes, etc.

Now we've got three merge commits: pre-M, M, and N.  (Technically,
pre-M and N might be toplevel trees rather than full commits, but
whatever.)  The difference between pre-M and M represent the manual
work the user did in order to create M.  Now, do a three-way
(non-recursive) merge of those commits, to get the rebased result, R.
This operation has the affect of applying the changes from pre-M to M
on top of N.

There's obviously some edge cases (e.g. nested conflict markers), but
I think they're better than the edge cases presented by the
alternatives:
  * the first-parent difference idea silently discards intermediate
changes from reapplying other patches (especially if other patches are
added or dropped), which to me feels _very_ dangerous
  * the current rebase-merges idea silently discards manual user
changes within the original merge commit (i.e. it hopes that there is
no difference between pre-M and M), which can also be lossy
  * I don't think this idea drops any data, but it does run the risk
of conflicts that are difficult to understand.  But I suspect less so
than your five-way merge would entail.

If the difficulty of conflicts in this scheme is too high, we could do
a few things like providing multiple versions (e.g. if either
pre-M:file or N:file had conflicts, or maybe if R:file has nested
conflicts, then place both R:file and N:file in the working tree
somewhere) or pointing at special commands that help users figure out
what went on (e.g. 'git log -1 --remerge-diff M -- file').



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux