Git takes a long time to become comfortable with. Still now, years after I first used it, I hold my breath doing rebases and cross my fingers there are no conflicts. It is not controversial to say Git is unintuitive, with strangely named commands and a lacking command line interface. Unfortunately, we're stuck with it for the time being...
"Git hygiene" refers to good organisation of a Git repository and its commit history. Commits act as documentation and are often used to generate release notes, so it is important they describe changes accurately. For me, each commit should represent the project in a working state. I should be able to checkout something from a couple weeks ago and run the project without error. That said, it is common to see the following in pull requests:
feat(Button): add size variant
chore: fix linting
fix: pull request feedback
fix: failing test
There are a few problems with the above:
main
branch is polluted with broken commits. Later on, identifying which commit introduced an issue becomes harder.Fixup commits offer us an alternative here. Let's start with the commit:
feat(Button): add size variant
Imagine I open the pull request and an automated workflow tells me there are lint issues. Instead of naming a new commit I can run:
git commit --fixup [COMMIT_SHA]
Which results in:
feat(Button): add size variant
fixup! feat(Button): add size variant
When I first saw that I thought it was perfect. It indicates exactly my intentions to the the reader: I want one commit, but I am "fixing" it with further revisions. Now, we could rebase locally and push only a single commit back to the remote branch, but in my experience GitHub doesn't like that. In the case of some feedback being addressed I want to compare the previous state to the new one and I need multiple commits for that.
Still, we do need to squash the commits before merging since we don't want them ending up on main
. Thankfully, we can do:
git rebase main -i --autosquash
This applies all the fixup commits, resulting in one (or more) clean and hygienic commits that are ready to be merged. I do wish GitHub would integrate this functionality into its user interface. Currently that command must be run locally, instead of using the "Rebase and merge" button.
February 4, 2024