Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I squash merge when merge.ff = only?

Tags:

git

merge

To start with, I have my merge.ff setting to only, as in:

git config --global merge.ff only

I have it like this because I don't want git to do non-fast-forward merges without checking with me first. This acts as a nice safeguard to make sure I get the opportunity to do something other than create an extraneous merge commit. When I do need to do a non-fast-forward merge, I can tell git to override my default setting:

git merge --no-ff

Now consider a git repository with a history like this:

single diverging branch

Let's say for some reason I want to squash merge the work branch onto master. (In a case this simple, I could just rebase, of course, but suppose I had some other reason to squash instead.) You normally do a squash merge with the --squash argument:

git checkout master
git merge --squash work

But in this instance, it results in an error message:

fatal: Not possible to fast-forward, aborting.

This kind of makes sense. A fast-forward merge isn't possible because both branches have commits that are not in common. But this is also okay: I want to do a merge anyway. The obvious solution is to use --no-ff like I normally would to tell git that this is okay and it should proceed anyway:

git merge --squash --no-ff work

But this also gives an error:

fatal: You cannot combine --squash with --no-ff.

So how do I get git to squash merge without changing my configuration?

like image 938
jpmc26 Avatar asked Apr 07 '16 20:04

jpmc26


1 Answers

Answer

Use git -c merge.ff merge --squash <args>.

Discussion

Squash "merges" are not really merges at all (and in fact, neither are fast-forward merges), so it seems like a bug that git rejects them with the config setting.

That said, though, you could temporarily override your merge.ff=only setting. Experimentation shows that this works (aside, merging with stash is nonsensical but I happen to have one in this repo and I'm not actually merging here):

$ git config --global merge.ff=only
$ git merge --squash stash
fatal: Not possible to fast-forward, aborting.
$ git -c merge.ff=false merge --squash stash
fatal: You cannot combine --squash with --no-ff.
$ git -c merge.ff=true merge --squash stash
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested

(at which point I just use git reset --hard to undo the fake merge).

Since -c defaults to =true, we get the answer at the top.

like image 194
torek Avatar answered Sep 28 '22 07:09

torek