Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop support for git rebase --preserve-merges #195

Closed
wants to merge 11 commits into from

Conversation

dscho
Copy link
Member

@dscho dscho commented May 14, 2019

In 427c3bd (rebase: deprecate --preserve-merges, 2019-03-11) (which was included in v2.22.0), we officially deprecated the --preserve-merges backend. Over two years later, it is time to drop that backend, and here is a patch series that does just that.

Changes since v2:

  • Removed the no-longer-needed script_snippet variable
  • Enhanced the commit message of the git svn patch to clarify that the deprecation happened only in v2.25 there
  • Adjusted code comments that still talked about the removed option
  • Removed some no-longer-needed ACTION_* enum values
  • We now also drop check_todo_list_from_file() because it is no longer needed
  • The todo_list_add_exec_commands() function is now scoped to the file (because there are no longer any outside users)
  • When users still use the options, they are no longer met by Git's blank stares, but by a helpful error message suggesting to use --rebase-merges instead

Changes since v1:

  • Rebased onto v2.33.0

Cc: Eric Wong e@80x24.org
cc: Ævar Arnfjörð Bjarmason avarab@gmail.com
cc: Johannes Sixt j6t@kdbg.org
cc: Alban Gruin alban.gruin@gmail.com
cc: Phillip Wood phillip.wood123@gmail.com
cc: Elijah Newren newren@gmail.com

@dscho dscho added the needs-work These patches have pending issues that need to be resolved before submitting label May 20, 2019
@dscho dscho force-pushed the drop-rebase-p branch 2 times, most recently from 9d3ba72 to ea6237a Compare May 30, 2019 12:37
@dscho dscho changed the base branch from master to js/rebase-cleanup July 24, 2019 11:24
@dscho dscho changed the base branch from js/rebase-cleanup to js/git-svn-use-rebase-merges November 23, 2019 20:04
@dscho dscho added ready to submit Has commits that have not been submitted yet and removed needs-work These patches have pending issues that need to be resolved before submitting labels Nov 23, 2019
@dscho
Copy link
Member Author

dscho commented Nov 23, 2019

/submit

@gitgitgadget
Copy link

gitgitgadget bot commented Nov 23, 2019

@@ -678,7 +678,6 @@ config key: svn.authorsProg
--strategy=<strategy>::
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Eric Wong wrote (reply to this):

Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com> wrote:
> We already passed the `--rebase-merges` option to `git rebase` instead,
> now we make this move permanent.

