{"thread":{"id":"48496","subject":"could `git merge --no-ff origin/master` be made more useful?","startedAt":"2018-05-14T22:08:06Z","lastAt":"2018-05-15T08:27:33Z","messageCount":3,"participants":["demerphq","Ævar Arnfjörð Bjarmason"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"347663","messageId":"CANgJU+VFCY0LNRLMSGtD7ScpcLaPFMzUOyw6Bjgk6q=Kx9DvCg@mail.gmail.com","threadId":"48496","inReplyTo":null,"subject":"could `git merge --no-ff origin/master` be made more useful?","fromName":"demerphq","fromEmail":"demerphq@gmail.com","sentAt":"2018-05-14T22:08:00Z","receivedAt":"2018-05-14T22:08:06Z","isPatch":false,"sender":{"key":"demerphq@gmail.com","avatar":null},"body":"The first time I tried to use --no-ff I tried to do something like this:\n\n  git checkout master\n  git commit -a -m'whatever'\n  git commit -a -m'whatever2'\n  git merge --no-ff origin/master\n\nand was disappointed when \"it didn't work\" and git told me there was\nnothing to do as the branch was up to date. (Which I found a bit\nconfusing.)\n\nI realize now my expectations were incorrect, and that the argument to\nmerge needs to resolve to a commit that is ahead of the current\ncommit, and in the above sequence it is the other way around. So to do\nwhat I want I can do:\n\n  git checkout master\n  git checkout -b topic\n  git commit -a -m'whatever'\n  git commit -a -m'whatever2'\n  git checkout master\n  git merge --no-ff topic\n\nand iiuir this works because 'master' would be behind 'topic' in this case.\n\nBut I have a few questions, 1) is there is an argument to feed to git\nmerge to make the first recipe work like the second? And 2) is this\nasymmetry necessary with --no-ff?\n\nMore specifically would something horrible break if --no-ff\norigin/trunk detected that the current branch was ahead of the named\nbranch and \"swapped\"  the implicit order of the two so that the first\nrecipe could behave like the second?\n\nAnyway, even if the above makes no sense, would it be hard to make the\nmessage provided by git merge in the first recipe a bit more\nsuggestive of what is going on? For instance if it had said \"Cannot\n--no-ff merge, origin/master is behind master\" it would have been much\nmore clear what was going on.\n\nYves\n\n\n\n\n\n\n\n\n\n\n-- \nperl -Mre=debug -e \"/just|another|perl|hacker/\"\n"},{"id":"347664","messageId":"87lgcl3kv9.fsf@evledraar.gmail.com","threadId":"48496","inReplyTo":"CANgJU+VFCY0LNRLMSGtD7ScpcLaPFMzUOyw6Bjgk6q=Kx9DvCg@mail.gmail.com","subject":"Re: could `git merge --no-ff origin/master` be made more useful?","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-05-14T22:58:34Z","receivedAt":"2018-05-14T22:58:41Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Mon, May 14 2018, demerphq wrote:\n\n> The first time I tried to use --no-ff I tried to do something like this:\n>\n>   git checkout master\n>   git commit -a -m'whatever'\n>   git commit -a -m'whatever2'\n>   git merge --no-ff origin/master\n>\n> and was disappointed when \"it didn't work\" and git told me there was\n> nothing to do as the branch was up to date. (Which I found a bit\n> confusing.)\n>\n> I realize now my expectations were incorrect, and that the argument to\n> merge needs to resolve to a commit that is ahead of the current\n> commit, and in the above sequence it is the other way around. So to do\n> what I want I can do:\n>\n>   git checkout master\n>   git checkout -b topic\n>   git commit -a -m'whatever'\n>   git commit -a -m'whatever2'\n>   git checkout master\n>   git merge --no-ff topic\n>\n> and iiuir this works because 'master' would be behind 'topic' in this case.\n>\n> But I have a few questions, 1) is there is an argument to feed to git\n> merge to make the first recipe work like the second? And 2) is this\n> asymmetry necessary with --no-ff?\n\nI've been bitten my this myself, but found that it's documented as the\nvery first thing in git-merge:\n\n    Incorporates changes from the named commits (since the time their\n    histories diverged from the current branch) into the current\n    branch[...].\n\nSince origin/master hasn't diverged from your current branch (unlike the\nother way around), the merge with --no-ff is a noop.\n\n> More specifically would something horrible break if --no-ff\n> origin/trunk detected that the current branch was ahead of the named\n> branch and \"swapped\"  the implicit order of the two so that the first\n> recipe could behave like the second\n\nIf it worked like that then the user who sets merge.ff=false in his\nconfig and issues a \"git pull\" after making a commit on his local master\nwould create a merge commit.\n\nThis old E-Mail of Junio's discusses that edge case & others in detail:\nhttps://public-inbox.org/git/7vty1zfwmd.fsf@alter.siamese.dyndns.org/\n\n> Anyway, even if the above makes no sense, would it be hard to make the\n> message provided by git merge in the first recipe a bit more\n> suggestive of what is going on? For instance if it had said \"Cannot\n> --no-ff merge, origin/master is behind master\" it would have been much\n> more clear what was going on.\n\nI can't spot any reason for why we couldn't have something like this POC\n(would be properly done through advice.c):\n\n    diff --git a/builtin/merge.c b/builtin/merge.c\n    index 9db5a2cf16..920f67d9f8 100644\n    --- a/builtin/merge.c\n    +++ b/builtin/merge.c\n    @@ -1407,6 +1407,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n                     * but first the most common case of merging one remote.\n                     */\n                    finish_up_to_date(_(\"Already up to date.\"));\n    +               if (fast_forward == FF_NO)\n    +                       fprintf(stderr, \"did you mean this the other way around?\\n\");\n                    goto done;\n            } else if (fast_forward != FF_NO && !remoteheads->next &&\n                            !common->next &&\n\nBut that should probably be reworked to be smart about whether --no-ff\nor merge.ff=false was specified, i.e. do we want to yell this at the\nuser who's just set that at his config default, or the user who's\nspecified --no-ff explicitly, or both? I don't know.\n"},{"id":"347686","messageId":"CANgJU+W7JcA=W4dNn5uVj_=iiGCCfE6uD4cR=v5qPyCTRr3ARw@mail.gmail.com","threadId":"48496","inReplyTo":"87lgcl3kv9.fsf@evledraar.gmail.com","subject":"Re: could `git merge --no-ff origin/master` be made more useful?","fromName":"demerphq","fromEmail":"demerphq@gmail.com","sentAt":"2018-05-15T08:27:25Z","receivedAt":"2018-05-15T08:27:33Z","isPatch":false,"sender":{"key":"demerphq@gmail.com","avatar":null},"body":"On 15 May 2018 at 00:58, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n>\n> On Mon, May 14 2018, demerphq wrote:\n>\n>> The first time I tried to use --no-ff I tried to do something like this:\n>>\n>>   git checkout master\n>>   git commit -a -m'whatever'\n>>   git commit -a -m'whatever2'\n>>   git merge --no-ff origin/master\n>>\n>> and was disappointed when \"it didn't work\" and git told me there was\n>> nothing to do as the branch was up to date. (Which I found a bit\n>> confusing.)\n>>\n>> I realize now my expectations were incorrect, and that the argument to\n>> merge needs to resolve to a commit that is ahead of the current\n>> commit, and in the above sequence it is the other way around. So to do\n>> what I want I can do:\n>>\n>>   git checkout master\n>>   git checkout -b topic\n>>   git commit -a -m'whatever'\n>>   git commit -a -m'whatever2'\n>>   git checkout master\n>>   git merge --no-ff topic\n>>\n>> and iiuir this works because 'master' would be behind 'topic' in this case.\n>>\n>> But I have a few questions, 1) is there is an argument to feed to git\n>> merge to make the first recipe work like the second? And 2) is this\n>> asymmetry necessary with --no-ff?\n>\n> I've been bitten my this myself, but found that it's documented as the\n> very first thing in git-merge:\n>\n>     Incorporates changes from the named commits (since the time their\n>     histories diverged from the current branch) into the current\n>     branch[...].\n>\n> Since origin/master hasn't diverged from your current branch (unlike the\n> other way around), the merge with --no-ff is a noop.\n\nYeah, I got it, but only after rereading a lot of times.\n\n>\n>> More specifically would something horrible break if --no-ff\n>> origin/trunk detected that the current branch was ahead of the named\n>> branch and \"swapped\"  the implicit order of the two so that the first\n>> recipe could behave like the second\n>\n> If it worked like that then the user who sets merge.ff=false in his\n> config and issues a \"git pull\" after making a commit on his local master\n> would create a merge commit.\n>\n> This old E-Mail of Junio's discusses that edge case & others in detail:\n> https://public-inbox.org/git/7vty1zfwmd.fsf@alter.siamese.dyndns.org/\n\nThanks I skimmed, but it is long so I will review later.\n\nI see the point about the config option for no-ff.\n\nBut what about an option like --reverse? Assuming we are on a local\nbranch master then\n\n  git merge --no-ff --reverse origin/master\n\nwould treat origin/master as the \"current\" branch, and \"master\" as the\nmerged in branch, and create the appropriate merge commit. Which as\nfar as I can tell is tree-wise identical to creating a topic branch\ninstead of hacking on the local master.\n\n>> Anyway, even if the above makes no sense, would it be hard to make the\n>> message provided by git merge in the first recipe a bit more\n>> suggestive of what is going on? For instance if it had said \"Cannot\n>> --no-ff merge, origin/master is behind master\" it would have been much\n>> more clear what was going on.\n>\n> I can't spot any reason for why we couldn't have something like this POC\n> (would be properly done through advice.c):\n>\n>     diff --git a/builtin/merge.c b/builtin/merge.c\n>     index 9db5a2cf16..920f67d9f8 100644\n>     --- a/builtin/merge.c\n>     +++ b/builtin/merge.c\n>     @@ -1407,6 +1407,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n>                      * but first the most common case of merging one remote.\n>                      */\n>                     finish_up_to_date(_(\"Already up to date.\"));\n>     +               if (fast_forward == FF_NO)\n>     +                       fprintf(stderr, \"did you mean this the other way around?\\n\");\n>                     goto done;\n>             } else if (fast_forward != FF_NO && !remoteheads->next &&\n>                             !common->next &&\n>\n> But that should probably be reworked to be smart about whether --no-ff\n> or merge.ff=false was specified, i.e. do we want to yell this at the\n> user who's just set that at his config default, or the user who's\n> specified --no-ff explicitly, or both? I don't know.\n\nYes, all those points make sense.\n\nYves\n\n\n-- \nperl -Mre=debug -e \"/just|another|perl|hacker/\"\n"}]}