Rebase vs merge
Conceptual Overview
The first thing to understand about git rebase
is that it solves the same problem as git merge
. Both of these commands are designed to integrate changes from one branch into another branch—they just do it in very different ways.
Consider what happens when you start working on a new feature in a dedicated branch, then another team member updates the master
branch with new commits. This results in a forked history, which should be familiar to anyone who has used Git as a collaboration tool.
Now, let’s say that the new commits in master
are relevant to the feature that you’re working on. To incorporate the new commits into your feature
branch, you have two options: merging or rebasing.
Merge
Merging is nice because it’s a non-destructive operation. The existing branches are not changed in any way. This avoids all of the potential pitfalls of rebasing.
On the other hand, this also means that the feature
branch will have an extraneous merge commit every time you need to incorporate upstream changes. If master
is very active, this can pollute your feature branch’s history quite a bit. While it’s possible to mitigate this issue with advanced git log
options, it can make it hard for other developers to understand the history of the project.
Rebase
This moves the entire feature
branch to begin on the tip of the master
branch, effectively incorporating all of the new commits in master
. But, instead of using a merge commit, rebasing re-writes the project history by creating brand new commits for each commit in the original branch.
The major benefit of rebasing is that you get a much cleaner project history. First, it eliminates the unnecessary merge commits required by git merge
. Second, as you can see in the above diagram, rebasing also results in a perfectly linear project history—you can follow the tip of feature
all the way to the beginning of the project without any forks. This makes it easier to navigate your project with commands like git log
, git bisect
, and gitk
.
But, there are two trade-offs for this pristine commit history: safety and traceability. If you don’t follow the Golden Rule of Rebasing, re-writing project history can be potentially catastrophic for your collaboration workflow. And, less importantly, rebasing loses the context provided by a merge commit—you can’t see when upstream changes were incorporated into the feature.
Golden rule of rebasing
The golden rule of git rebase
is to never use it on public branches.
So, before you run git rebase
, always ask yourself, “Is anyone else looking at this branch?” If the answer is yes, take your hands off the keyboard and start thinking about a non-destructive way to make your changes (e.g., the git revert
command). Otherwise, you’re safe to re-write history as much as you like.
Interactive Rebasing
Interactive rebasing gives you the opportunity to alter commits as they are moved to the new branch. This is even more powerful than an automated rebase, since it offers complete control over the branch’s commit history. Typically, this is used to clean up a messy history before merging a feature branch into master
.
Eliminating insignificant commits like this makes your feature’s history much easier to understand. This is something that git merge
simply cannot do.
Squash rebase workflow
before you merge a feature branch back into your main branch (often master
or develop
), your feature branch should be squashed down to a single buildable commit, and then rebased from the up-to-date main branch.
If you follow this process it guarantees that ALL commits in master build and pass tests. This simple fact makes debugging an issue much easier. You can use git bisect when trying to find the source of a bug. Git bisect becomes almost completely ineffective if there are broken commits on the master branch; if you jump to a commit that isn’t clean, it’s difficult or impossible to tell if it introduced the bug.
Because each commit contains all the code for a feature or bug fix, you can easily see the whole unit of work in a commit, and you don’t have to worry about checking out the correct commit from a branch.
It makes handling conflicts from rebasing simple. Since you’ve squashed down to one commit, you only have to deal with those conflicts once, rather than having to work against half-baked code. It reduces the risk of losing code when dealing with conflicts.
When it comes to squashing and rebasing your commits, the pros significantly outweigh the cons. It speeds up your debugging process, cleans up your history, reduces the pain from merge conflicts and makes collaboration in your team much better.
Merge vs Rebase
And that’s all you really need to know to start rebasing your branches. If you would prefer a clean, linear history free of unnecessary merge commits, you should reach for git rebase
instead of git merge
when integrating changes from another branch.
On the other hand, if you want to preserve the complete history of your project and avoid the risk of re-writing public commits, you can stick with git merge
. Either option is perfectly valid, but at least now you have the option of leveraging the benefits of git rebase
.
Last updated
Was this helpful?