> diff --git a/git-svn.perl b/git-svn.perl
> index 4aa208ff5f..f1fa1bc7f7 100755
> --- a/git-svn.perl
> +++ b/git-svn.perl
> @@ -271,7 +271,6 @@ sub _req_svn {
>  			  'fetch-all|all' => \$_fetch_all,
>  			  'dry-run|n' => \$_dry_run,
>  			  'rebase-merges|p' => \$_rebase_merges,
> -			  'preserve-merges|p' => \$_rebase_merges,
>  			  %fc_opts } ],
>  	'commit-diff' => [ \&cmd_commit_diff,
>  	                   'Commit a diff between two trees',

Nack, it breaks existing usages.   Why the urgency with removal?

I don't know a whole lot about this rebase feature in
particular, but deprecation periods should be measured in years
or even decades because of LTS distros.  Not months, especially
for things which have been around for a long while.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Johannes Schindelin wrote (reply to this):

Hi Eric,

On Sat, 23 Nov 2019, Eric Wong wrote:

> Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com> wrote:
> > We already passed the `--rebase-merges` option to `git rebase` instead=
,
> > now we make this move permanent.
>
> > diff --git a/git-svn.perl b/git-svn.perl
> > index 4aa208ff5f..f1fa1bc7f7 100755
> > --- a/git-svn.perl
> > +++ b/git-svn.perl
> > @@ -271,7 +271,6 @@ sub _req_svn {
> >  			  'fetch-all|all' =3D> \$_fetch_all,
> >  			  'dry-run|n' =3D> \$_dry_run,
> >  			  'rebase-merges|p' =3D> \$_rebase_merges,
> > -			  'preserve-merges|p' =3D> \$_rebase_merges,
> >  			  %fc_opts } ],
> >  	'commit-diff' =3D> [ \&cmd_commit_diff,
> >  	                   'Commit a diff between two trees',
>
> Nack, it breaks existing usages.   Why the urgency with removal?

Which urgency? The cover letter spells it out quite clearly that this is
not even intended for v2.25.0, which is still over 2 months out.

The reason I submitted this patch series now is so that we can avoid
inadvertent new users of the `--preserve-merges` backend.

> I don't know a whole lot about this rebase feature in
> particular, but deprecation periods should be measured in years
> or even decades because of LTS distros.  Not months, especially
> for things which have been around for a long while.

The LTS distros will not even pick up this patch. So that's a red herring.

But yes, you're right, v2.25.0 will probably be the first version to even
have the `--rebase-merges` option in `git svn`, and therefore v2.26.0
would be awfully early a time to drop `--preserve-merges` in `git svn`.
Question is whether we want to split this patch series, or just rather
wait with merging it to `master` until a year from now, or something like
that?

Ciao,
Dscho

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Eric Wong wrote (reply to this):

Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com> wrote:
> > > We already passed the `--rebase-merges` option to `git rebase` instead,
> > > now we make this move permanent.
> >
> > > diff --git a/git-svn.perl b/git-svn.perl
> > > index 4aa208ff5f..f1fa1bc7f7 100755
> > > --- a/git-svn.perl
> > > +++ b/git-svn.perl
> > > @@ -271,7 +271,6 @@ sub _req_svn {
> > >  			  'fetch-all|all' => \$_fetch_all,
> > >  			  'dry-run|n' => \$_dry_run,
> > >  			  'rebase-merges|p' => \$_rebase_merges,
> > > -			  'preserve-merges|p' => \$_rebase_merges,
> > >  			  %fc_opts } ],
> > >  	'commit-diff' => [ \&cmd_commit_diff,
> > >  	                   'Commit a diff between two trees',
> >
> > Nack, it breaks existing usages.   Why the urgency with removal?
> 
> Which urgency? The cover letter spells it out quite clearly that this is
> not even intended for v2.25.0, which is still over 2 months out.

"Months" a blink of an eye when it comes to deprecations and removals.

> The reason I submitted this patch series now is so that we can avoid
> inadvertent new users of the `--preserve-merges` backend.

Then documenting it as deprecated and warning is all that's
needed.

> > I don't know a whole lot about this rebase feature in
> > particular, but deprecation periods should be measured in years
> > or even decades because of LTS distros.  Not months, especially
> > for things which have been around for a long while.
> 
> The LTS distros will not even pick up this patch. So that's a red herring.
> 
> But yes, you're right, v2.25.0 will probably be the first version to even
> have the `--rebase-merges` option in `git svn`, and therefore v2.26.0
> would be awfully early a time to drop `--preserve-merges` in `git svn`.
> Question is whether we want to split this patch series, or just rather
> wait with merging it to `master` until a year from now, or something like
> that?

Fwiw, I object to the regressions to all the other commands
(rebase/pull/remote) in this series, too, but I mainly do Perl.

--preserve-merges was only deprecated in v2.22.0 (2019-06-07).
LTS distro users are very likely on pre-v2.22.0, more likely
v2.1x.0 and maybe even v2.x.0.

Their next LTS release could be several years from now.  We
could be on git 2.[345]x.0 by then and that's when the LTS
packagers could package the next version.  LTS users are likely
to never see the entire period from v2.22.0..v2.25.0 and thus
never see a deprecation warning.

Even Debian stable (not exactly LTS, but still on the slower
side) went from v2.11.0 in Debian 9 all the way to v2.20.1
in Debian 10.  Actual LTS users will see bigger jumps.

@dscho dscho removed the ready to submit Has commits that have not been submitted yet label Nov 24, 2019
Even if those tests try to override that setting, let's not use it
because it is deprecated: let's use `merges` instead.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@gitgitgadget
Copy link

gitgitgadget bot commented Aug 31, 2021

The pull request has 6443 commits. The max allowed is 30. Please split the patch series into multiple pull requests. Also consider squashing related commits.

@gitgitgadget
Copy link

gitgitgadget bot commented Aug 31, 2021

There are merge commits in this Pull Request:

5d96bcbc0602f96ccee3111ff93b05389cd6eae6
07e230d762bde9ce5fa41384efb8caed4c7de684
0659866a09ef6a7a0e74eb18ef66d8f5bd959215
c9780bb2ca81828ec4f43c60b2107c335271a72f
4da281e84d87b099ba8d0a255534dc1251be968e
4d4c7d05dadb11e1181207c44bab53f12fc629cd
c3c0b71f9ad82483b37869c3b0fb88e3efb4a308
308528a3eae30b7dc02fffe76b91af8a91cc1b01
d2992c6bc075e577301c629adee9880164be3027
b6bd704c3ed911b87e7c8eb1aaabf0b9b7b9f02a
21ef7ee4d6104c35fc6753da5406c842fb2d9286
1157618a2ae50ae611ca22ce1833760bc0456156

Please rebase the branch and force-push.

@dscho dscho changed the base branch from js/git-svn-use-rebase-merges to master August 31, 2021 15:11
@dscho dscho self-assigned this Aug 31, 2021
We ignore them silently, but it actually makes sense to warn the users
that their config setting has no effect.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@dscho
Copy link
Member Author

dscho commented Sep 1, 2021

/submit

@gitgitgadget
Copy link

gitgitgadget bot commented Sep 7, 2021

On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this):


