{"thread":{"id":"47757","subject":"cherry-pick '-m' curiosity","startedAt":"2018-02-05T11:54:22Z","lastAt":"2018-02-20T16:23:17Z","messageCount":7,"participants":["Sergey Organov","Junio C Hamano","Stefan Beller","G. Sylvie Davies"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"338213","messageId":"87wozry7z4.fsf@javad.com","threadId":"47757","inReplyTo":null,"subject":"cherry-pick '-m' curiosity","fromName":"Sergey Organov","fromEmail":"sorganov@gmail.com","sentAt":"2018-02-05T11:46:39Z","receivedAt":"2018-02-05T11:54:22Z","isPatch":false,"sender":{"key":"sorganov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8501568?v=4"},"body":"Hello,\n\n$ git help cherry-pick\n\n-m parent-number, --mainline parent-number\n           Usually you cannot cherry-pick a merge because you do not\n           know which side of the merge should be considered the\n           mainline.\n\nIsn't it always the case that \"mainline\" is the first parent, as that's\nhow \"git merge\" happens to work?\n\nIs, say, \"-m 2\" ever useful?\n\n-- \nSergey\n"},{"id":"338238","messageId":"xmqqtvuv9po8.fsf@gitster-ct.c.googlers.com","threadId":"47757","inReplyTo":"87wozry7z4.fsf@javad.com","subject":"Re: cherry-pick '-m' curiosity","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-02-05T19:55:51Z","receivedAt":"2018-02-05T19:55:59Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sergey Organov <sorganov@gmail.com> writes:\n\n> Isn't it always the case that \"mainline\" is the first parent, as that's\n> how \"git merge\" happens to work?\n\nYou may not be merging into the \"mainline\" in the first place.\n\nImagine forking two topics at the same commit on the mainline, and\nmerging these two topics of equal importance together into a single\nbigger topic, before asking the mainline to pull the whole.\n\n    $ git checkout mainline\n    $ git tag fork-point\n    $ git checkout -b frontend-topic fork-point\n    $ work work work\n    $ git checkout -b backend-topic fork-point\n    $ work work work\n    $ git checkout -b combined\n    $ git merge frontend-topic\n    $ git tag merged\n\nThe backend-topic may be recorded as the first-parent of the\nresulting merge, but logically the two topics are of equal footing,\nso merge^1..merge and merge^2..merge are both equally interesting.\n\n\n\n"},{"id":"338262","messageId":"CAGZ79kZ5ZiETM7L6DRr1pSXMGBPPyOazsM8Gi0E9jrMYfwrfdA@mail.gmail.com","threadId":"47757","inReplyTo":"87wozry7z4.fsf@javad.com","subject":"Re: cherry-pick '-m' curiosity","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-02-05T22:03:12Z","receivedAt":"2018-02-05T22:03:20Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Mon, Feb 5, 2018 at 3:46 AM, Sergey Organov <sorganov@gmail.com> wrote:\n> Hello,\n>\n> $ git help cherry-pick\n>\n> -m parent-number, --mainline parent-number\n>            Usually you cannot cherry-pick a merge because you do not\n>            know which side of the merge should be considered the\n>            mainline.\n>\n> Isn't it always the case that \"mainline\" is the first parent, as that's\n> how \"git merge\" happens to work?\n>\n> Is, say, \"-m 2\" ever useful?\n\nSay you want to backport everything except that topic using cherry-picks.\nThen -m2 would be useful?\n"},{"id":"338491","messageId":"87eflyv5a1.fsf@javad.com","threadId":"47757","inReplyTo":"CAGZ79kZ5ZiETM7L6DRr1pSXMGBPPyOazsM8Gi0E9jrMYfwrfdA@mail.gmail.com","subject":"Re: cherry-pick '-m' curiosity","fromName":"Sergey Organov","fromEmail":"sorganov@gmail.com","sentAt":"2018-02-06T09:25:26Z","receivedAt":"2018-02-06T09:25:34Z","isPatch":false,"sender":{"key":"sorganov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8501568?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> On Mon, Feb 5, 2018 at 3:46 AM, Sergey Organov <sorganov@gmail.com> wrote:\n>> Hello,\n>>\n>> $ git help cherry-pick\n>>\n>> -m parent-number, --mainline parent-number\n>>            Usually you cannot cherry-pick a merge because you do not\n>>            know which side of the merge should be considered the\n>>            mainline.\n>>\n>> Isn't it always the case that \"mainline\" is the first parent, as that's\n>> how \"git merge\" happens to work?\n>>\n>> Is, say, \"-m 2\" ever useful?\n>\n> Say you want to backport everything except that topic using cherry-picks.\n> Then -m2 would be useful?\n\nDidn't get the idea, sorry. Care to clarify?\n\n-- Sergey\n"},{"id":"338505","messageId":"87y3k6tgi4.fsf@javad.com","threadId":"47757","inReplyTo":"xmqqtvuv9po8.fsf@gitster-ct.c.googlers.com","subject":"Re: cherry-pick '-m' curiosity","fromName":"Sergey Organov","fromEmail":"sorganov@gmail.com","sentAt":"2018-02-06T13:05:55Z","receivedAt":"2018-02-06T13:06:12Z","isPatch":false,"sender":{"key":"sorganov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8501568?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Sergey Organov <sorganov@gmail.com> writes:\n>\n>> Isn't it always the case that \"mainline\" is the first parent, as that's\n>> how \"git merge\" happens to work?\n>\n> You may not be merging into the \"mainline\" in the first place.\n>\n> Imagine forking two topics at the same commit on the mainline, and\n> merging these two topics of equal importance together into a single\n> bigger topic, before asking the mainline to pull the whole.\n>\n>     $ git checkout mainline\n>     $ git tag fork-point\n>     $ git checkout -b frontend-topic fork-point\n>     $ work work work\n>     $ git checkout -b backend-topic fork-point\n>     $ work work work\n>     $ git checkout -b combined\n>     $ git merge frontend-topic\n>     $ git tag merged\n>\n> The backend-topic may be recorded as the first-parent of the\n> resulting merge, but logically the two topics are of equal footing,\n> so merge^1..merge and merge^2..merge are both equally interesting.\n\nPoint taken, thanks! Now, if I reformulate my original question as:\n\n\"Isn't it _usually_ the case that \"mainline\" is the first parent?\"\n\nwhat is the answer?\n\nFor example, in the above case I'd likely rather: \n\n     $ git checkout -b combined fork-point\n     $ git merge --no-ff frontend-topic\n     $ git merge --no-ff backend-topic\n\nand still have clear \"mainline\" on \"-m1\" for both merges.\n\nI'm asking because those:\n\n\"Usually you cannot cherry-pick a merge because you do not know which\nside of the merge should be considered the mainline.\"\n\nin the manual page still feels confusing in the context of typical git\nusage (as opposed to the context of abstract DAG operations where it'd\nmake sense indeed.)\n\n-- Sergey\n"},{"id":"339642","messageId":"CAAj3zPxiLxqgnKXth2EZZWwgYhW_cHEcxbM6_BqpzpHR_ipqyQ@mail.gmail.com","threadId":"47757","inReplyTo":"87wozry7z4.fsf@javad.com","subject":"Re: cherry-pick '-m' curiosity","fromName":"G. Sylvie Davies","fromEmail":"sylvie@bit-booster.com","sentAt":"2018-02-19T21:39:59Z","receivedAt":"2018-02-19T21:40:07Z","isPatch":false,"sender":{"key":"sylvie@bit-booster.com","avatar":"https://gravatar.com/avatar/eb5bda7d3fb1e3361252bbf100d1f355ffe9ff8d8b559a08e4c7bc17d6f949d5?d=mp&s=160"},"body":"On Mon, Feb 5, 2018 at 3:46 AM, Sergey Organov <sorganov@gmail.com> wrote:\n> Hello,\n>\n> $ git help cherry-pick\n>\n> -m parent-number, --mainline parent-number\n>            Usually you cannot cherry-pick a merge because you do not\n>            know which side of the merge should be considered the\n>            mainline.\n>\n> Isn't it always the case that \"mainline\" is the first parent, as that's\n> how \"git merge\" happens to work?\n>\n\nFirst-parent will be whatever commit you were sitting on when you\ntyped \"git merge\".\n\nIf you're sitting on your branch and you type \"git fetch; git merge\norigin/master\", then \"mainline\" will be 2nd parent.\n\nSame happens if you type \"git pull\".\n\nFurther reading here:\nhttps://developer.atlassian.com/blog/2016/04/stop-foxtrots-now/\n\n\"git revert -m\" also has the same problem.\n\n\n> Is, say, \"-m 2\" ever useful?\n>\n> --\n> Sergey\n"},{"id":"339712","messageId":"87606rk4ur.fsf@javad.com","threadId":"47757","inReplyTo":"CAAj3zPxiLxqgnKXth2EZZWwgYhW_cHEcxbM6_BqpzpHR_ipqyQ@mail.gmail.com","subject":"Re: cherry-pick '-m' curiosity","fromName":"Sergey Organov","fromEmail":"sorganov@gmail.com","sentAt":"2018-02-20T16:23:08Z","receivedAt":"2018-02-20T16:23:17Z","isPatch":false,"sender":{"key":"sorganov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8501568?v=4"},"body":"\"G. Sylvie Davies\" <sylvie@bit-booster.com> writes:\n\n> On Mon, Feb 5, 2018 at 3:46 AM, Sergey Organov <sorganov@gmail.com> wrote:\n>> Hello,\n>>\n>> $ git help cherry-pick\n>>\n>> -m parent-number, --mainline parent-number\n>>            Usually you cannot cherry-pick a merge because you do not\n>>            know which side of the merge should be considered the\n>>            mainline.\n>>\n>> Isn't it always the case that \"mainline\" is the first parent, as that's\n>> how \"git merge\" happens to work?\n>>\n>\n> First-parent will be whatever commit you were sitting on when you\n> typed \"git merge\".\n\nRight, but I believe it's also \"mainline\", see below.\n\n> If you're sitting on your branch and you type \"git fetch; git merge\n> origin/master\", then \"mainline\" will be 2nd parent.\n\nNo. If you ever want to cherry-pick this commit, it'd still be -m1 side\nof it that likely makes sense, and it's exactly the side that makes\nsense to be picked that is called \"mainline\" in the manual page we are\ndiscussing, and there is no any other definition of \"mainline\" as far as\nI can tell.\n\nThere is nothing about 'origin/master' that makes it \"mainline\" from the\nPOV of future cherry-picks, if any, of this merge commit. I was also\nunable to find any git documentation that calls 'origin/master'\n\"mainline\". It's called \"remote-tracking branch\", or maybe sometimes\n\"upstream\".\n\nOTOH, when one merges something, he often merges \"side branch\" onto\n\"mainline\", so in the context of this particular merge, your local\n\"master\" happens to be \"mainline\" and \"origin/master\" happens to be\n\"side branch\".\n\n> \"git revert -m\" also has the same problem.\n\nYes, as it's essentially just \"git cherry-pick --reverse -m\", provided\ncherry-pick has had the \"--reverse\" from regular \"patch\" utility [*].\n\nIt's also interesting to notice that manual page for \"git revert\" refers\nto the revert-a-faulty-merge How-To, that in turn again uses only \"git\nrevert -m 1\".\n\nOverall, it's still a mystery to me why \"-m 1\" is not the default\nbehavior for both \"git revert\" and \"git cherry-pick\".\n\nThe only suspicion I have is that actual intention is to deny picking\nmerge commits by default. Then, the usual git way would be to use\n--force or --enable-merges to overcome the denial, but if we still do\nneed \"-m 2\" etc. even rarely, then rather re-using \"-m 1\" as \"I mean it\"\nindication is only logical.\n\nIf my suspicion is true, how about something like this:\n\n-m parent-number, --mainline parent-number\n\tThis option specifies the parent number (starting from 1) of a\n\tcommit and instructs cherry-pick to replay the change relative\n\tto the specified parent. Cherry-pick will refuse to handle merge\n\tcommits unless this option is given.\n\nDamn, it now has no \"mainline\" in the description at all, so it's\nunclear why it has been called --mainline in the first place, not that\nit was somehow clear to me before.\n\nAnd while we are at it, I just stumbled over \"git cherry-pick -m 1\"\nrefusing to handle non-merge commits:\n\n$ git cherry-pick -m1 dd5c320\nerror: Mainline was specified but commit dd5c320a300520a044cfa73d17f6cbffbbef60ef is not a merge.\nfatal: cherry-pick failed\n$ \n\nI wonder whether this is intentional? What's the rationale then? It\nseems it could be useful to be able to cherry-pick multiple commits,\nsome of which are merges, no?\n\nFootnote:\n\n[*] rebase, revert, and cherry-pick all look rather similar in git and\ncould be calling for some unification.\n\n-- Sergey\n"}]}