DEV Community

Cover image for Git `merge` vs `rebase` to keep feature branch up to date
Martin Belev
Martin Belev

Posted on • Edited on • Originally published at belev.dev

Git `merge` vs `rebase` to keep feature branch up to date

Today we are going to look at how Git merge and rebase commands behave while trying to keep feature branch up to date.

In a large codebase where a lot of people are working we have constant updates to the master branch. We want to work on top of this branch and always have to latest changes. We can achieve this by either using merge or rebase to get the latest changes made in master branch into our feature branch.

merge

So what is merge doing:

Join two or more development histories together

Let's now look at an example using merge to keep our branch up to date. This is pretty simple example with a few commits in each branch:

* c5d39ef (HEAD -> feature) update 1 feature.txt
* 0c4d97c add feature.txt
| * 4d55c54 (master) update 1 master.txt
|/
* 2358179 add master.txt

// Different representation of the situation
A---B  master
 \
  C---D  feature

We started our feature branch from master where at first there was only one commit A. We made a commit 'C' in our feature branch. In the mean time someone made a commit B in master branch and after that we made another commit D in our feature branch. We now have to get the latest changes from master into our feature branch and we are going to use merge.

After executing git merge master from our feature branch we got:

*   ec3f6dc (HEAD -> feature) Merge branch 'master' into feature
|\
| * 4d55c54 (master) update 1 master.txt
* | c5d39ef update 1 feature.txt
* | 0c4d97c add feature.txt
|/
* 2358179 add master.txt

// Different representation of the situation
A---B  master
 \
  C-B-D-E  feature

It has it's benefits, of course, as every other thing in software development but the drawbacks in large codebase are huge.

  • It is hard to go back and change/clean our feature branch commits.
  • It is making hard to follow and find out when/why something was done.

In this simple example maybe it is understandable what happened. But in real life where we got hundreds of commits and we will make a lot of merge commits which are redundant. You can imagine that this is going to become almost impossible to follow when we are working for a long time on a feature because we will end up with a lot of merge commits.

rebase to the rescue

So what is rebase doing:

Reapply commits on top of another base tip

We will review the same scenario but using rebase instead.

A---B  master
 \
  C---D  feature

After executing git rebase master from our feature branch we got:

* 7d4b7c0 (HEAD -> feature) update from-rebase.txt
* 5b61ccd add from-rebase.txt
* d694446 (master) update rebase.txt
* 8f8b0e3 add rebase.txt

// Different representation of the situation
A---B  master
     \
      C'-D'  feature

We got our changes reapplied over the latest commit from master branch. Note: the commits have the same set of changes but from Git point of view they are completely different objects and have different hashes.

Conclusion

By using rebase we benefit from:

  • making the history in our master branch much easier to follow because it is linear
  • long tramlines from long-lived feature branches
  • ability to easily change our feature branch history

There are a couple of things to keep in mind though:

  • it can be confusing for less experienced Git users
  • we are loosing the chronological order - IMO this is not a problem at all because we achieve series of intentional changes that are made to master branch
  • it can result in fixing the same conflict for every commit in the feature branch - for this one I find really useful the git rerere configuration which is saving the resolved conflicts and then reusing them. With it we don't have to resolve the same conflict all over again.

I don't recommend to blindly use rebase to keep your feature branches up to date but for larger projects my preference is to use rebase instead of merge.

When I started using Git I find those concepts very confusing, so I hope someone will enjoy this and will find it useful. If this is the case, please follow me on Twitter where I will share another tips and upcoming articles from my experience.

Top comments (5)

Collapse
 
martinbelev profile image
Martin Belev

It is true that things can get really messy with rebase when people don't understand what is happening. We had this problem for a while, sometimes fixing the problem requires an hour or two... However, I couldn't say that we didn't have problems with merge as well. So, I think if people don't spend enough time playing around with Git and learning how it is working and the concepts behind it, we will always end up in messed up situation.

From my experience, merge is working well enough when the team is small - let's say up to 6-8 people. There aren't so many changes that we would need to get from master branch and keeping the feature branch up to date is not so critical. However, with multiple teams working on the same codebase the situation is pretty different and merge is just not working. So, the sooner team members get familiar with more Git commands, the better.

This article is just scratching the surface and there are a lot of things going on in a large codebase with a proper Git workflow. I agree deep dive into this topic can be good for an interview.

P.S. I am thinking to share more articles about problems that we encountered in our teams - one of them will be deeper look into rebase because when we have branch from a branch things get messy.

Collapse
 
dimaip profile image
Dmitri Pisarev πŸ‡·πŸ‡Ί

The additional difficulty of conflict resolution with rebase made me lean towards merge more and more... I hate conflicts!

Collapse
 
martinbelev profile image
Martin Belev

Give β€˜rerere’ a try - you won’t need to resolve the same conflict again. Apart from that, conflicts can occur in both cases.

Collapse
 
dimaip profile image
Dmitri Pisarev πŸ‡·πŸ‡Ί

Thanks, I will! How reliably does it work? Any disadvantages compared to merge?

Thread Thread
 
martinbelev profile image
Martin Belev

Rerere is just a Git configuration, it can’t be compared to merge. About the differences, there is some more information in the article. : )