Rebase vs. Merge

Git

In the past, I have always merged master into my feature branch before a pull request. Should I have used rebase all this time?

The first thing to remember is that both of these commands allow to integrate changes from one branch into another branch. They just do it differently.

Merge

Merging is the easiest option.

To merge master or main into your feature branch, you would do the following: git merge feature master

This creates a new commit into your feature branch that ‘regroups’ the branches together.

Your history will now have a ‘merge’ commit as the latest commit.

Merge is safe as it is a non-destructive option.

The only disadvantage is that it shows an extra commitment in your branch. If you were to merge main often in your feature branch, it could pollute your commit history and making harder to follow.

It sounds like a minor inconvenience but having a single atomic commit makes reviewing easier.

Also, when you go down the rabbit hole of the git history to understand a piece of code, those merge commits tend to muddy the water since they are often quite sizeable.

Rebase

Rebasing moves the entire branch to be based on another commit.

Let’s take an example. You started working on your feature when the main last commit was ‘A’. Your feature branch is base on A. While you working on your feature, PRs are getting approved and merge into main. The main branch is now at commit C. Rebasing feature onto main will move the base of feature to C. In other words, it will look as if you created your branch when master was at C.

This has the advantage of creating a linear commit history. It makes it easier in the future to work with git log, git bisect or gitk

The drawback is that rebasing can be destructive if not applied properly.

When to use rebase vs. merge

I tend to use git quite a lot to go back in time and try to understand the why behind the code. Whether we like it or not, we all work in legacy codebase. The code that we write today is the legacy code of tomorrow.

Unfortunately, some developers don’t like to leave comments for diverse reasons that I do not understand - but that’s another debate.

Having a nice commit history is great to inspect why a certain piece of code has been written in a certain way. Especially when something looks hacky, it is probably because it was meant to be hacky.

Therefore, moving forward I will be using rebase as much as possible.

When you should not rebase

There is one important rule: do not rebase public branches.

A public branch is a branch that your colleagues might use.

Without going into details, when you want to push a rebased branch you often need to force push. If you were to rebase a public branch, such as main and force push it, you might overwrite code.

In case of doubt, merge

While I like rebase, in case of doubt a merge is always the safest option. Take it from a man that spent hours yesterday finding a bug introduced during a careless rebase…