* Thoughts about the -m option of cherry-pick and revert
@ 2024-06-20 10:05 Stefan Haller
2024-06-21 2:03 ` Junio C Hamano
0 siblings, 1 reply; 9+ messages in thread
From: Stefan Haller @ 2024-06-20 10:05 UTC (permalink / raw)
To: Git
There are plenty of StackOverflow questions and blog posts about the
error message that you get when you use git cherry-pick or git revert on
a merge commit without specifying the -m option. Many people don't seem
to understand what the error message means, or why they even get an
error in the first place.
The answers to these questions patiently explain what the error means
and why the -m option is necessary. Many of them contain example
scenarios; but I haven't seen a single one that doesn't use -m1 to
illustrate the usage.
I have two questions:
- What are real-world scenarios where you would use a mainline number
other than 1? I could only come up with a single example myself, which
is that you have a topic branch, and right before merging it back to
main, you merge main into the topic branch; and then you merge it to
main with a fast-forward merge. If you then want to cherry-pick or
revert that topic, you'd have to use -m2 on that last merge from main.
Any other examples?
- Wouldn't it make sense to default to -m1 when no -m option is given?
It seems that this would do the expected thing in the vast majority of
cases.
For the GUI client that I'm co-maintaining (lazygit), I'm actually
considering going so far as to not providing a choice at all, and always
using -m1. I'm not fully decided yet if that's a good idea, but it seems
that most people expect this, most of the time.
I'm probably missing something though, but what?
-Stefan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Thoughts about the -m option of cherry-pick and revert
2024-06-20 10:05 Thoughts about the -m option of cherry-pick and revert Stefan Haller
@ 2024-06-21 2:03 ` Junio C Hamano
2024-06-21 6:33 ` Stefan Haller
2024-06-21 10:12 ` Phillip Wood
0 siblings, 2 replies; 9+ messages in thread
From: Junio C Hamano @ 2024-06-21 2:03 UTC (permalink / raw)
To: Stefan Haller; +Cc: Git
Stefan Haller <lists@haller-berlin.de> writes:
> I have two questions:
>
> - What are real-world scenarios where you would use a mainline number
> other than 1? I could only come up with a single example myself, which
> is that you have a topic branch, and right before merging it back to
> main, you merge main into the topic branch; and then you merge it to
> main with a fast-forward merge. If you then want to cherry-pick or
> revert that topic, you'd have to use -m2 on that last merge from main.
> Any other examples?
I do think your example is a real issue that is helped by using -m2;
I do not think of any other cases offhand myself.
> - Wouldn't it make sense to default to -m1 when no -m option is given?
> It seems that this would do the expected thing in the vast majority of
> cases.
I do agree -m2 or higher would be rare when doing "git revert".
Given that the current behaviour was chosen to make sure that the
user is aware that the commit being reverted/cherry-picked is a
merge and has a chance to choose the right parent (as opposed to
blindly picking the first parent that happened to be the right one
by accident), I am not sure if it is prudent to change the
behaviour.
If I were simplifying this, I would probably
(1) disallow cherry-picking a merge (and suggest redoing the same
merge, possibly after rebasing the copy of the merged history
to an appropriate base as needed), and
(2) allowing reverting a merge only wrt the first parent,
but that is a different story.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Thoughts about the -m option of cherry-pick and revert
2024-06-21 2:03 ` Junio C Hamano
@ 2024-06-21 6:33 ` Stefan Haller
2024-06-21 10:19 ` Phillip Wood
2024-06-21 10:12 ` Phillip Wood
1 sibling, 1 reply; 9+ messages in thread
From: Stefan Haller @ 2024-06-21 6:33 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git
On 21.06.24 04:03, Junio C Hamano wrote:
> Stefan Haller <lists@haller-berlin.de> writes:
>
>> - Wouldn't it make sense to default to -m1 when no -m option is given?
>
> Given that the current behaviour was chosen to make sure that the
> user is aware that the commit being reverted/cherry-picked is a
> merge and has a chance to choose the right parent (as opposed to
> blindly picking the first parent that happened to be the right one
> by accident), I am not sure if it is prudent to change the
> behaviour.
Hm, in all example scenarios I experimented with, picking the wrong
parent would result in an empty diff, and consequently an error message
like this:
nothing to commit, working tree clean
The previous cherry-pick is now empty, possibly due to conflict
resolution.
If you wish to commit it anyway, use:
git commit --allow-empty
Otherwise, please use 'git cherry-pick --skip'
I'm not sure if this error is easier or harder to understand than the
one you get today when omitting -m, but we could probably improve it by
mentioning the -m option if the cherry-picked commit was a merge.
I'd be interested in example scenarios where both sides of the merge
have non-empty diffs. Won't this only happen for evil merges?
> If I were simplifying this, I would probably
>
> (1) disallow cherry-picking a merge (and suggest redoing the same
> merge, possibly after rebasing the copy of the merged history
> to an appropriate base as needed), and
This seems unnecessarily restrictive to me. Cherry-picking merge commits
using -m1 is useful, it's an important part of our release workflow at
my day job.
> (2) allowing reverting a merge only wrt the first parent,
Interesting, that's what I'm considering doing in lazygit (except for
both revert and cherry-pick), but I kind of didn't expect much support
for that idea. :-)
-Stefan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Thoughts about the -m option of cherry-pick and revert
2024-06-21 2:03 ` Junio C Hamano
2024-06-21 6:33 ` Stefan Haller
@ 2024-06-21 10:12 ` Phillip Wood
1 sibling, 0 replies; 9+ messages in thread
From: Phillip Wood @ 2024-06-21 10:12 UTC (permalink / raw)
To: Junio C Hamano, Stefan Haller; +Cc: Git
On 21/06/2024 03:03, Junio C Hamano wrote:
> Stefan Haller <lists@haller-berlin.de> writes:
>
> Given that the current behaviour was chosen to make sure that the
> user is aware that the commit being reverted/cherry-picked is a
> merge and has a chance to choose the right parent (as opposed to
> blindly picking the first parent that happened to be the right one
> by accident), I am not sure if it is prudent to change the
> behaviour.
FWIW I agree with this, for me the main benefit of the current behavior
is stopping when I'm not expecting to cherry-pick a merge.
Best Wishes
Phillip
> If I were simplifying this, I would probably
>
> (1) disallow cherry-picking a merge (and suggest redoing the same
> merge, possibly after rebasing the copy of the merged history
> to an appropriate base as needed), and
> (2) allowing reverting a merge only wrt the first parent,
>
> but that is a different story.
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Thoughts about the -m option of cherry-pick and revert
2024-06-21 6:33 ` Stefan Haller
@ 2024-06-21 10:19 ` Phillip Wood
2024-06-21 11:48 ` Stefan Haller
2024-06-21 16:34 ` Junio C Hamano
0 siblings, 2 replies; 9+ messages in thread
From: Phillip Wood @ 2024-06-21 10:19 UTC (permalink / raw)
To: Stefan Haller, Junio C Hamano; +Cc: Git
On 21/06/2024 07:33, Stefan Haller wrote:
> On 21.06.24 04:03, Junio C Hamano wrote:
>> Stefan Haller <lists@haller-berlin.de> writes:
>
> Hm, in all example scenarios I experimented with, picking the wrong
> parent would result in an empty diff, and consequently an error message
> like this:
>
> nothing to commit, working tree clean
> The previous cherry-pick is now empty, possibly due to conflict
> resolution.
> If you wish to commit it anyway, use:
>
> git commit --allow-empty
>
> Otherwise, please use 'git cherry-pick --skip'
>
> I'm not sure if this error is easier or harder to understand than the
> one you get today when omitting -m, but we could probably improve it by
> mentioning the -m option if the cherry-picked commit was a merge.
That might be helpful - if we do that we'd want to make sure that the
user can retry this pick with "-m" without restarting the whole cherry-pick.
> I'd be interested in example scenarios where both sides of the merge
> have non-empty diffs. Won't this only happen for evil merges?
I think you'd need a conflicting merge that is resolved in a way that
the resolution of the conflicting lines doesn't match either parent. (I
assume that's what you mean by evil but I thought it best to check)
>> If I were simplifying this, I would probably
>>
>> (1) disallow cherry-picking a merge (and suggest redoing the same
>> merge, possibly after rebasing the copy of the merged history
>> to an appropriate base as needed), and
>
> This seems unnecessarily restrictive to me. Cherry-picking merge commits
> using -m1 is useful, it's an important part of our release workflow at
> my day job.
I can see why people want to revert merges but cherry-picking them
always feels strange to me - what is the advantage over actually merging
the branch and seeing the full history of that commit?
>> (2) allowing reverting a merge only wrt the first parent,
>
> Interesting, that's what I'm considering doing in lazygit (except for
> both revert and cherry-pick), but I kind of didn't expect much support
> for that idea. :-)
For lazygit I would think it would be fine to be a bit more restrictive
that git as anyone with an unusual requirement can always fall back to
using git for that.
Best Wishes
Phillip
> -Stefan
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Thoughts about the -m option of cherry-pick and revert
2024-06-21 10:19 ` Phillip Wood
@ 2024-06-21 11:48 ` Stefan Haller
2024-06-21 16:34 ` Junio C Hamano
1 sibling, 0 replies; 9+ messages in thread
From: Stefan Haller @ 2024-06-21 11:48 UTC (permalink / raw)
To: phillip.wood, Junio C Hamano; +Cc: Git
On 21.06.24 12:19, Phillip Wood wrote:
> On 21/06/2024 07:33, Stefan Haller wrote:
>
>> I'd be interested in example scenarios where both sides of the merge
>> have non-empty diffs. Won't this only happen for evil merges?
>
> I think you'd need a conflicting merge that is resolved in a way that
> the resolution of the conflicting lines doesn't match either parent. (I
> assume that's what you mean by evil but I thought it best to check)
Ah yes, that's another example, but it's not an evil merge. An evil
merge is one that has additional changes that don't come from either
side, and don't come from conflict resolution (e.g. they were amended
into the merge). I thought that was commonly understood terminology.
>> This seems unnecessarily restrictive to me. Cherry-picking merge commits
>> using -m1 is useful, it's an important part of our release workflow at
>> my day job.
>
> I can see why people want to revert merges but cherry-picking them
> always feels strange to me - what is the advantage over actually merging
> the branch and seeing the full history of that commit?
It's less work (if you otherwise insist on rebasing the branch to the
destination before merging), and results in a simpler graph that's
easier to understand (if you don't).
And I suppose you could ask the same question about the --squash option
of git-merge.
-Stefan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Thoughts about the -m option of cherry-pick and revert
2024-06-21 10:19 ` Phillip Wood
2024-06-21 11:48 ` Stefan Haller
@ 2024-06-21 16:34 ` Junio C Hamano
2024-06-24 7:33 ` Stefan Haller
1 sibling, 1 reply; 9+ messages in thread
From: Junio C Hamano @ 2024-06-21 16:34 UTC (permalink / raw)
To: Phillip Wood; +Cc: Stefan Haller, Git
Phillip Wood <phillip.wood123@gmail.com> writes:
> I can see why people want to revert merges but cherry-picking them
> always feels strange to me - what is the advantage over actually
> merging the branch and seeing the full history of that commit?
One case that comes to my mind is when you failed to plan ahead and
used a wrong base when building a series to "fix" an old bug. You
built a 7-patch series to fix a bug that you introduced in release
1.0, but instead of basing the fix on maint-1.0 maintenance track,
you forked from the tip of master that is preparing for your next
feature release that is release 1.4.
Even if you realized that the fix is important enough to warrant
applying to the maint-1.0 maintenance track, you cannot merge the
topic that houses 7-patch series down to the old maintenance track
without bringing all the new features that happened since 1.0 on the
master track.
A kosher way may be to rebase the 7-patch series to maint-1.0 and
merge the result into the maint-1.0 track (and upwards if needed).
But cherry-picking the commit that merged the original "fix" topic
into master _may_ be simpler, as you need to resolve a larger
conflict but (hopefully) only once, instead of up to 7 times, once
per each commit on the "fix" topic while rebasing.
But of course if something goes wrong, it makes the result
impossible to bisect---exactly the same reason why you should think
twice before doing a "merge --squash". In addition, if you somehow
figured out why the cherry-picked fix was inadequate, you'd now need
to forward-port the fix for the fix to the master track or whereever
the cherry-picked-merge was taken from.
On the other hand, if the original "fix" branch was rebased on
maint-1.0 and then further fixed, the result can be merged to
maint-1.0 as well as all the way to the master track.
So, I can understand why people may want to cherry-pick a merge,
I suspect it is a false economy. Optimizing for picking, paying
higher price when the result of (incorrect) picking has to be
corrected later.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Thoughts about the -m option of cherry-pick and revert
2024-06-21 16:34 ` Junio C Hamano
@ 2024-06-24 7:33 ` Stefan Haller
2024-06-24 18:43 ` Junio C Hamano
0 siblings, 1 reply; 9+ messages in thread
From: Stefan Haller @ 2024-06-24 7:33 UTC (permalink / raw)
To: Junio C Hamano, Phillip Wood; +Cc: Git
On 21.06.24 18:34, Junio C Hamano wrote:
> Phillip Wood <phillip.wood123@gmail.com> writes:
>
>> I can see why people want to revert merges but cherry-picking them
>> always feels strange to me - what is the advantage over actually
>> merging the branch and seeing the full history of that commit?
>
> One case that comes to my mind is when you failed to plan ahead and
> used a wrong base when building a series to "fix" an old bug. You
> built a 7-patch series to fix a bug that you introduced in release
> 1.0, but instead of basing the fix on maint-1.0 maintenance track,
> you forked from the tip of master that is preparing for your next
> feature release that is release 1.4.
>
> Even if you realized that the fix is important enough to warrant
> applying to the maint-1.0 maintenance track, you cannot merge the
> topic that houses 7-patch series down to the old maintenance track
> without bringing all the new features that happened since 1.0 on the
> master track.
>
> A kosher way may be to rebase the 7-patch series to maint-1.0 and
> merge the result into the maint-1.0 track (and upwards if needed).
> But cherry-picking the commit that merged the original "fix" topic
> into master _may_ be simpler, as you need to resolve a larger
> conflict but (hopefully) only once, instead of up to 7 times, once
> per each commit on the "fix" topic while rebasing.
>
> But of course if something goes wrong, it makes the result
> impossible to bisect---exactly the same reason why you should think
> twice before doing a "merge --squash". In addition, if you somehow
> figured out why the cherry-picked fix was inadequate, you'd now need
> to forward-port the fix for the fix to the master track or whereever
> the cherry-picked-merge was taken from.
>
> On the other hand, if the original "fix" branch was rebased on
> maint-1.0 and then further fixed, the result can be merged to
> maint-1.0 as well as all the way to the master track.
>
> So, I can understand why people may want to cherry-pick a merge,
> I suspect it is a false economy. Optimizing for picking, paying
> higher price when the result of (incorrect) picking has to be
> corrected later.
You may call this "failed to plan ahead", but for us it's a deliberate
decision to work this way. Developers work exclusively on main, and
merge their branches to main, always. Release management decides later
(sometimes much later) which of these branches are cherry-picked to
which release branches. We never merge back from a release branch to main.
And we prefer single-commit cherry-picks of the merge commits because it
makes the history of the release branches easier to read. Bisectability
is not an issue; developers bisect failures on the main branch. (Yes,
I'm aware that there may be cases where a defect manifests itself
differently (or not at all) on main than on the release branch, but
these are so rare that it hasn't been an issue for us so far.)
I'm not saying I'm very happy with this workflow, it wasn't my decision.
And in particular I'm not trying to argue which workflow is better than
the other; all I'm saying is that there are teams who decide they want
to cherry-pick merge commits, so git should continue to allow it. This
is only in response to your earlier "If I were simplifying this, I would
probably [...] disallow cherry-picking a merge".
(Side note: my main gripe about cherry-picking in general is, of course,
that it makes it impossible to use "git branch --contains" or "git tag
--contains" to find out which releases contain a given bug fix; but
that's a problem no matter whether you cherry-pick the merge commit, or
replay the branch on maint and merge it there again.)
-Stefan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Thoughts about the -m option of cherry-pick and revert
2024-06-24 7:33 ` Stefan Haller
@ 2024-06-24 18:43 ` Junio C Hamano
0 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2024-06-24 18:43 UTC (permalink / raw)
To: Stefan Haller; +Cc: Phillip Wood, Git
Stefan Haller <lists@haller-berlin.de> writes:
> And we prefer single-commit cherry-picks of the merge commits because it
> makes the history of the release branches easier to read.
I would have expected that "git log --first-parent" would give you
the same "easy-to-read" history as a run of squached cherry-picks.
It of course takes some discipline to ensure that the first-parent
chain is kept meaningful, but "never merge, always cherry-pick the
merges of topics" also already takes some discipline, so I do not
see either workflow has much upside with respect to this point.
> I'm not saying I'm very happy with this workflow, it wasn't my decision.
> And in particular I'm not trying to argue which workflow is better than
> the other; all I'm saying is that there are teams who decide they want
> to cherry-pick merge commits, so git should continue to allow it. This
> is only in response to your earlier "If I were simplifying this, I would
> probably [...] disallow cherry-picking a merge".
Sure. I thought it was fairly obvious to everybody that I was not
"simplifying this", at least unilaterally, so raising a concern like
you did was the right thing ;-).
> (Side note: my main gripe about cherry-picking in general is, of course,
> that it makes it impossible to use "git branch --contains" or "git tag
> --contains" to find out which releases contain a given bug fix; but
> that's a problem no matter whether you cherry-pick the merge commit, or
> replay the branch on maint and merge it there again.)
Correct for the "cherry-picking", but not necessarily for a "rebase
and merge".
You can have (1) a "fix" based on the "main", and (2) the backport
of the same "fix" rebased on the "maint", the latter of which has
likely been spawned after the former was merged to "main". You can
merge the "rebased fix" to the "maint" *as well as* to the "main".
If we think about it, that is a natural thing to do. By rebasing
"fix" to "maint" to create "rebased fix", we are "correcting" an
earlier mistake of basing the fix on a wrong (iow, too recent)
point, so after such a rebase, we treat the rebased result as the
primary thing.
After that, "contains" will do the right thing for the "rebased
fix", which is now the primary fix, and shows both "main" and
"maint" has it.
Of course, a project can choose to adopt a workflow that refuses to
obtain such a benefit (presumably for other reasons that gives
benefits that outweigh the "sigh, we cannot merge but have to
cherry-pick, with all the inconveniences").
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2024-06-24 18:43 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-20 10:05 Thoughts about the -m option of cherry-pick and revert Stefan Haller
2024-06-21 2:03 ` Junio C Hamano
2024-06-21 6:33 ` Stefan Haller
2024-06-21 10:19 ` Phillip Wood
2024-06-21 11:48 ` Stefan Haller
2024-06-21 16:34 ` Junio C Hamano
2024-06-24 7:33 ` Stefan Haller
2024-06-24 18:43 ` Junio C Hamano
2024-06-21 10:12 ` Phillip Wood
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).