You know what a merge does conceptually and how to merge in Git. What you may not know are the different types of merges. That’s what this piece is about.
This post is a slightly modified version of the Git merge section in Pro Git, which I would highly recommend reading. The Git merge section in Pro Git is licensed under the Creative Commons Attribution Non Commercial Share Alike 3.0 license, as is this post.
Fast forward merge
Figure 1. Linear history
There are a few commits already and your HEAD pointer is currently at commit
c2. Say you now decide to create a new branch:
$ git checkout -b feature-x Switched to a new branch 'feature-x'
This is what our workflow looks like now:
Figure 2. New branch, feature-x
After adding a
LICENSE file, the
feature-x branch moves ahead of the master branch:
$ vim LICENSE $ git commit -a -m "add license"
Figure 3. feature-x ahead of master
Let’s say you now get told that you need to fix an important bug that takes precedence over the new feature you’re working on. You decide to base this new branch off master:
$ git checkout master Switched to branch 'master' $ git checkout -b fix-login-bug Switched to new branch 'fix-login-bug' $ vim login.php $ git commit -a -m "fixed whatever was wrong" [fix-login-bug 1ga2879] fixed whatever was wrong 1 file changed, 11 insertions(+)
Figure 4. New fix-login-bug branch made and now ahead of master
Now it’s time to merge fix-login-bug into master. To do this, you first need to switch to the branch that you want to merge into – master in this case.
$ git checkout master $ git merge fix-login-bug Updating k91n234..9bU9365c Fast-forward login.php | 11++ 1 file changed, 11 insertions(++)
Notice where it says
fast-forward. Since master was behind
fix-login-bug (see figure 4: master was on commit
c3 and fix-login-bug on commit
c5), Git has to move the pointer forward.
Figure 5. Current workflow after the fast-forward merge
After completing your work on the new feature, you’re now ready to merge it back in.
$ git add -a -m "add apple sign-in" $ git checkout master Switched to branch 'master' $ git merge feature-x Merge made by the 'recursive' strategy. login.php | 44 + 1 file changed, 44 insertions(+)
fast-forward, it’s now saying that it merged it in using the
recursive strategy. This is because the commit on the branch you’re on (
feature-x) was not an ancestor of the branch we’re merging into (
master). Git does a three-way merge using the tips of the branches (
feature-x) and the last common ancestor.
Figure 6. Three snapshots.
From figure 6, you may now be able to see the three snapshots better. Git has made a new snapshot that is the result of the three-way merge, labelled as
c6 in figure 6. This is known as the merge commit. It is unique in that it has more than one parent:
Unlike older VCS systems like CVS or Subversion (pre v1.5), Git automatically finds the best common ancestor to use for the merge for us. In this regard, Git is a lot easier.
Featured image credit: Caleb Jones