On Tue, Sep 07 2021, Junio C Hamano wrote:

> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> On Wed, Sep 01 2021, Junio C Hamano wrote:
>>
>>> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
>>> writes:
>>>
>>>> In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was
>>>> included in v2.22.0), we officially deprecated the --preserve-merges
>>>> backend. Over two years later, it is time to drop that backend, and here is
>>>> a patch series that does just that.
>>>
>>> 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.
>>
>> Fair enough. To be clear I think this series is fine as-is, we've just
>> usually done "now that this function is dead, rm it" as part of the
>> series that makes it dead, so I figured fixups/squashes to change those
>> parts would be welcome & integrated, likewise Alban Gruin's suggestions
>> in <62fbd389-28f5-76e5-d3f3-5510415a7bf5@gmail.com>.
>>
>> But the git-sh-i18n.sh change and/or his suggestions can be done after
>> this lands...
>
> I have this funny feeling that the "Fair enough" is thrown at a
> comment that you didn't intend to ;-)

I think I meant to reply to
https://lore.kernel.org/git/xmqqlf4aejko.fsf@gitster.g/; I don't know
how I got them mixed up, sorry about that.

In preparation for `git-rebase--preserve-merges.sh` entering its after
life, we remove this (deprecated) option that would still rely on it.

To help users transition who still did not receive the memo about the
deprecation, we offer a helpful error message instead of throwing our
hands in the air and saying that we don't know that option, never heard
of it.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This option was deprecated in favor of `--rebase-merges` some time ago,
and now we retire it.

To assist users to transition away, we do not _actually_ remove the
option, but now we no longer implement the functionality. Instead, we
offer a helpful error message suggesting which option to use.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
We already passed the `--rebase-merges` option to `git rebase` instead,
now we make this move permanent.

As pointed out by Ævar Arnfjörð Bjarmason, in contrast to the
deprecation of `git rebase`'s `--preserve-merges` backend, `git svn`
only deprecated this option in v2.25.0 (because this developer missed
`git svn`'s use of that backend when deprecating the rebase backend
running up to Git v2.22).

Still, v2.25.0 has been released on January 13th, 2020. In other words,
`git svn` deprecated this option over one and a half years ago, _and_
has been redirecting to the `--rebase-merges` option during all that
time (read: `git svn rebase --preserve-merges` didn't do _precisely_
what the user asked, since v2.25.0, anyway, it fell back to pretending
that the user asked for `git svn rebase --rebase-merges` instead).

