This post is part of my "Shorts" series, where each post is concise and hyper-focused on a single concept.
If you have worked with Git, you must have come across merge commits. These commits are not created every time you merge, but only on some special scenarios. In this post, we will learn about merge commits and when are they created. At the end of the post, I will also provide a way to avoid them.
First, the simple fast-forward merge
Consider that you have a branch named featureX
which diverges from the main
branch like shown below.
If you try to merge featureX
into main
using git merge featureX
, you will see the text Fast-forward
in the merge output. Git uses this merge strategy when the commit pointed to by the branch that is being merged into - main
in this case - is a direct ancestor of the branch that is being merged - featureX
in this case.
In other words, if you start following the parent starting from the commit pointed to by featureX
and you reach the commit pointed to by main
after some jumps, Git will simply move (fast-forward) the main
branch pointer to the commit pointed to by featureX
.
I have used the
main
branch as an example. I don't mean to convey that merges can only happen into themain
branch. Any Git branch can be merged into any Git branch.
When the main branch is NOT an ancestor of your feature branch
Consider the scenario below where the main
branch has moved ahead from the point where featureX
diverged.
In this case, the commit pointed to by main
is not an ancestor of the featureX
branch. So, Git tries to find the common ancestor of the main
and featureX
. Then, Git performs a three-way merge between the common ancestor commit, the commit pointed to by main
, and the commit pointed to by featureX
. It creates a new snapshot that results from this merge and creates a "merge commit" on the main
branch (or the branch being merged into).
A merge commit has more than one parent.
Avoiding merge commits
To avoid "merge commits", you can rebase the featureX
branch on the main
branch. After the rebase, the commit pointed to by main
will become an ancestor of featureX
. To learn more about rebasing, I suggest you read my post introducing git-rebase.
Top comments (1)
Good article!