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:
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?
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 withstash
is nonsensical but I happen to have one in this repo and I'm not actually merging here):(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.