Why does git merge sometimes create a commit, sometimes does not?

Git

Git Problem Overview


When I do git merge from another branch to current workspace, git sometimes makes a new commit:

Merge remote-tracking branch xxx into xxx

Sometimes, it does not:

Fast-forward
... src files ...

So what determines whether a commit should be created or not?

Git Solutions


Solution 1 - Git

So-called "Fast-forward" merges don't produce a commit, whereas other merges (often refered to as "octopus merge" (now you see why github's mascott is an octocat)) produce commits.

Basically, a Fast-forward happens when your branches did not diverge.

Say you want to merge a branch foo in the master branch. If these branches did not diverge, you would have an history like this (each * represents a commit):

*---* (master)
     \
      *---*---* (foo)

In this situation, the merge is fast-forward because (according to the graph theory, which is the underlying foundation of a git graph), master is reachable from foo. In other words, you just have to move the master reference to foo, and you're done:

*---*
     \
      *---*---* (master, foo)

When your branches diverge:

*---*---* (master)
     \
      *---*---* (foo)

You have to create a commit to "join" the two branches:

                ↓
*---*---*-------* (master)
     \         / 
      *---*---* (foo)

The commit pointed by the arrow is the merge commit and has two parent commits (the former master branch tip, and the current foo branch tip).

Note that you can force Git to create a merge commit for a fast-forward merge with the --no-ff option.

I highly recommend reading http://think-like-a-git.net/ for a good understanding of how the graph theory applies to git (you don't need to know the graph theory, everything you need to know is on the website), which will make working with Git incredibly easier :)

Solution 2 - Git

You can use the --no-ff option to force a new commit to avoid the fast-forward.

Solution 3 - Git

A fast forward means that a commit has already happened and is stored in your log, and your HEAD (pointer) has moved forward to that commit. You can check out merge behavior here

Solution 4 - Git

When no fast-forward --no-ff option is presented git will not create a commit if the head of the branch you are merging in is the ancestor of the merged branch. In this case (no --no-ff option) it will just move the head (it's a fast-forward).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser972946View Question on Stackoverflow
Solution 1 - GitGeoffrey BacheletView Answer on Stackoverflow
Solution 2 - Gituser3021843View Answer on Stackoverflow
Solution 3 - GithyleausView Answer on Stackoverflow
Solution 4 - GitAlexey KozhevnikovView Answer on Stackoverflow