When working on a collaborative project, you find strategies like feature branching or bugfix branching.By using pull requests, changes can be integrated into the main or release branch.
From time to time, while actively developing your feature, new changes will occur on the main branch. When pulling from upstream (main) branch, there are two options:
- Merging the upstream branch into a local branch
- Rebasing the local branch on its upstream branch
In this short article, we will see how those two options differ.
1. Merging the upstream branch into the local branch
This is the default strategy when using
git pull. If changes in the upstream branch are present, then git will create a new merge commit indicating that changes have been merged into your local branch.
This results in having a base, some local commits, followed by a merge commit. When opening a pull request, the git history of your branch is quite cluttered. The more you pull from an upstream branch, the more merge commits your commit history will have. A review of this pull request might become more difficult since unnecessary merge commits clutter your linear work process.
2. Rebasing on the upstream branch
Another option to integrate remote changes into your local branch is to use the
git pull --rebase option.
Your local branch gets an update to the upstream branch and any present local commits will get applied again on top of the new base.
The result is a linear and clean commit history, resulting in a clean
Merge to the main, rebase the feature
Rebasing the feature branch on the upstream branch results in clean git history and
makes your workflow more comprehensible.
However, keep in mind, that rebasing actively changes a given commit history.
Never use rebase on public branches since you will modify everyone’s history, which leads to merge conflicts!
In case of a merge conflict after pulling, you can resolve it as usual using
Rebasing will apply every commit after each other. If you have e.g. 10 commits with merge conflicts a single merge commit could be a better choice since you only need to resolve an overall resulting conflict once.
When you want to update an already pushed history using git rebase you need to pass
git push to force rewrite the git history.
Otherwise, the history cannot be rewritten.
When working alone on a feature branch, rebasing is a solid option for a clean history. However, when working with multiple colleagues on a branch, merge commits should be preferred to avoid manipulation of the git history. If you want to dive deeper into this topic I can recommend the tutorial Merging vs. Rebasing over on atlassian.com.