It is time to act on that deprecation and remove that option after all.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
It was only used by the `--preserve-merges` backend, which we just
removed.

Helped-by: Alban Gruin <alban.gruin@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Now that we no longer have a `--preserve-merges` backend, this comment
needs to be adjusted.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
We no longer support `--preserve-merges`, therefore it does not make
sense to keep mentioning that option, even in code comments.

Helped-by: Phillip Wood <phillip.wood123@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
With the `--preserve-merges` option going away, we no longer need this
function.

Helped-by: Alban Gruin <alban.gruin@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The function to add the `exec` commands to the todo list only needed to
be public API because it was not only used internally by the sequencer,
but also by `git rebase --preserve-merges`.

Now that that mode has been removed, we no longer need that function to
be scoped publicly.

Helped-by: Alban Gruin <alban.gruin@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@dscho
Copy link
Member Author

dscho commented Sep 7, 2021

/submit

@gitgitgadget
Copy link

gitgitgadget bot commented Sep 7, 2021

Submitted as pull.195.v3.git.1631048712.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git pr-195/dscho/drop-rebase-p-v3

To fetch this version to local tag pr-195/dscho/drop-rebase-p-v3:

git fetch --no-tags https://github.com/gitgitgadget/git tag pr-195/dscho/drop-rebase-p-v3

@gitgitgadget
Copy link

gitgitgadget bot commented Sep 7, 2021

On the Git mailing list, Elijah Newren wrote (reply to this):

On Tue, Sep 7, 2021 at 11:51 AM Johannes Schindelin
<Johannes.Schindelin@gmx.de> 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').

@gitgitgadget
Copy link

gitgitgadget bot commented Sep 7, 2021

User Elijah Newren <newren@gmail.com> has been added to the cc: list.

@gitgitgadget
Copy link

gitgitgadget bot commented Sep 8, 2021

On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this):


On Tue, Sep 07 2021, Johannes Schindelin via GitGitGadget wrote:

> In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was
> included in v2.22.0), we officially deprecated the --preserve-merges
> backend. Over two years later, it is time to drop that backend, and here is
> a patch series that does just that.
>
> Changes since v2:
>
>  * Removed the no-longer-needed script_snippet variable
>  * Enhanced the commit message of the git svn patch to clarify that the
>    deprecation happened only in v2.25 there
>  * Adjusted code comments that still talked about the removed option
>  * Removed some no-longer-needed ACTION_* enum values
>  * We now also drop check_todo_list_from_file() because it is no longer
>    needed
>  * The todo_list_add_exec_commands() function is now scoped to the file
>    (because there are no longer any outside users)
>  * When users still use the options, they are no longer met by Git's blank
>    stares, but by a helpful error message suggesting to use --rebase-merges
>    instead
>
> Changes since v1:
>
>  * Rebased onto v2.33.0
>
> Johannes Schindelin (11):
>   t5520: do not use `pull.rebase=preserve`
>   remote: warn about unhandled branch.<name>.rebase values
>   tests: stop testing `git rebase --preserve-merges`
>   pull: remove support for `--rebase=preserve`
>   rebase: drop support for `--preserve-merges`
>   git-svn: drop support for `--preserve-merges`
>   rebase: drop the internal `rebase--interactive` command
>   rebase: remove obsolete code comment
>   rebase: stop mentioning the -p option in comments
>   rebase: remove a no-longer-used function
>   sequencer: restrict scope of a formerly public function

I've looked this version over & followed all the discussions on the
earlier rounds (this year), this looks good to me. Thanks a lot for
working on it:

Reviewed-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>

@gitgitgadget
Copy link

gitgitgadget bot commented Sep 10, 2021

On the Git mailing list, Johannes Schindelin wrote (reply to this):

Hi Elijah,

On Tue, 7 Sep 2021, Elijah Newren wrote:

> On Tue, Sep 7, 2021 at 11:51 AM Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
> >
> > 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').

While I agree that `merge-ort` makes a lot of things much better, I think
in this context we need to keep in mind that those nested merge conflicts
can really hurt.

