{"thread":{"id":"53117","subject":"[PATCH] pull: avoid running both merge and rebase","startedAt":"2020-03-27T21:51:45Z","lastAt":"2020-04-04T13:48:04Z","messageCount":7,"participants":["Elijah Newren via GitGitGadget","Junio C Hamano","Jeff King","Derrick Stolee","Elijah Newren","Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"394205","messageId":"pull.739.git.git.1585345900763.gitgitgadget@gmail.com","threadId":"53117","inReplyTo":null,"subject":"[PATCH] pull: avoid running both merge and rebase","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-03-27T21:51:40Z","receivedAt":"2020-03-27T21:51:45Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nWhen opt_rebase is true, we still first check if we can fast-forward.\nIf the branch is fast-forwardable, then we can avoid the rebase and just\nuse merge to do the fast-forward logic.  However, when commit a6d7eb2c7a\n(\"pull: optionally rebase submodules (remote submodule changes only)\",\n2017-06-23) added the ability to rebase submodules it accidentally\ncaused us to run BOTH a merge and a rebase.  Add a flag to avoid doing\nboth.\n\nThis was found when a user had both pull.rebase and rebase.autosquash\nset to true.  In such a case, the running of both merge and rebase would\ncause ORIG_HEAD to be updated twice (and match HEAD at the end instead\nof the commit before the rebase started), against expectation.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n    pull: avoid running both merge and rebase\n    \n    Cc: Norbert Kiesel nkiesel@gmail.com [nkiesel@gmail.com], Jeff King \n    peff@peff.net [peff@peff.net]\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-739%2Fnewren%2Favoid-merge-and-rebase-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-739/newren/avoid-merge-and-rebase-v1\nPull-Request: https://github.com/git/git/pull/739\n\n builtin/pull.c | 5 ++++-\n 1 file changed, 4 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex 3e624d1e008..19899b45c1d 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -976,6 +976,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \n \tif (opt_rebase) {\n \t\tint ret = 0;\n+\t\tint ran_ff = 0;\n \t\tif ((recurse_submodules == RECURSE_SUBMODULES_ON ||\n \t\t     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&\n \t\t    submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))\n@@ -992,10 +993,12 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\t\tif (is_descendant_of(merge_head, list)) {\n \t\t\t\t/* we can fast-forward this without invoking rebase */\n \t\t\t\topt_ff = \"--ff-only\";\n+\t\t\t\tran_ff = 1;\n \t\t\t\tret = run_merge();\n \t\t\t}\n \t\t}\n-\t\tret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n+\t\tif (!ran_ff)\n+\t\t\tret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n \n \t\tif (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||\n \t\t\t     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))\n\nbase-commit: 274b9cc25322d9ee79aa8e6d4e86f0ffe5ced925\n-- \ngitgitgadget\n"},{"id":"394211","messageId":"xmqqy2rlcssn.fsf@gitster.c.googlers.com","threadId":"53117","inReplyTo":"pull.739.git.git.1585345900763.gitgitgadget@gmail.com","subject":"Re: [PATCH] pull: avoid running both merge and rebase","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-03-27T22:54:48Z","receivedAt":"2020-03-27T22:54:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Elijah Newren via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Elijah Newren <newren@gmail.com>\n>\n> When opt_rebase is true, we still first check if we can fast-forward.\n> If the branch is fast-forwardable, then we can avoid the rebase and just\n> use merge to do the fast-forward logic.  However, when commit a6d7eb2c7a\n> (\"pull: optionally rebase submodules (remote submodule changes only)\",\n> 2017-06-23) added the ability to rebase submodules it accidentally\n> caused us to run BOTH a merge and a rebase.  Add a flag to avoid doing\n> both.\n\nThis is a fun one.  Thanks for digging to the bottom of the issue.\n\n> diff --git a/builtin/pull.c b/builtin/pull.c\n> index 3e624d1e008..19899b45c1d 100644\n> --- a/builtin/pull.c\n> +++ b/builtin/pull.c\n> @@ -976,6 +976,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>  \n>  \tif (opt_rebase) {\n>  \t\tint ret = 0;\n> +\t\tint ran_ff = 0;\n>  \t\tif ((recurse_submodules == RECURSE_SUBMODULES_ON ||\n>  \t\t     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&\n>  \t\t    submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))\n> @@ -992,10 +993,12 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>  \t\t\tif (is_descendant_of(merge_head, list)) {\n>  \t\t\t\t/* we can fast-forward this without invoking rebase */\n>  \t\t\t\topt_ff = \"--ff-only\";\n> +\t\t\t\tran_ff = 1;\n>  \t\t\t\tret = run_merge();\n>  \t\t\t}\n>  \t\t}\n> -\t\tret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n> +\t\tif (!ran_ff)\n> +\t\t\tret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n>  \n>  \t\tif (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||\n>  \t\t\t     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))\n>\n> base-commit: 274b9cc25322d9ee79aa8e6d4e86f0ffe5ced925\n"},{"id":"394237","messageId":"20200328155627.GB1215566@coredump.intra.peff.net","threadId":"53117","inReplyTo":"pull.739.git.git.1585345900763.gitgitgadget@gmail.com","subject":"Re: [PATCH] pull: avoid running both merge and rebase","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2020-03-28T15:56:27Z","receivedAt":"2020-03-28T15:56:35Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Mar 27, 2020 at 09:51:40PM +0000, Elijah Newren via GitGitGadget wrote:\n\n> When opt_rebase is true, we still first check if we can fast-forward.\n> If the branch is fast-forwardable, then we can avoid the rebase and just\n> use merge to do the fast-forward logic.  However, when commit a6d7eb2c7a\n> (\"pull: optionally rebase submodules (remote submodule changes only)\",\n> 2017-06-23) added the ability to rebase submodules it accidentally\n> caused us to run BOTH a merge and a rebase.  Add a flag to avoid doing\n> both.\n> \n> This was found when a user had both pull.rebase and rebase.autosquash\n> set to true.  In such a case, the running of both merge and rebase would\n> cause ORIG_HEAD to be updated twice (and match HEAD at the end instead\n> of the commit before the rebase started), against expectation.\n> \n> Signed-off-by: Elijah Newren <newren@gmail.com>\n> ---\n>     pull: avoid running both merge and rebase\n>     \n>     Cc: Norbert Kiesel nkiesel@gmail.com [nkiesel@gmail.com], Jeff King \n>     peff@peff.net [peff@peff.net]\n\nI'm not sure how cc is supposed to work with GGG, but it clearly didn't\nhere. :)\n\nAnyway, the patch looks good. Thanks for following through on this.\n\n> @@ -992,10 +993,12 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n>  \t\t\tif (is_descendant_of(merge_head, list)) {\n>  \t\t\t\t/* we can fast-forward this without invoking rebase */\n>  \t\t\t\topt_ff = \"--ff-only\";\n> +\t\t\t\tran_ff = 1;\n>  \t\t\t\tret = run_merge();\n>  \t\t\t}\n>  \t\t}\n> -\t\tret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n> +\t\tif (!ran_ff)\n> +\t\t\tret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n\nIt feels like there should be some arrangement of the conditionals that\ndoesn't require setting an extra flag, but I actually don't think there\nis. And anyway, doing the most obvious and minimal fix here is the right\nplace to start. We don't need more regressions. ;)\n\n-Peff\n"},{"id":"394239","messageId":"afb593c8-ba46-fe8f-8853-d0b727186af0@gmail.com","threadId":"53117","inReplyTo":"20200328155627.GB1215566@coredump.intra.peff.net","subject":"Re: [PATCH] pull: avoid running both merge and rebase","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2020-03-28T16:55:26Z","receivedAt":"2020-03-28T16:55:31Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 3/28/2020 11:56 AM, Jeff King wrote:\n> On Fri, Mar 27, 2020 at 09:51:40PM +0000, Elijah Newren via GitGitGadget wrote:\n> \n>> When opt_rebase is true, we still first check if we can fast-forward.\n>> If the branch is fast-forwardable, then we can avoid the rebase and just\n>> use merge to do the fast-forward logic.  However, when commit a6d7eb2c7a\n>> (\"pull: optionally rebase submodules (remote submodule changes only)\",\n>> 2017-06-23) added the ability to rebase submodules it accidentally\n>> caused us to run BOTH a merge and a rebase.  Add a flag to avoid doing\n>> both.\n>>\n>> This was found when a user had both pull.rebase and rebase.autosquash\n>> set to true.  In such a case, the running of both merge and rebase would\n>> cause ORIG_HEAD to be updated twice (and match HEAD at the end instead\n>> of the commit before the rebase started), against expectation.\n>>\n>> Signed-off-by: Elijah Newren <newren@gmail.com>\n>> ---\n>>     pull: avoid running both merge and rebase\n>>     \n>>     Cc: Norbert Kiesel nkiesel@gmail.com [nkiesel@gmail.com], Jeff King \n>>     peff@peff.net [peff@peff.net]\n> \n> I'm not sure how cc is supposed to work with GGG, but it clearly didn't\n> here. :)\n\nAngle brackets would work instead of square brackets:\n\n\tCc: Norbert Keisel <nkiesel@gmail.com>\n\nfor example. Personally, I drop the names and only use email addresses\nso I don't make this same mistake.\n\n-Stolee\n"},{"id":"394243","messageId":"CABPp-BHLtyCR_2KC6M=GaiJTOAR90wHTLAM4twEq_p4JaKrm3g@mail.gmail.com","threadId":"53117","inReplyTo":"afb593c8-ba46-fe8f-8853-d0b727186af0@gmail.com","subject":"Re: [PATCH] pull: avoid running both merge and rebase","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-03-28T17:17:31Z","receivedAt":"2020-03-28T17:17:46Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Sat, Mar 28, 2020 at 9:55 AM Derrick Stolee <stolee@gmail.com> wrote:\n>\n> On 3/28/2020 11:56 AM, Jeff King wrote:\n> > On Fri, Mar 27, 2020 at 09:51:40PM +0000, Elijah Newren via GitGitGadget wrote:\n> >\n> >> When opt_rebase is true, we still first check if we can fast-forward.\n> >> If the branch is fast-forwardable, then we can avoid the rebase and just\n> >> use merge to do the fast-forward logic.  However, when commit a6d7eb2c7a\n> >> (\"pull: optionally rebase submodules (remote submodule changes only)\",\n> >> 2017-06-23) added the ability to rebase submodules it accidentally\n> >> caused us to run BOTH a merge and a rebase.  Add a flag to avoid doing\n> >> both.\n> >>\n> >> This was found when a user had both pull.rebase and rebase.autosquash\n> >> set to true.  In such a case, the running of both merge and rebase would\n> >> cause ORIG_HEAD to be updated twice (and match HEAD at the end instead\n> >> of the commit before the rebase started), against expectation.\n> >>\n> >> Signed-off-by: Elijah Newren <newren@gmail.com>\n> >> ---\n> >>     pull: avoid running both merge and rebase\n> >>\n> >>     Cc: Norbert Kiesel nkiesel@gmail.com [nkiesel@gmail.com], Jeff King\n> >>     peff@peff.net [peff@peff.net]\n> >\n> > I'm not sure how cc is supposed to work with GGG, but it clearly didn't\n> > here. :)\n>\n> Angle brackets would work instead of square brackets:\n>\n>         Cc: Norbert Keisel <nkiesel@gmail.com>\n>\n> for example. Personally, I drop the names and only use email addresses\n> so I don't make this same mistake.\n\nMy original did have angle brackets; it was literally the following line:\n\nCc: Norbert Kiesel <nkiesel@gmail.com>, Jeff King <peff@peff.net>\n\nNot sure why it came through with duplicated email addresses with one\ninside of square brackets.  Maybe GitHub markup does something to the\nangle brackets, and GGG doesn't get the original text but the\nmarkdown-interpreted clobbering thereof?  Or something like that?\n"},{"id":"394244","messageId":"CABPp-BFgwcGjvwFsHzgf8bvR6dY2EocpUbn5-on5sdeRqkw1jw@mail.gmail.com","threadId":"53117","inReplyTo":"20200328155627.GB1215566@coredump.intra.peff.net","subject":"Re: [PATCH] pull: avoid running both merge and rebase","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-03-28T17:18:07Z","receivedAt":"2020-03-28T17:18:20Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Sat, Mar 28, 2020 at 8:56 AM Jeff King <peff@peff.net> wrote:\n>\n> On Fri, Mar 27, 2020 at 09:51:40PM +0000, Elijah Newren via GitGitGadget wrote:\n>\n> > When opt_rebase is true, we still first check if we can fast-forward.\n> > If the branch is fast-forwardable, then we can avoid the rebase and just\n> > use merge to do the fast-forward logic.  However, when commit a6d7eb2c7a\n> > (\"pull: optionally rebase submodules (remote submodule changes only)\",\n> > 2017-06-23) added the ability to rebase submodules it accidentally\n> > caused us to run BOTH a merge and a rebase.  Add a flag to avoid doing\n> > both.\n> >\n> > This was found when a user had both pull.rebase and rebase.autosquash\n> > set to true.  In such a case, the running of both merge and rebase would\n> > cause ORIG_HEAD to be updated twice (and match HEAD at the end instead\n> > of the commit before the rebase started), against expectation.\n> >\n> > Signed-off-by: Elijah Newren <newren@gmail.com>\n> > ---\n> >     pull: avoid running both merge and rebase\n> >\n> >     Cc: Norbert Kiesel nkiesel@gmail.com [nkiesel@gmail.com], Jeff King\n> >     peff@peff.net [peff@peff.net]\n>\n> I'm not sure how cc is supposed to work with GGG, but it clearly didn't\n> here. :)\n\nYeah, I clearly don't either.  I even looked up another submission\nfrom Dscho (https://github.com/git/git/pull/728) and attempted to\nmimic it, but still managed to get it wrong somehow and I don't know\nhow.\n\n> Anyway, the patch looks good. Thanks for following through on this.\n>\n> > @@ -992,10 +993,12 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n> >                       if (is_descendant_of(merge_head, list)) {\n> >                               /* we can fast-forward this without invoking rebase */\n> >                               opt_ff = \"--ff-only\";\n> > +                             ran_ff = 1;\n> >                               ret = run_merge();\n> >                       }\n> >               }\n> > -             ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n> > +             if (!ran_ff)\n> > +                     ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n>\n> It feels like there should be some arrangement of the conditionals that\n> doesn't require setting an extra flag, but I actually don't think there\n> is. And anyway, doing the most obvious and minimal fix here is the right\n> place to start. We don't need more regressions. ;)\n\nThanks for reviewing it.\n"},{"id":"394774","messageId":"nycvar.QRO.7.76.6.2004041546290.46@tvgsbejvaqbjf.bet","threadId":"53117","inReplyTo":"CABPp-BFgwcGjvwFsHzgf8bvR6dY2EocpUbn5-on5sdeRqkw1jw@mail.gmail.com","subject":"GGG Cc: bug, was Re: [PATCH] pull: avoid running both merge and rebase","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-04-04T13:47:58Z","receivedAt":"2020-04-04T13:48:04Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Elijah,\n\nOn Sat, 28 Mar 2020, Elijah Newren wrote:\n\n> On Sat, Mar 28, 2020 at 8:56 AM Jeff King <peff@peff.net> wrote:\n> >\n> > On Fri, Mar 27, 2020 at 09:51:40PM +0000, Elijah Newren via GitGitGadget wrote:\n> >\n> > > When opt_rebase is true, we still first check if we can fast-forward.\n> > > If the branch is fast-forwardable, then we can avoid the rebase and just\n> > > use merge to do the fast-forward logic.  However, when commit a6d7eb2c7a\n> > > (\"pull: optionally rebase submodules (remote submodule changes only)\",\n> > > 2017-06-23) added the ability to rebase submodules it accidentally\n> > > caused us to run BOTH a merge and a rebase.  Add a flag to avoid doing\n> > > both.\n> > >\n> > > This was found when a user had both pull.rebase and rebase.autosquash\n> > > set to true.  In such a case, the running of both merge and rebase would\n> > > cause ORIG_HEAD to be updated twice (and match HEAD at the end instead\n> > > of the commit before the rebase started), against expectation.\n> > >\n> > > Signed-off-by: Elijah Newren <newren@gmail.com>\n> > > ---\n> > >     pull: avoid running both merge and rebase\n> > >\n> > >     Cc: Norbert Kiesel nkiesel@gmail.com [nkiesel@gmail.com], Jeff King\n> > >     peff@peff.net [peff@peff.net]\n> >\n> > I'm not sure how cc is supposed to work with GGG, but it clearly didn't\n> > here. :)\n>\n> Yeah, I clearly don't either.  I even looked up another submission\n> from Dscho (https://github.com/git/git/pull/728) and attempted to\n> mimic it, but still managed to get it wrong somehow and I don't know\n> how.\n\nIt might be a bug in the way I implemented folding the cover letter into\nsingle-patch mails. I simply might not pick up the Cc:s there.\n\nHowever, I am seriously under water right now and won't be able to work on\na fix for that. Would you mind opening a ticket at\nhttps://github.com/gitgitgadget/gitgitgadget/issues/new?\n\nThanks,\nDscho\n\n>\n> > Anyway, the patch looks good. Thanks for following through on this.\n> >\n> > > @@ -992,10 +993,12 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n> > >                       if (is_descendant_of(merge_head, list)) {\n> > >                               /* we can fast-forward this without invoking rebase */\n> > >                               opt_ff = \"--ff-only\";\n> > > +                             ran_ff = 1;\n> > >                               ret = run_merge();\n> > >                       }\n> > >               }\n> > > -             ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n> > > +             if (!ran_ff)\n> > > +                     ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);\n> >\n> > It feels like there should be some arrangement of the conditionals that\n> > doesn't require setting an extra flag, but I actually don't think there\n> > is. And anyway, doing the most obvious and minimal fix here is the right\n> > place to start. We don't need more regressions. ;)\n>\n> Thanks for reviewing it.\n>\n"}]}