Git `merge` vs `rebase` to keep feature branch up to date
Tags: git
Published: 2020-05-25 14:47:57

Today we are going to look at how Git [merge](https://git-scm.com/docs/git-merge) and [rebase](https://git-scm.com/docs/git-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](https://git-scm.com/docs/git-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](https://git-scm.com/docs/git-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](https://git-scm.com/docs/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](https://twitter.com/BelevMartin) where I will share another tips and upcoming articles from my experience.