Rebase to the future!
Tags: git, rebase, tutorial
Published: 2018-05-02 19:04:02

---
title: Rebase to the future!
published: true
description: Learn how to alter history with git rebase
tags: git,rebase,tutorial
cover_image: https://thepracticaldev.s3.amazonaws.com/i/tyadekazzapy1jp7ajky.png
---


Although *rebase* is not a complicated concept itself, many people have trouble understanding it.

I believe this is mostly because people new to git postpone or never get to learning the rebase command because they are overwhelmed by all the other stuff necessary to just survive with git. And the fact they keep hearing rebase is a dangerous command makes them keep postponing it's learning.


So if this applies to you too, stay with me to learn how git rebase works on a simple example.

-----

Say you are on your project's `master` branch (we’ll display only the last 4 commits):

![master branch](https://thepracticaldev.s3.amazonaws.com/i/8traaniaq5h361gvjaud.png)

Now you want to develop some cool new feature on a different branch so you create one with `git checkout -b feature` and make two commits. Now your `master` and `feature` branches look like this:

![feature branch](https://thepracticaldev.s3.amazonaws.com/i/t62c0inaqpnd101cgptu.png)

But now someone reports a bug on your application and you quickly switch (checkout) to your `master` branch to find and fix the bug. After some time you do fix it and push (and deploy) the change. Everything is fine again and you can come back to your `feature` branch.

![bug fix](https://thepracticaldev.s3.amazonaws.com/i/ge9rm07wya4qegb7jugt.png)

But now you realize you have a little problem. Your `feature` branch still has that same bug that you fixed on the `master` branch and you realize that the bug will also affect your new code on the `feature` branch, so you need to incorporate those bug-fixing changes (commit) to your `feature` branch. But how? Well, there are a few ways to achieve that but the best would be if you could just go back in time like Doc and Marty did, and do the bug-fix commit before you made the `feature` branch. That way the commit that has the bug fixing code would be contained in the `feature` branch (once you get back to the future). Well, turns out you can do just that. I mean, not actually go back in time but alter (git) history. And you do it with the rebase command. So, if you are on your `feature` branch and you do:

```
git rebase master
```

This is how your branches are gonna look like afterward:

![bug fix](https://thepracticaldev.s3.amazonaws.com/i/mhlbpwgznzgw2wemgma6.png)

As you see, the history of the `feature` branch has changed. If someone would now look at it he/she would think you made (checked out) your `feature` branch after the bug fixing commit.

----

So this is great right? Why just not use it all the time? Well, there is a catch. Remember how when Doc and Marty came back to the future it was a bit different? Well, that happens with git rebase too, but don’t worry, your code will stay the same, only the checksums of the commits on your `feature` branch will change. And what are these checksums? Well, you probably noticed that 40-chars long string that you see right to every commit when you do `git log`:


```
commit f5cad47722bc98419fe5037753f5bbe29d3917c4
Author: John Doe <john@doe.com>
Date:   Mon Apr 23 11:49:07 2018 +0200

Did some stuff:)
```

That's the *checksum*. You can think of checksums as unique identifiers for commits and because of the way git generates them (you can check my blog post on git’s [data model](https://hackernoon.com/https-medium-com-zspajich-understanding-git-data-model-95eb16cc99f5) for more info) they change on our `feature` branch after rebase.

So, if the commits had these checksums before rebase:
![checksums before rebase](https://thepracticaldev.s3.amazonaws.com/i/dmw3ja93wua991hvjv6f.png)

Then after the rebase, the checksums on the `feature` branch would change:
![checksums after rebase](https://thepracticaldev.s3.amazonaws.com/i/nse4xau2mge7jifxolyn.png)

And this is why you keep hearing git rebase is a *dangerous* command. Because it alters history and you should use it with caution. 

But why exactly is this **dangerous** and when? Well, let’s say you are not the only one working on the `feature` branch, but there are more people pulling and pushing changes to it. And now you do your rebase and (force) push the changes to the `feature` remote. Now, when your colleague Bob tries to pull from the remote `feature`, everything explodes because his local version of `feature` branch has a different history than the remote version.

![rebase explosion](https://thepracticaldev.s3.amazonaws.com/i/yp1wetiyj9ivm9zvp6tr.png)
OK, so Bob’s computer won't actually explode, but there is no nice way for him to fix this situation. So, as a general rule of thumb, if you are working on a public branch (that other people are pulling changes from), you will not do a rebase on that branch. If, on the other hand, you are working on your local branch and haven’t pushed it to the remote server yet, or you did but it is still only you who is working on that branch (you must be sure of that) then you can do a rebase on it.