Sep 21, 2022

Clean git history: git pull --rebase vs. git pull --merge

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:

  1. Merging the upstream branch into a local branch
  2. 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

AWS S3 - website setup

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

AWS S3 - website setup

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 pull request.

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 git mergetool.

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 -f to 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.

git rebase merge pull request