Git rebase

Git rebase is a must for keeping histories clean. It wasn’t long ago I learnt about this, and I had already been using git for a couple of years.

For some definition of using… Mainly git add . git commit -m “new stuff” git push)

The main advantages of using rebase is:

  1. It allows you clean up branches after review
  2. Results in a linear history, which is easier to revisit later.

Keeping a clean history of your feature branch

As far as I know, the most typical git workflow is using feature branches that eventually get merged to a common branch, typically master. Therefore, at some point, you would:

git switch -c new-feature
git commit
git push

And then do a pull request/merge request, where typically code review happens.

Where the mess typically starts

Assuming your commit history is good before the code review happens, this is typically where the mess starts. Maybe you find a couple of typos in your code, or some errors you want to fix. You might add commits resembling the following:

commit 6477253c1849d8ee67e0f5b326939cda88226083 (HEAD -> master)
Author: ---------------------------------
Date:   Sat Feb 24 11:38:03 2024 +0100

    Fix subtle error
    It turns out that I forgot about a very special case so my first attempt
    to do this is broken and this fixes it

commit d2d41b26a6512a913cdf074cc13047af0198b3f9
Author: ---------------------------------
Date:   Sat Feb 24 11:37:50 2024 +0100

    Fix typo

Or perhaps you might even use suggestions from your peers handled through the GitHub or GitLab web interfaces, because you might not want to jump into your branch, do a commit and push it again if you just want to add a missing comma in a code comment.

See GitHub PR docs for an example.

At this point, you have an important choice:

  1. You go ahead, merge your changes and go on with your life. You’re too busy to clean up your branch. Who cares anyway, am I right?!
  2. You tidy up things before merging. It might take some time if subtle errors were found in code review.

Eventually, someone will want to review whatever you did back then because an issue has been found, or someone wants to change something. What will happen then is up to you

Leave me alone, I’m to busy to waste time rewriting my branch’s history!

I understand, you’re too busy. You might be fixing a bug that requires immediate fixing, it might be friday afternoon or even a weekend. But beware, you might leave a complete mess that makes someone else waste hours (if not more) because you couldn’t spare 30 minutes.

The poor guy looking at your code might look like this:

Concerned Homer Simpson Bad ending: you were too busy

Cleaning up the mess

In order to tidy up, my go-to mechanism is:

  1. git commit –fixup=SHA_OF_THE_COMMIT_I_WANNA_FIX
  2. git commit –fixup=SHA_OF_THE_COMMIT_I_WANNA_FIX
  3. git rebase -i
  4. Rewrite history as I want, modifying commits, squashing them, changing commit messages, …

The –fixup thing is mainly for convenience, because if you do that and

 autosquash = true

in your .gitconfig file, git will automatically move your fixup commits right after the commit you’re fixing, and squash them into the original commit while keeping the old commit message. Of course, if you want to rewrite the commit message, you can also squash (or if the commit you’re fixing is the last one you did, amend it.

You combined bugfixes and typos to the original commits that introduced them, and adapted commit messages appropriately. The commit history clearly reflects what you did and why, and it’s there forever.

Relaxed Homer Simpson Good ending: you did THE RIGHT THING™


This post is licensed under CC BY 4.0 by the author.