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:
- It allows you clean up branches after review
- 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:
1
2
3
4
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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:
- 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?!
- 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:
Cleaning up the mess
In order to tidy up, my go-to mechanism is:
- git commit –fixup=SHA_OF_THE_COMMIT_I_WANNA_FIX
- git commit –fixup=SHA_OF_THE_COMMIT_I_WANNA_FIX
- git rebase -i
- 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
1 2 [rebase] autosquash = truein 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.
Good ending: you did THE RIGHT THING™
Please, DO THE RIGHT THING.