Message ID | 3d9ff69198e5a604b124bf861df4d6ecf6eb661e.1626536508.git.gitgitgadget@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Handle pull option precedence | expand |
Elijah Newren via GitGitGadget wrote: > From: Elijah Newren <newren@gmail.com> > > Now that the handling of fast-forward-only in combination with rebases > has been moved before the merge-vs-rebase logic, we have an unnecessary > special fast-forward case left within the rebase logic. Actually, more > than unnecessary, it's actually a violation of the rules. As per > https://lore.kernel.org/git/xmqqwnpqot4m.fsf@gitster.g/, --rebase is > supposed to override all ff flags other than an explicit --ff-only. > Ensure that it does so by removing the fast-forward special case that > exists within the rebase logic. What Junio said in one mail are not the rules. This goes against what is described in the documentation.
"Elijah Newren via GitGitGadget" <gitgitgadget@gmail.com> writes: > From: Elijah Newren <newren@gmail.com> > > Now that the handling of fast-forward-only in combination with rebases > has been moved before the merge-vs-rebase logic, we have an unnecessary > special fast-forward case left within the rebase logic. It is correct to say that we could call run_rebase() and it will do the right thing, even when can_ff is true, in this codepath. But I am not sure if you want to do this as a part of this series. The code in question comes from 33b842a1 (pull: fast-forward "pull --rebase=true", 2016-06-29). It was meant as a mere optimization to avoid calling run_rebase() when we know we have nothing to replay on top of their head after we fast-forward, and doing a pure fast-forward is easier by calling run_merge(). In other words, the code this patch touches should not have anything to do with the rebase-vs-fast-forward logic. Now, if a benchmarking tells us that there is no difference between calling an empty run_rebase() and run_merge(), I'd be perfectly fine with this change, with the justification that we are "discarding an earlier optimization that has become irrelevant". But that would be totally outside the theme of this topic, I would think. Thanks. > @@ -1070,13 +1070,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix) > submodule_touches_in_range(the_repository, &upstream, &curr_head)) > die(_("cannot rebase with locally recorded submodule modifications")); > > - if (can_ff) { > - /* we can fast-forward this without invoking rebase */ > - opt_ff = "--ff-only"; > - ret = run_merge(); > - } else { > - ret = run_rebase(&newbase, &upstream); > - } > + ret = run_rebase(&newbase, &upstream); > > if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON || > recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)) > diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh > index e2c0c510222..4b50488141f 100755 > --- a/t/t5520-pull.sh > +++ b/t/t5520-pull.sh > @@ -295,7 +295,7 @@ test_expect_success '--rebase (merge) fast forward' ' > # The above only validates the result. Did we actually bypass rebase? > git reflog -1 >reflog.actual && > sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy && > - echo "OBJID HEAD@{0}: pull --rebase . ff: Fast-forward" >reflog.expected && > + echo "OBJID HEAD@{0}: pull --rebase . ff (finish): returning to refs/heads/to-rebase" >reflog.expected && > test_cmp reflog.expected reflog.fuzzy > ' > > @@ -307,8 +307,8 @@ test_expect_success '--rebase (am) fast forward' ' > > # The above only validates the result. Did we actually bypass rebase? > git reflog -1 >reflog.actual && > - sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy && > - echo "OBJID HEAD@{0}: pull --rebase . ff: Fast-forward" >reflog.expected && > + sed -e "s/^[0-9a-f][0-9a-f]*/OBJID/" -e "s/[0-9a-f][0-9a-f]*$/OBJID/" reflog.actual >reflog.fuzzy && > + echo "OBJID HEAD@{0}: rebase finished: refs/heads/to-rebase onto OBJID" >reflog.expected && > test_cmp reflog.expected reflog.fuzzy > '
On Tue, Jul 20, 2021 at 4:35 PM Junio C Hamano <gitster@pobox.com> wrote: > > "Elijah Newren via GitGitGadget" <gitgitgadget@gmail.com> writes: > > > From: Elijah Newren <newren@gmail.com> > > > > Now that the handling of fast-forward-only in combination with rebases > > has been moved before the merge-vs-rebase logic, we have an unnecessary > > special fast-forward case left within the rebase logic. > > It is correct to say that we could call run_rebase() and it will do > the right thing, even when can_ff is true, in this codepath. > > But I am not sure if you want to do this as a part of this series. It turns out my commit message was wrong, and so was the patch. My changes did have a functional change, substituting one form of submodule breakage with another. I'll replace this with a patch that fixes the submodule issue. (When --ff-only is specified, we should not rebase submodules. We should fast-forward both the parent module and the submodules.)
diff --git a/builtin/pull.c b/builtin/pull.c index 5c9cbea37c9..5ba376a7487 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -1070,13 +1070,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix) submodule_touches_in_range(the_repository, &upstream, &curr_head)) die(_("cannot rebase with locally recorded submodule modifications")); - if (can_ff) { - /* we can fast-forward this without invoking rebase */ - opt_ff = "--ff-only"; - ret = run_merge(); - } else { - ret = run_rebase(&newbase, &upstream); - } + ret = run_rebase(&newbase, &upstream); if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON || recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)) diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index e2c0c510222..4b50488141f 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -295,7 +295,7 @@ test_expect_success '--rebase (merge) fast forward' ' # The above only validates the result. Did we actually bypass rebase? git reflog -1 >reflog.actual && sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy && - echo "OBJID HEAD@{0}: pull --rebase . ff: Fast-forward" >reflog.expected && + echo "OBJID HEAD@{0}: pull --rebase . ff (finish): returning to refs/heads/to-rebase" >reflog.expected && test_cmp reflog.expected reflog.fuzzy ' @@ -307,8 +307,8 @@ test_expect_success '--rebase (am) fast forward' ' # The above only validates the result. Did we actually bypass rebase? git reflog -1 >reflog.actual && - sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy && - echo "OBJID HEAD@{0}: pull --rebase . ff: Fast-forward" >reflog.expected && + sed -e "s/^[0-9a-f][0-9a-f]*/OBJID/" -e "s/[0-9a-f][0-9a-f]*$/OBJID/" reflog.actual >reflog.fuzzy && + echo "OBJID HEAD@{0}: rebase finished: refs/heads/to-rebase onto OBJID" >reflog.expected && test_cmp reflog.expected reflog.fuzzy '