In my tests (I tried to implement a strategy where a 3-way merge is done
with M and N^, using the parent commits of M as merge parents
successively, see
https://lore.kernel.org/git/nycvar.QRO.7.76.6.1804130002090.65@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz/
for the nitty gritty), I ran into _nasty_ nested merge conflicts, even
with trivial examples. And I came to the conviction that treating the
merge conflict markers as Just Another Line was the main culprit.

I wish I had the time to try out your proposed strategy with the
conconcted example I presented in that mail I linked above. Because now I
am curious what it would do...

Ciao,
Dscho

@@ -125,7 +125,6 @@
/git-range-diff
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this):


On Tue, Sep 07 2021, Johannes Schindelin via GitGitGadget wrote:

> diff --git a/builtin/rebase.c b/builtin/rebase.c
> index 33e09619005..5f8d9f89ba4 100644
> --- a/builtin/rebase.c
> +++ b/builtin/rebase.c
> @@ -48,8 +48,7 @@ static GIT_PATH_FUNC(merge_dir, "rebase-merge")
>  enum rebase_type {
>  	REBASE_UNSPECIFIED = -1,
>  	REBASE_APPLY,
> -	REBASE_MERGE,
> -	REBASE_PRESERVE_MERGES
> +	REBASE_MERGE
>  };

This definitely doesn't require a re-roll, but just in case you didn't
know, from CodingGuidelines:

   . since early 2012 with e1327023ea, we have been using an enum
     definition whose last element is followed by a comma.  This, like
     an array initializer that ends with a trailing comma, can be used
     to reduce the patch noise when adding a new identifier at the end.

(That was added in cc0c42975a2 (CodingGuidelines: spell out post-C89
rules, 2019-07-16))

I.e. in case you're slavisly following this particular bit of C syntax
for C89 compatibility it's not needed anymore, which helps to make diffs
smaller, and writing code generation loops less annoying.

@gitgitgadget
Copy link

gitgitgadget bot commented Sep 10, 2021

On the Git mailing list, Elijah Newren wrote (reply to this):

On Fri, Sep 10, 2021 at 5:08 AM Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
>
> Hi Elijah,
>
> On Tue, 7 Sep 2021, Elijah Newren wrote:
>
> > On Tue, Sep 7, 2021 at 11:51 AM Johannes Schindelin
> > <Johannes.Schindelin@gmx.de> wrote:
> > >
...
> > > 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').
>
> While I agree that `merge-ort` makes a lot of things much better, I think
> in this context we need to keep in mind that those nested merge conflicts
> can really hurt.

Yes, and I'm not sure you fully appreciate how much either.  Your
discussion in the other thread of nested conflicts suggests you may
not be aware of a few facts; for regular merges (not talking about
rebase-merges yet):

* Merges can have nested conflicts DESPITE having unique merge bases
and NOT using merge.conflictstyle=diff3
* With unique merge bases (i.e. not a "recursive" merge), a merge will
have at most two layers of conflicts
* non-unique merge-bases and merge.conflictstyle=diff3 make nested
conflicts much more likely
* There is no limit on the number of nestings of conflict markers for a merge

Now, in terms of rebase-merges:

You noted in the other thread the possibility of being unable to
differentiate conflict markers because they had the same length.
However, increasing the length on the second merge by one or two
characters is not sufficient in general, because that might just make
you match the length of one of the nested conflicts from the other
merge.  You need to programmatically determine the sizes of the
conflict markers in the first merge, and then adjust based on it for
your other merge(s).


I know this will sound like I'm scaring you off of my idea even
further, but I actually think despite the above that my ideas for
rebase-merges may have merit.  I just want people to actually
understand the edge and corner cases.  From my reading of the previous
threads on rebasing merges, I'm concerned that there is no discussion
of arbitrarily nested conflict markers and a complete omission of any
considerations for path-based rather than content-based conflicts.

> In my tests (I tried to implement a strategy where a 3-way merge is done
> with M and N^, using the parent commits of M as merge parents
> successively, see
> https://lore.kernel.org/git/nycvar.QRO.7.76.6.1804130002090.65@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz/
> for the nitty gritty), I ran into _nasty_ nested merge conflicts, even
> with trivial examples. And I came to the conviction that treating the
> merge conflict markers as Just Another Line was the main culprit.

