Tuesday, May 8, 2012

Why you should use git merge --no-ff when rebasing.

When working with Git my normal workflow was to create my feature/bugfix in a branch. When I'm ready to integrate it, I rebase the branch and merge it into master. This ensures that the master branch has a linear history.

This gives you a clean history which is easy to bisect.
An example of linear history
However, when reading the help for git merge I came across the --no-ff parameter. It says:
Create a merge commit even when the merge resolves as a fast-forward.
I decided to use it for my 0.2 version of my software. This created the following graph in gitk:
Branche rebased and merged with git merge --no-ff
This code was first rebased, then merged with git merge --no-ff. An explicit merge commit is now created (where the tag 0.2 points to). Because the branch was already rebased, this merge commit does not contain a diff - it only exists to merge the two branches together.

This gives you several advantages on top of the advantages you have using git rebase:
  1. You can see the name of the branch you merged back into master.
    The name is part of the commit message of the merge commit.
  2. In the graph you can easily see what commits were part of the branch. 
    This comes in handy when you later want to see what individual commits were needed to create a specific feature branch.
  3. You are now able to revert the entire branch by reverting the merge commit with git revert.
    Beware that the git revert commit command needs to know that you are reverting a merge. In the example above I would revert it with 'git revert -m 1 0.2'. See the git man page for details.
Enough advantages for me to keep on using the rebase workflow but to merge it with an explicit merge commit.