One of the most read articles on Medium about git rebase encourages to not do so. This article advises the only purpose of rebasing is to have a good looking git log history.

I’ve come to the conclusion that it’s about vanity. Rebasing is a purely aesthetic operation.

I want to list a few good reason why, in my opinion, rebasing is a good practice that brings many benefits to your workflow.

What does rebase mean?

Suppose that you have a feature branch you’re working on, and a master branch you branched off from. You should have a log history like this:

$ git log --graph --oneline * f7d389gc (feature) — lorem ipsum

* 6hy982dx — dolor sit

* aer3ou71 — amet consecutur

* nfk62s3z (master) — adipiscing elit

* …

Suppose that you’re not working on the project on your own, other developers are adding contribution to the codebase. So while you’re working on your branch, the master branch has been moved forward on the remote git server.

git rebase — figure 1

In order to inherit the changes introduced on the master branch, you can rebase, basically move your commits on top of the master branch.

Assuming that your feature branch is named feature , you may want to run:

$ git checkout feature

$ git rebase master

After the rebase process you might have a status like so:

* e2r3fa05 (feature) — lorem ipsum

* qc85lx4w — dolor sit

* ui9o7xpa — amet consecutur

* i52dxqs3 (master) — proin sagittis

* nfk62s3z — adipiscing elit

* …

Side effects

In git all commits (except the initial one) contain a reference to their parent commit. What git does when you’re rebasing, is to change the reference to the parent in the first commit of your branch commits history that is not in common with the master branch history ( aer3ou71 in our case).

Consider that the hash of each commit is the result of the hash of a few components, among which is included the hash of the parent commit.

So, given that the new parent’s hash will be different, our rebased commit will get a new hash. So will the other commits that belong to our branch history. You can see that in the snippet above.

You should consider this in the case you’ve pushed your branch to the remote before running the rebase command. In that case your remote commit hashes will be different by the ones you have locally, so if now you just run git push you will get an error saying that the operation cannot be done because the local and the remote versions of your branch have diverged. In order to fix that you just have to force your push:

git push --force-with-lease

Alright, gotcha. But why should I rebase?

There are three reasons imho why it’s worth the hassle.

Increases tests reliability

Have a look at the figure 1 again. If you run your tests on your feature branch before rebasing (left hand side figure), you don’t include the last 3 commits of master in your codebase, so you cannot be sure your tests are not affected by them.

So if your tests pass, you are not sure they will pass again after merging your branch into master.

Rebasing instead, allows you to inherit the code from the latest commits of master.

Makes debugging easier

If you want to rollback your application to a previous version to check where a bug has been introduced you can do that easily if you have a clean history.

In a “spaghetti” history where commits can have multiple parents, the master branch contains both commits with code and merge commits, it would be extremely tricky to spot a commit that introduced a bug.

I explained this topic more in detail in my other post “The importance of meaningful commits”, because making commits with a sense, helps with this operation as well.

Solve conflicts before merging

Solving conflicts can be painful and boring, especially when the feature took too long to be ready and it affected many different parts of the codebase.

If you solve all the conflict at once it might be tricky to get it sorted. Rather, if you solve your conflicts when rebasing, git will prompt the conflict message commit by commit, so it will be easier to track the changes and figure out how to solve the conflict.

Small clarification

In the same article against git rebase I found a statement that made my day:

By rebasing, you are lying to yourself and to your team. You pretend that the commits were written today, when they were in fact written yesterday…

I am not sure what that means, I guess it’s because the author, in his commits history or maybe on Github, sees the last date of modification instead of the date of creation.

Git saves both the creation date and the last modification date:

git show 007e3ae

Author: Alessio Pieruccetti <

AuthorDate: Tue Jul 23 10:26:39 2019 +0100

Commit: Alessio Pieruccetti <

CommitDate: Fri Aug 9 09:14:20 2019 +0100 commit 007e3ae4ab751f8ab2d9cebef87983a320399accAuthor: Alessio Pieruccetti < alessio@xxx.com AuthorDate: Tue Jul 23 10:26:39 2019 +0100Commit: Alessio Pieruccetti < alessio@xxx.com CommitDate: Fri Aug 9 09:14:20 2019 +0100 Replaced exception type in User class

There are a few different ways to show the creation date in your commits history, like:

git log --pretty=fuller

In my .gitconfig I have an alias for git history , like so:

[alias]

history = log --graph --pretty=format:'%Cred%h%Creset %d -%Cblue %s%Creset %Cgreen(%ar) %Cblue<%an>%Creset' --abbrev-commit --date=relative

This will show your log nicely with a relative creation date (eg. 2 days ago ).

Conclusion

In our job I often find people who support or despise this or that tool / programming language / practice. I reckon every tool is good for some context.

I read articles against TDD, Agile development, etc… My point is that these practices are great for some environments or products, but they can fail for others.

Same with git tools.

I don’t want to convince you to use git rebase, but I just want to point out that it has some advantages, as well as git merge. It’s up to you which one to use, depending on your experience, your confidence with the tool and how you work with your teammates.

I hope this helps.