I agree that we should not treat merge conflict markers as Just
Another Line.  There are other issues I can mention besides the above
here, but I'm getting kind of long already.

However, I think a big part of the problem you ran into was that the
previous suggestions only work nicely in _really_ simple cases.  In
particular, although I like Phillip's suggested sequence of merges[1]
a lot more than the other suggestions in that thread or from prior
threads, his suggestion is going to be prone to unnecessary nested
conflict markers, as you found in your testcase.

[1] https://lore.kernel.org/git/6c8749ca-ec5d-b4b7-f1a0-50d9ad2949a5@talktalk.net/

> I wish I had the time to try out your proposed strategy with the
> conconcted example I presented in that mail I linked above. Because now I
> am curious what it would do...

For this simple testcase, as best I understood it (you didn't quite
describe it fully so I had to take a guess or two), it provides a
simpler conflict than either of the two you showed you got (from
different merge orderings of Phillip's suggestion).   However, let me
double check that I understood your testcase correctly; please correct
any errors in my understanding.  I believe the commit graph you were
describing was this:

* rebase-of-original-merge
|\
| * rebase-of-local-add-caller-of-core
* | rebase-of-local-rename-to-hi
|/
* upstream
|
|
|
| * original-merge
| |\
| | * local-add-caller-of-core
| |/
|/|
| * local-rename-to-hi
|/
* initial-version


Further, the versions of main.c in each of those are as follows:

==> initial-version:
int core(void) {
    printf("Hello, world!\n");
}


==> local-rename-to-hi:
int hi(void) {
    printf("Hello, world!\n");
}


==> local-add-caller-of-core:
int core(void) {
    printf("Hello, world!\n");
}
/* caller */
void caller(void) {
    core();
}


==> what an automatic merge of the two local-* branches would give:
int hi(void) {
    printf("Hello, world!\n");
}
/* caller */
void caller(void) {
    core();
}


==> original-merge (amended from above by s/core/hi/ in caller()):
int hi(void) {
    printf("Hello, world!\n");
}
/* caller */
void caller(void) {
    hi();
}


==> upstream:
int greeting(void) {
    printf("Hello, world!\n");
}
/* main event loop */
void event_loop(void) {
    /* TODO: place holder for now */
}


==> rebase-of-local-rename-to-hi (kept 'hi' over 'greeting'):
int hi(void) {
    printf("Hello, world!\n");
}
/* main event loop */
void event_loop(void) {
    /* TODO: place holder for now */
}


==> rebase-of-local-add-caller-of-core (kept both new functions,
updated caller):
int greeting(void) {
    printf("Hello, world!\n");
}
/* main event loop */
void event_loop(void) {
    /* TODO: place holder for now */
}
/* caller */
void caller(void) {
    greeting();
}



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
}

@gitgitgadget
Copy link

gitgitgadget bot commented Sep 13, 2021

On the Git mailing list, Johannes Schindelin wrote (reply to this):

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:
> >
> > > On Tue, Sep 7, 2021 at 11:51 AM Johannes Schindelin
> > > <Johannes.Schindelin@gmx.de> wrote:
> > >
> > > [... talk about re-resolving merge conflicts when recreating merges
> > >  in a `git rebase --rebase-merges` run ...]
> ...
> >
> > While I agree that `merge-ort` makes a lot of things much better, I think
> > in this context we need to keep in mind that those nested merge conflicts
> > can really hurt.
>
> Yes, and I'm not sure you fully appreciate how much either.

*grin*

