21

I have many short-lived branches in my workflow and I would like them to be separated. So, I plan to use git config --add merge.ff false. However, when I am doing a pull (which I understand is fetch+merge) - then I want a fast-forward behavior, to avoid unnecessary extra commit here.

Is this a good thing to do? Is this possible?

Елин Й.
  • 953
  • 10
  • 25
Vikash
  • 989
  • 2
  • 9
  • 28
  • Note: `git config push.ff only` will help in Git 2.0. See [my edited answer below](http://stackoverflow.com/a/12798995/6309) – VonC Mar 12 '14 at 14:21
  • @VonC I think you meant `pull.ff` instead of `push.ff`. Also appears once in your answer edit. – Kelvin Apr 02 '15 at 18:23
  • I understand that this is not the same, but I believe `git pull --rebase` can solve your problem. – Nick Roz Nov 14 '16 at 15:34

1 Answers1

26

Note: Git 2.0 (Q2 2014) will introduce with commit b814da8 a config push.ff:

pull.ff::

By default, Git does not create an extra merge commit when merging a commit that is a descendant of the current commit. Instead, the tip of the current branch is fast-forwarded.

  • When set to false, this variable tells Git to create an extra merge commit in such a case (equivalent to giving the --no-ff option from the command line).
  • When set to only, only such fast-forward merges are allowed (equivalent to giving the --ff-only option from the command line).

Initial answer (October 2012)

Try a:

git pull --ff

It should take precedence on your merge config setting.
It will pass the --ff option to the underlying merge within the git pull command.

Beware of the --no-ff option though, as mentioned in "Understanding the Git Workflow"

With enough flags you can force Git to act the way you think it should instead of the way it wants to. But that’s like using a screwdriver like a hammer; it gets the job done, but it’s done poorly, takes longer, and damages the screwdriver.

Consider how a common Git workflow falls apart.

Create a branch off Master, 
do work, 
and merge it back into Master when you’re done

Most of the time this behaves as you expect because Master changed since you branched. Then one day you merge a feature branch into Master, but Master hasn’t diverged. Instead of creating a merge commit, Git points Master to the latest commit on the feature branch, or “fast forwards.” (Diagram)

Unfortunately, your feature branch contained checkpoint commits, frequent commits that back up your work but captures the code in an unstable state. Now these commits are indistinguishable from Master’s stable commits. You could easily roll back into a disaster.

So you add a new rule: “When you merge in your feature branch, use –no-ff to force a new commit.” This gets the job done, and you move on.

Then one day you discover a critical bug in production, and you need to track down when it was introduced. You run bisect but keep landing on checkpoint commits. You give up and investigate by hand.

You narrow the bug to a single file. You run blame to see how it changed in the last 48 hours. You know it’s impossible, but blame reports the file hasn’t been touched in weeks.
It turns out blame reports changes for the time of the initial commit, not when merged. Your first checkpoint commit modified this file weeks ago, but the change was merged in today.

The no-ff band-aid, broken bisect, and blame mysteries are all symptoms that you’re using a screwdriver as a hammer.

For more, see:

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 3
    I don't really see how the quote justifies why `--no-ff` is bad. If the merge was a FF, you'd still be confronted with the same mystery of when the merge actually happened (it's even more mysterious because there's no record whatsoever). If you used `--no-ff`, you could combine `blame` and `git log --graph --ancestry-path` to figure out when the code got into the branch. – Kelvin Apr 02 '15 at 18:33
  • 2
    @Kelvin True. Other good reads on ff: http://stackoverflow.com/a/29319178/6309 and http://git-blame.blogspot.fr/2015/03/fun-with-non-fast-forward.html. – VonC Apr 02 '15 at 18:58