Can I make fast forwarding be off by default in git?
Solution 1
Yes, there is --no-ff
. You can configure merge options per branch, e.g.
git config branch.master.mergeoptions "--no-ff"
adds the following to your $(REPO)/.git/config
file:
[branch "master"]
mergeoptions = --no-ff
Footnote: speaking of my experience, I eventually found switching fast-forward to off was mostly helpful for git newcomers - however once the feel for workflows and concepts start to sink in you definitely want to avoid blurring your log graph with tons of pointless 'merged remote ..blarf' type commits.
Footnote 2, a decade later: the other answers below provide more modern config options, but really, you probably DO want to stay with the defaults (i.e. fast-forward whenever possible) in this day and age, because empty merge-commits really only make the history much more difficult to reason about.
Solution 2
It seems there is still a pending question in the thread: How to do it globally (i.e. for all branches) ? For the records, we can use the following:
git config --add merge.ff false
...to make it apply to all branches in the current repository. To make it apply to all branches in all repositories where someone has not run it without the --global
option (local settings override global) run this:
git config --global --add merge.ff false
From the documentation:
merge.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).
Solution 3
Reading the thread of answers I ended up using the following two options
git config --global pull.ff only # Disallows non ff merges on pull. Overrides merge.ff when pulling
git config --global merge.ff false # even create extra merge commit when fast forward merge would be possible
Only loosely related I've also found this setting avoids trouble during pull
git config --global pull.rebase true # set up pull to rebase instead of merge
Related videos on Youtube
Comments
-
Jason Baker over 3 years
I can't really ever think of a time when I would use
git merge
rather thangit rebase
and not want to have a commit show up. Is there any way to configure git to have fast forwarding off by default? The fact that there's an--ff
option would seem to imply that there's a way, but I can't seem to find it in the documentation.-
CB Bailey about 14 yearsI use
merge
all the time for branches when haven't made any commits off their remote in order to fast-forward them. It seems the simplest and safest way to do this. I'm curious, you obviously have a use case. Why would you ever want to create a merge commit where there are no commits on one side of the branch? -
Jason Baker about 14 yearsI use branches to create a logical grouping of commits. So if I make a merge, it's basically a way to say "these commits go together". You can almost think of it as a poor man's interactive rebase and squash. :-)
-
steinybot over 11 yearsTurning off fast forwarding is extremely useful, particularly when following a model like A successful Git branching model
-
rjmunro over 8 yearsPlease change the accepted answer for this to Eric Platon's answer stackoverflow.com/a/6810687/3408 - I did the steps in the accepted answer, then realised that it was only for the master branch in the current repository, which is silly.
-
jpmc26 about 8 years@Steiny No, it just makes your repository a mess: endoflineblog.com/gitflow-considered-harmful.
-
steinybot about 8 years@jpmc26 Each to their own I guess. I happen to disagree with that article. Finding the two parents of a merge commit is not hard and tells you exactly what the changes were. Then you can take those changes and do a "rebase onto" some other branch. With the flat model you have to manually find and cherry pick. We choose to embrace branching. Sure it is complex when looking at the entire tree but that is the reality, multiple changes occurring in parallel. Flattening everything just hides what really happened.
-
jpmc26 about 8 years@Steiny Yes, it does hide "what really happened." And that's a good thing. It cuts out irrelevant details no one needs to care about and preserves the ones that are important; that's what good documentation does. Finding the parent of a single merge is not hard, true. Tracing back across 100 commits over 4 branches with a lot of criss crossing trying to figure out what actually changed and where does not seem especially easy, especially when those commits may or may not actually introduce changes to the code base. (This is what Gitflow recommends/requires.)
-
Brian Ogden over 6 years@jpmc26 You are making claims that are very strong and biased, you literally said "No, it just makes your repository a mess" regarding this article nvie.com/posts/a-successful-git-branching-model, while this Git workflow might not work for you, it works for some enterprise teams
-
Suma over 5 yearsI understand git config changes the settings per user. Is there a way to disable fast forwarding for the repository (for all users), creating a kind of "repository merge policy"?
-
Steve Summit about 2 yearsI think the comments (and the referenced blog post) about the way a non-fast-forward merge "makes your repository a mess" are missing the point. That "mess" is not the result of a complicated merge structure — it's the result of the lack of good tools for visualizing a complicated merge structure. A fast-forward merge "removes" the mess — but in doing so, it erases history, creating a sanitized version which can, yes, be more easily viewed using a meager one-dimensional log viewer.
-
-
conny about 14 yearsLearning git is a bit like mountain climbing; but instead of starting with small cliffs and progressing to tougher ones, git makes you climb the same mountain again and again, only to fall at different heights each time, every time just as surprised that the lifeline wasn't attached.
-
Tom Mayfield almost 14 yearsDoes this affect "git pull" and its merge strategy at all?
-
Michelle Tilley over 13 years@Thomas: Yes;
git pull
isgit fetch
+git merge
. -
Tony R about 13 yearsThis looks good, but is there any way to do it globally, for all branches, instead of having to set it up for every branch?
-
Chris Johnsen almost 13 yearsNote:
merge.ff
was introduced in Git 1.7.6. It is not effective in older versions. -
andriy over 12 yearsFor people using Git 1.7.6, this is the best and simplest solution.
-
Dalibor Filus over 12 yearsBeware of the dragons. This option is dangerous just as @Thomas said... Every git pull creates merge commit. git pull --ff doesn't override the mergeoptions=no-ff in git config.
-
stigi almost 12 yearsI'm using this together with an alias
puff = "pull --ff --ff-only"
-
Bob Kerns over 11 yearsRegarding the footnote -- instead of 1 "pointless" "merged branch fiddle-around" commits -- we get the entire "fiddle-around" series of commits merged onto our master. Often including a half-dozen merge commits. If you have the merge commits, you can ignore the detailed feature commits, and get the big overview, like this: $ git log --first-parent --pretty=oneline'feature-1'" c605cca334c722a34e3aea88c36a043ab3cca741 Merge branch 'feature-2' f93a46a24bd0761da0a1bd64b2da0549980979c8 Merge branch 'feature-1' 163602263b4f0a8463c6de82d3a7dd7b4c04ebca project inception
-
pedromanoel about 11 yearsI really like the alias option, since your pulls won't result in a merge commit always.
-
cregox over 10 years
-
jotomo over 9 yearsTheres is also (now, see git-scm.com/docs/git-config) the option pull.ff which can be set to only, which will do the same as the alias.
-
Eric Platon over 9 yearsThank you, @jotomo. That feature is available from Git v2.0.0 (from commit b814da891e8261b909fc5d9fb07b4e8b13989c2d).
-
Kadarach over 9 yearsWhat if I'm just tired of typing
git merge --no-ff (branchname)
? And I wantgit pull
to function as it always has? -
andriy almost 9 yearsYou probably wouldn't want to set this up for your master branch. Where it's most useful is small feature branches, where you'd like to be able to see all the commits on that feature branch as distinct from other commits.
-
rjmunro over 8 yearsIf you want a non-fast-forward merge, use rebase. A fast forward merge is really a rebase as rebase naturally doesn't add merge commits. Set git pull to use rebase using
git pull --rebase
or configure it withgit config --global pull.rebase true
-
rjmunro over 8 yearsYou could also use rebase for git pull, to prevent merge commits. Use
git pull --rebase
or configure it as default withgit config --global pull.rebase true
. If you have not made any commits, this works identically tomerge --ff
. If you have made some commits to the branch locally, but not pushed them, they will be added to the end of the branch, rather than merged in. This is usually what you want. -
Eric over 7 yearsThis helped a lot! I would like to add for those who are interested you can also set other subcommand options by simply replacing the
--no-ff
with any other subcommand. I recently found this setting to be very beneficial.git config branch.<branchName>.mergeoptions "--log"
To allow the--log
subcommand to track in the merge commit the subject of all the commits being merged into the specified branch. -
orzechow about 7 years@DaliborFilus Tame the dragons:
git config branch.autosetuprebase always
This enables fast-forward for the master branch when pulling, even withbranch.master.mergeoptions "--no-ff"
-
wayofthefuture over 6 yearsIs there a way to only make this apply when merging branches and not when doing a git pull?
-
Gendolph about 6 yearsSince Git 2.4.3 you can specify
pull.ff
(to true) config options to overridemergeOptions
forpull
command. -
Pylinux about 6 yearsFYI: This is just for the master branch, if you want for all branches you need @eric-platon's answer
-
zowers over 4 yearsgit config --global pull.rebase true # notice 'true' at the end of the line
-
bastian over 4 yearsThanks @zowers I've fixed this
-
Dennis Kassel almost 4 yearsSince nobody has mentioned this in the answer, I would like to add, that this option has side effects on how "git pull" works. I have experienced, that "git pull" will implicitly create a separate merge-commit, even though fast-forwarding the branch was possible.
-
bigbear3001 about 3 yearsFor it to work on our systems i needed
git config --global --bool merge.ff false
(git version 2.20.1) -
perepm about 3 yearsI believe that the peace of mind of knowing that you can undo any faulty merge with a simple
git reset HEAD~1
simply overtakes any inconvenience of always merging with a new commit. In fact, I'd mark (@eric-platon's)[stackoverflow.com/a/6810687/8699916] answer as correct. By doing what he says,pull
stays the same. -
mellow-yellow over 2 yearsYes! The top-ranked answer misses this. Also, Git Common Flow, arguably the de-facto standard, says, "It is RECOMMENDED that all branches be merged using
git merge --no-ff
" but when you're pulling, merge has already happened, so this seems the like best answer in 2021--at least to me.