> [... a lot of insight that I totally agree with ...]
>
> I believe the commit graph you were describing was this:
>
> * rebase-of-original-merge
> |\
> | * rebase-of-local-add-caller-of-core
> * | rebase-of-local-rename-to-hi
> |/
> * upstream
> |
> |
> |
> | * original-merge
> | |\
> | | * local-add-caller-of-core
> | |/
> |/|
> | * local-rename-to-hi
> |/
> * initial-version
>
>
> Further, the versions of main.c in each of those are as follows:
>
> ==> initial-version:
> int core(void) {
>     printf("Hello, world!\n");
> }
>
>
> ==> local-rename-to-hi:
> int hi(void) {
>     printf("Hello, world!\n");
> }
>
>
> ==> local-add-caller-of-core:
> int core(void) {
>     printf("Hello, world!\n");
> }
> /* caller */
> void caller(void) {
>     core();
> }
>
>
> ==> what an automatic merge of the two local-* branches would give:
> int hi(void) {
>     printf("Hello, world!\n");
> }
> /* caller */
> void caller(void) {
>     core();
> }
>
>
> ==> original-merge (amended from above by s/core/hi/ in caller()):
> int hi(void) {
>     printf("Hello, world!\n");
> }
> /* caller */
> void caller(void) {
>     hi();
> }
>
>
> ==> upstream:
> int greeting(void) {
>     printf("Hello, world!\n");
> }
> /* main event loop */
> void event_loop(void) {
>     /* TODO: place holder for now */
> }
>
>
> ==> rebase-of-local-rename-to-hi (kept 'hi' over 'greeting'):
> int hi(void) {
>     printf("Hello, world!\n");
> }
> /* main event loop */
> void event_loop(void) {
>     /* TODO: place holder for now */
> }
>
>
> ==> rebase-of-local-add-caller-of-core (kept both new functions,
> updated caller):
> int greeting(void) {
>     printf("Hello, world!\n");
> }
> /* main event loop */
> void event_loop(void) {
>     /* TODO: place holder for now */
> }
> /* caller */
> void caller(void) {
>     greeting();
> }

That all matches my recollection of what I wanted to drive at.

> 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.

Ciao,
Dscho

@gitgitgadget
Copy link

gitgitgadget bot commented Sep 13, 2021

On the Git mailing list, Elijah Newren wrote (reply to this):

On Mon, Sep 13, 2021 at 4:24 AM Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
>
> 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...]

> > 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.

@dscho
Copy link
Member Author

dscho commented Oct 19, 2021

Merged via 223a1bf

@dscho dscho closed this Oct 19, 2021
@dscho dscho deleted the drop-rebase-p branch October 19, 2021 10:40
@softworkz
Copy link

/test 1 (apologies)

@gitgitgadget
Copy link

gitgitgadget bot commented Dec 18, 2021

Error: User softworkz is not permitted to use GitGitGadget

@softworkz
Copy link

/test 2 (apologies)

@gitgitgadget
Copy link

gitgitgadget bot commented Dec 18, 2021

Error: User softworkz is not permitted to use GitGitGadget

@softworkz
Copy link

/test 3 (apologies)

@gitgitgadget
Copy link

gitgitgadget bot commented Dec 18, 2021

Error: User softworkz is not permitted to use GitGitGadget

@@ -125,7 +125,6 @@
/git-range-diff
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this):

On Tue, Sep 07 2021, Johannes Schindelin via GitGitGadget wrote:

> From: Johannes Schindelin <johannes.schindelin@gmx.de>
> [...]
> --p::
> ---preserve-merges::
> -	[DEPRECATED: use `--rebase-merges` instead] Recreate merge commits
> -	instead of flattening the history by replaying commits a merge commit
> -	introduces. Merge conflict resolutions or manual amendments to merge
> -	commits are not preserved.

[In reply to an old commit]

I opened "man git-rebase" today due to an on-list discussion and went
through pretty much:

 1. /preserve-merges # fails
 2. skimming the SYNOPSIS, forgetting what the new thing is called
 3. Paging down, eventually findinging & remembering the new thing is
    "--rebase-merges".

I wonder if there's objections to reinstating this in the docs
somewhere, just as something like:

	--preserve-merges:
		An old "rebase" backend which is no longer supported,
		and which was removed from git in version v2.35.0.

We don't do that with all flags that we've dropped, but perhaps this one
was well known enough to not leave readers hanging...

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Junio C Hamano wrote (reply to this):

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

