I’ve been taught several times about best practices for committing code changes grouped into logical chunks, and I start every new feature branch with the intention of writing organized commits based on these principles. In practice, however, my commit history always looks like more of a hot mess than I had originally intended.
While it’s tempting to write off commit hygiene as more effort than it’s worth, authoring clean and organized commits that logically group code changes has substantial benefits:
cherry-pick
to better organize their commits.
In other words, organizing commits is like washing your hands - it’s something everybody should be doing to improve the whole group’s [code] hygiene.For some tasks, writing code in a way that lends itself to organized commits comes naturally, but for more complex features this can be anywhere from difficult to impossible. If I want to consistently have a useful commit history at the end of the development process, like a Hollywood celebrity I sometimes have to fake it in post-processing.
Thankfully, git provides several tools to make this easy. Here is a list of some of the tools I find most useful, including when and how to use them.
Augments your most recent commit message, contents, or both. It will lump any staged changes in with your most recent commit contents, and will give you an opportunity to make inline edits to that commit’s message.
You just thought of a better way to phrase your commit message. You noticed some weird extra whitespace after a change you just made. Amending is useful any time you want to correct a small error or make a small improvement.
git commit --amend
will add any staged changes to your most recent commit and launch an editor to edit the message
Changing Last Commit Using --amend - PawanGaria
Launches an interactive editor that allows you to re-order, combine, and remove commits as well as edit commit messages.
You’ve created a new commit for every single trivial change in your feature branch. You have several commits that introduce a change only to later change it again or just revert it. Reviewers are faced with a formidable 18 commits with no guidance on where the bulk of the changes live. Interactive rebasing allows you to logically group those commits by combining multiple commits that have all made related changes or deleting ones that are no longer wanted.
git rebase -i HEAD~{n}
, where {n} is the number of previous commits you would like to rewind. This will launch an interactive editor with detailed instructions, but I’ll include only a few highlights:
pick
with f
or fixup
to combine a commit with the one immediately before it (remember, you can change the order to combine it with any commit). Replace it with s
or squash
if you want to do combine commits while also updating the commit message.--preserve-merges
(or -p
) when you run your rebase if you've been using a merge-based workflow. This will help you avoid resolving rebase conflicts on merge commits (otherwise, you will be very, very sad).Git Interactive Rebase, Squash, Amend - ThoughtBot
Creates a new commit on your current branch that applies the contents of an existing commit from a different branch.
You are branching from a coworker’s work because they have done an important refactor in part of the code base that you are working with. However, they’ve also introduced several other changes in the same branch that are irrelevant to your work. Since you only care about a subset of the changes on their branch, you would cherry-pick only the commit(s) containing the refactor.
git cherry-pick {sha}
where {sha} is the unique ID for the commit you would like to apply to your branch. Repeat for every single commit you would like to cherry-pick.
Understanding Git Cherry-pick - CodeMentor
Launches an interactive editor that allows you to stage your local changes one chunk at a time.
You’ve introduced several local changes (a small refactor, a new feature, and tests for each) that don’t logically belong in the same commit, but may live in the same file(s). Add patch will allow you to stage and commit your changes in logically grouped chunks.
git add --patch
(or -p
) will launch an editor that will group your unstaged changes and display one at a time. Changes are grouped into hunks based on git heuristics, but you can split a hunk into smaller pieces, provided that the changes are not on adjacent lines. If you have made two unrelated changes on adjacent lines, you can manually edit the hunk within the interactive editor. After you’ve staged a logical grouping of your changes, commit and then repeat.
Git add --patch - Nuclear squid
Rewinds all commit history compared to the origin and surfaces the changes in your working tree.
You want to split changes in a single commit into multiple commits, or keep only some changes from a single commit. This is particularly powerful when combined with add patch to turn one or more bloated commits into new commits with logically grouped changes. When your commit history is so messy that it feels beyond rescuing, resetting your branch to origin/master is a wonderful git-grenade. It will allow you to keep all of your changes but re-write your commit history from scratch.
git reset {sha}
to rewind to a particular commit, or git reset origin/{parent branch}
to rewind all the way back to a parent branch.
Assuming you have at some point pushed your changes to the remote origin branch, using any of these tools will require a force push (-f
or --force
). This can be scary at first, and the internet is full of strongly-worded warnings against force pushing.
However, provided you are safely sandboxed on a feature branch, the damage you can do with a force push is minimal. If I am the only person working on a feature branch, I won’t hesitate to force push as often as I’d like. If I am working with other engineer(s) on a single branch, it can be a bit easier to permanently overwrite changes with a force push. Some helpful ways to prevent lost changes are:
Just before I am ready to open a pull request up for review, I will use these tools to re-organize my commits. I find that they are incredibly helpful for turning my change history into useful documentation, and I hope you find value in them too!
Want to know more about what it's like to work in tech at Simply Business? Read about our approach to tech, then check out our current vacancies.
Find out moreWe create this content for general information purposes and it should not be taken as advice. Always take professional advice. Read our full disclaimer
Keep up to date with Simply Business. Subscribe to our monthly newsletter and follow us on social media.
Subscribe to our newsletter6th Floor99 Gresham StreetLondonEC2V 7NG
Sol House29 St Katherine's StreetNorthamptonNN1 2QZ
© Copyright 2023 Simply Business. All Rights Reserved. Simply Business is a trading name of Xbridge Limited which is authorised and regulated by the Financial Conduct Authority (Financial Services Registration No: 313348). Xbridge Limited (No: 3967717) has its registered office at 6th Floor, 99 Gresham Street, London, EC2V 7NG.