Merging is adding the work done in one branch to another. There are three ways one could merge one branch into another:
- fast-forward merging,
- squash merging,
- and merging by creating a merge commit.
I would call the 3rd option "real merging" to emphasize it when necessary.
TL;DR
This piece subtitled "The Three Types of Merge" focuses mainly on setting up the ground for the discussion on whether to use rebase or merge. A follow-up article called "Git Merge vs Rebase and Where to Use Them" will cover the pros and cons of each workflow.
Fast-Forward Merge
When you have only new commits in the source branch, fast-forward merging is simply adding those commits to the destination branch. Easy!
Rebase and Fast-Forward Merge
The fast-forward merge is only possible if the target branch is an ancestor of the source branch, which is usually not the case. You have added 2 commits to your feature branch and by the time you want to merge it back to master, your colleagues have added 4 commits to it. In this situation, we say the feature branch is 2 commits ahead of the master and 4 commits behind.
One cannot perform a fast-forward merge if the feature branch is anything behind. To solve this problem, we do something called a "rebase". By rebasing the feature branch onto master, we remove the newly added branch commits, update the branch with the current state of the master, and then add the remove commit on the tip of the master.
git switch feature_branch
git rebase master
After performing the rebase, the feature branch becomes 2 commits ahead and 0 commits behind the master, and hence we can perform the fast-forward merge.
git switch master
git merge --ff-only feature_branch
Real Merge
Let's return to the case with the feature branch 2 commits ahead and 4 commits behind master. When performing a real merge, a new commit is added to the master branch that contains all of the new changes from the feature branch.
git switch master
git merge feature_branch
The newly added commit is called "the merge commit". It has references to the head of the feature branch, as well as a reference to its previous commit in the master branch; this is why we say the merge commit has two "parents".
Merge vs Rebase
When we talk about "merge vs rebase:, we are comparing the following two workflows for merging two branches:
- rebase and fast-forward,
- or perform a real merge.
There are a few differences between the two workflows:
- The rebase workflow keeps the git graph linear, while the merge workflow keeps track of the branch commits.
- If there are conflicts, in the former workflow one needs to resolve them in the rebasing phase, while in the latter workflow one needs to resolve them in the merging phase (so, one needs to merge the master into the feature branch, and then merge the feature branch into master).
Squash Merge
The third type of merging exists which is not getting as much attention. The squash merge basically squashes all of the commits on the feature branch (i.e. packs them all into one commit), and adds the one commit to the target branch.
The main difference is that the newly created commit has no reference back to the branch it was created from. So, this way of merging has similarities to the other two.
Future Work
In a future work to be published next, a full comparison between the workflows will be carried out.
Top comments (0)