> On Tue, Sep 07 2021, Johannes Schindelin via GitGitGadget wrote:
>
>> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>> [...]
>> --p::
>> ---preserve-merges::
>> -	[DEPRECATED: use `--rebase-merges` instead] Recreate merge commits
>> -	instead of flattening the history by replaying commits a merge commit
>> -	introduces. Merge conflict resolutions or manual amendments to merge
>> -	commits are not preserved.
>
> [In reply to an old commit]
>
> I opened "man git-rebase" today due to an on-list discussion and went
> through pretty much:
>
>  1. /preserve-merges # fails
>  2. skimming the SYNOPSIS, forgetting what the new thing is called
>  3. Paging down, eventually findinging & remembering the new thing is
>     "--rebase-merges".
>
> I wonder if there's objections to reinstating this in the docs
> somewhere, just as something like:
>
> 	--preserve-merges:
> 		An old "rebase" backend which is no longer supported,
> 		and which was removed from git in version v2.35.0.
>
> We don't do that with all flags that we've dropped, but perhaps this one
> was well known enough to not leave readers hanging...

My impression is that we consider that we have done so already for a
few releases by keeping "DEPRECATED: use rebase-merges", exactly
because "this one was well known enough", and now it is time to go
one step further, i.e. drop it from the document like the quoted
patch does, while recognising an attempt to use the option and
giving a custom message than the bog-standard "unknown option".

    $ git rebase --preserve-merges
    fatal: --preserve-merges was replaced by --rebase-merges
    Note: Your `pull.rebase` configuration may also be set to 'preserve',
    which is no longer supported; use 'merges' instead

The next step will be to drop that custom error support, I think.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Johannes Schindelin wrote (reply to this):

Hi Junio,

On Thu, 21 Jul 2022, Junio C Hamano wrote:

> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
> > On Tue, Sep 07 2021, Johannes Schindelin via GitGitGadget wrote:
> >
> >> From: Johannes Schindelin <johannes.schindelin@gmx.de>
> >> [...]
> >> --p::
> >> ---preserve-merges::
> >> -	[DEPRECATED: use `--rebase-merges` instead] Recreate merge commits
> >> -	instead of flattening the history by replaying commits a merge commit
> >> -	introduces. Merge conflict resolutions or manual amendments to merge
> >> -	commits are not preserved.
> >
> > [In reply to an old commit]
> >
> > I opened "man git-rebase" today due to an on-list discussion and went
> > through pretty much:
> >
> >  1. /preserve-merges # fails
> >  2. skimming the SYNOPSIS, forgetting what the new thing is called
> >  3. Paging down, eventually findinging & remembering the new thing is
> >     "--rebase-merges".
> >
> > I wonder if there's objections to reinstating this in the docs
> > somewhere, just as something like:
> >
> > 	--preserve-merges:
> > 		An old "rebase" backend which is no longer supported,
> > 		and which was removed from git in version v2.35.0.
> >
> > We don't do that with all flags that we've dropped, but perhaps this one
> > was well known enough to not leave readers hanging...
>
> My impression is that we consider that we have done so already for a
> few releases by keeping "DEPRECATED: use rebase-merges", exactly
> because "this one was well known enough", and now it is time to go
> one step further, i.e. drop it from the document like the quoted
> patch does, while recognising an attempt to use the option and
> giving a custom message than the bog-standard "unknown option".
>
>     $ git rebase --preserve-merges
>     fatal: --preserve-merges was replaced by --rebase-merges
>     Note: Your `pull.rebase` configuration may also be set to 'preserve',
>     which is no longer supported; use 'merges' instead
>
> The next step will be to drop that custom error support, I think.

Fully agree.

I _could_ see us introducing a sentence in the explanation of
`--rebase-merges` that leaves a historical note about superseding the
now-removed `--preserve-merges` option. But such historical notes tend to
go pretty stale pretty quickly, and eventually cause more confusion than
clarification.

So just like you said, I'd rather not re-introduce any text mentioning
`--preserve-merges` into the manual page.

Ciao,
Dscho

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants