89 things I know about Git commits
This is an article that's been swimming around in my head for ~5 weeks now, and may become a "living post" that I keep updated over time.
In no particular order, some things I've learned about Git commits and commit history, over the last 12 years. This is a mix of experience in companies with teams of 2-12 people, as well as in Open Source codebases with a vast range of contributors.
- Git has different uses - a collaboration tool, a backup tool, a documentation tool
- Git commit messages are excellent
- I've never met anyone who likes reading commit messages as much as me
- Finding out why a change was made is easier sorting through commits than it is through an issue/bug tracker
- It's better to have a commit that says "Various fixes. DEV-123" than it is to have "Various fixes"
- It's worse to have a commit that says "Various fixes. DEV-123" when the issue itself has no useful information
- Rebase-merging is my preference. Then squash-merge, then merge
- If you don't learn how to rebase, you're missing out on a good skill
- People who say "just delete the repo" when things go wrong really frustrate me
- Learn how to use
git reflog
, and it'll save you deleting a repo and work that was recoverable - Learn how to use
git reflog
, and you'll be able to save yourself from mistakes that aren't that bad - No amount of learning fancy tools and commands saves you from fucking up every once in a while
- My most recent botched rebase was last week, and I needed
git reflog
to help un-fuck it - Learn how to undo a force push and then how to more safely force push (remember the
=ref
!!) - Squashing is a waste of well-written atomic commits
- Squashing is better than 100 crap commits
- Squashing, and writing a good commit message at the time of merge is good
- Squashing, and then not re-editing the message is the worst
- Squashing, when you have 100 crap commits, and then not re-editing the message is a crime
- Squashing, and then not re-editing the message is worse than a merge commit from a branch with 100 crap commits
- Writing a well documented PR/MR description but not using that to inform the squash-merge message is a waste of time
- Writing commit messages have helped me pick up on missing test cases, missing documentation, or invalid thought processes, as it helps me rewrite why the changes are being made
- Using your
git log
as an indication for standup updates is valid - I can't be bothered to sign my commits (unless I'm forced to)
- If I have to sign my commits, SSH key signing makes it almost not awful
- If you're moving files between repos, you need to keep the history intact, using
git subtree
- Commits should be atomic - all the code and tests, and configuration changes should all be in there
- I spend a good chunk of time ensuring that each commit passes CI checks atomically
- Some people do horrific things, like split their implementation and test code from each other
- It's OK to put documentation in a separate commit - we don't have to have a whole end-to-end feature delivery in a single commit
- Repos that use squash-merges suck
- As a maintainer of Open Source projects, I like squash-merge, so I can rewrite contributors' commit messages
- Sometimes it's not worth coaching how to write a given commit message
- The people around you shape the way you write commits
- Do the work up front to make your history atomic
- It's much more painful to split a mega-commit into atomic commits after the fact
- Splitting work atomically can be good for improving your reward drive - you can get many more things done
- Atomic commits work really well with prefactoring
- Sometimes prefactor commits can go into separate PRs (especially if squash-merge is used)
- Writing commit messages can take longer than the implementation
- The commit message can be an order of magnitude larger than the number of lines changed in a commit
- If you end up writing a lot of "and"s or "also" in a commit message, you may be trying to do too many things
- Trawling through Git commit history in the past has helped unlock a number of cases where I could then understand the why without the original authors there to answer my questions
- Commit messages are a great point to reflect on not just what you've done, but why
- Why is more important than what - anyone can look at the diff and generally work out what changes were made, but the intent behind it is the special sauce
- If you only write what changed, you're annoying, and I dislike you
- A commit that explains what is better than a commit that just has "fixes"
- Chris Beams' article, How to Write a Git Commit Message is still an excellent post and a great place to start, just under 10 years later!
- Commits are a point-in-time explanation of the assumptions and the state of the world for the committer. Don't be too hard on them
- I don't want to read AI/LLM rewrites of your changes - either write it yourself, or call it
Various fixes
- There needs to be a way to add an annotation (maybe using
git notes
) to a previous message to correct assumptions - I won't write perfect commit messages up front - they'll sometimes be as much as
rew! add support for SBOMs
orsq
, or usegit commit --fixup
- I will, generally, break off very good atomic chunks of work into commits
- I will split atomic commits into multiple commits, sometimes
- Make sure you review your own code changes before you send it out for review to your collaborators
- Reviewing your commit messages should be as important as reviewing the code changes
- Getting all your contributors to invest the same amount of care into the commit history is a losing battle
- Trying to police commit history is going to be painful
- Trying to mandate reviews of commit messages as part of code review is going to be painful
- Trying to police commit history does lead to a greater level of documentation and consideration around changes int he codebase
- Making implicit assumptions explicit is really useful
- Introducing
commitlint
can be useful, but also frustrating - It's nicer to have your collaborators want to write good commit messages than you having to force them
- Some people don't write, and that's alright
- Writing is a skill
- I'm not perfect at writing (commit messages)
- Sometimes I can't be arsed to write the perfect message
- Sometimes I write some really great commit messages, and impress myself
- Using a template for your Git commit messages is a good nudge to doing it right
fixup
commits andgit rebase --autosquash
has been one of the best Git tips I've learned- I value working on a team with a diverse set of perspectives, skills and approaches to work
- But I also really value having a team who writes atomic commits with well-written commit messages
- Commit message writing is as useful as writing well-refined user stories/tickets
git commit -m sq
is probably my most-run command- Using
git add -p
andgit commit -p
are hugely important for atomic commits - Never use
git add -u
orgit add .
- Learn when you can use
git add -u
orgit add .
- I really need to look into tools like Graphite,
git-branchless
and other means to provide a stacked PR setup - Using conventional commits with semantic-release or go-semantic-release can make a huge difference when wanting to release automagically and often
- Using conventional commits as a framework for your commits can be really useful
- Using conventional commits, as someone with ADHD, reduces the need for thinking at times and can allow you to focus more on what the changes are
- Using conventional commits helps you work out when you're trying to do too much in a commit
- I think through writing so commit messages help understand why I did the thing
- It can be better to write a good commit message than a piece of documentation, stored elsewhere
- It can be better to write a good commit message than a code comment
- Give people space to learn
- Give people space to fail
- Remember you weren't so great at one point in time
- Documentation is rad. Do more of it