On 15 May 2018 at 00:58, Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> wrote: > > On Mon, May 14 2018, demerphq wrote: > >> The first time I tried to use --no-ff I tried to do something like this: >> >> git checkout master >> git commit -a -m'whatever' >> git commit -a -m'whatever2' >> git merge --no-ff origin/master >> >> and was disappointed when "it didn't work" and git told me there was >> nothing to do as the branch was up to date. (Which I found a bit >> confusing.) >> >> I realize now my expectations were incorrect, and that the argument to >> merge needs to resolve to a commit that is ahead of the current >> commit, and in the above sequence it is the other way around. So to do >> what I want I can do: >> >> git checkout master >> git checkout -b topic >> git commit -a -m'whatever' >> git commit -a -m'whatever2' >> git checkout master >> git merge --no-ff topic >> >> and iiuir this works because 'master' would be behind 'topic' in this case. >> >> But I have a few questions, 1) is there is an argument to feed to git >> merge to make the first recipe work like the second? And 2) is this >> asymmetry necessary with --no-ff? > > I've been bitten my this myself, but found that it's documented as the > very first thing in git-merge: > > Incorporates changes from the named commits (since the time their > histories diverged from the current branch) into the current > branch[...]. > > Since origin/master hasn't diverged from your current branch (unlike the > other way around), the merge with --no-ff is a noop. Yeah, I got it, but only after rereading a lot of times. > >> More specifically would something horrible break if --no-ff >> origin/trunk detected that the current branch was ahead of the named >> branch and "swapped" the implicit order of the two so that the first >> recipe could behave like the second > > If it worked like that then the user who sets merge.ff=false in his > config and issues a "git pull" after making a commit on his local master > would create a merge commit. > > This old E-Mail of Junio's discusses that edge case & others in detail: > https://public-inbox.org/git/7vty1zfwmd.fsf@xxxxxxxxxxxxxxxxxxxxxxxx/ Thanks I skimmed, but it is long so I will review later. I see the point about the config option for no-ff. But what about an option like --reverse? Assuming we are on a local branch master then git merge --no-ff --reverse origin/master would treat origin/master as the "current" branch, and "master" as the merged in branch, and create the appropriate merge commit. Which as far as I can tell is tree-wise identical to creating a topic branch instead of hacking on the local master. >> Anyway, even if the above makes no sense, would it be hard to make the >> message provided by git merge in the first recipe a bit more >> suggestive of what is going on? For instance if it had said "Cannot >> --no-ff merge, origin/master is behind master" it would have been much >> more clear what was going on. > > I can't spot any reason for why we couldn't have something like this POC > (would be properly done through advice.c): > > diff --git a/builtin/merge.c b/builtin/merge.c > index 9db5a2cf16..920f67d9f8 100644 > --- a/builtin/merge.c > +++ b/builtin/merge.c > @@ -1407,6 +1407,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix) > * but first the most common case of merging one remote. > */ > finish_up_to_date(_("Already up to date.")); > + if (fast_forward == FF_NO) > + fprintf(stderr, "did you mean this the other way around?\n"); > goto done; > } else if (fast_forward != FF_NO && !remoteheads->next && > !common->next && > > But that should probably be reworked to be smart about whether --no-ff > or merge.ff=false was specified, i.e. do we want to yell this at the > user who's just set that at his config default, or the user who's > specified --no-ff explicitly, or both? I don't know. Yes, all those points make sense. Yves -- perl -Mre=debug -e "/just|another|perl|hacker/"