"Squerging" is an effective way to close off a GitHub PR that I've come to learn while working with the guys at Lonely Planet that keeps the master commit log nice and tidy. Just what is it? Allow me to explain...
Alright, so it's not a real word. Someone at LP made it up (I believe it was chee). Often, PRs that have been through code review end up with a form of approval that simply says:
It's a combination of "squash" and "merge" and, as such, is the last step before hitting the green "Merge pull request" button.
If you're anything like me, you're likely to have a whole bunch of commits that could probably have been grouped together by the time you come to creating your PR... something like the following:
In this instance I feel it could be summed up in just a single commit and would make the
master branch's history log look a bit more sensible. As long as it makes sense, summing it up in more than one commit is also perfectly fine.
Another reason to combine commits like this is you don't really need to worry about every single commit making sense on it's own while developing. Sometimes you just need to commit something before you leave work, or there are code review changes (which make for rather unhelpful commit messages).
The first part of our "squerge" moniker is really what it's all about as the "merge" bit is just hitting the button on the PR, which brings me to...
In order to squash your commits, you need to do what's known as an interactive rebase in git using the following command:
git rebase -i HEAD~7
7 here is just the number of commits you want to iterate over. The easiest way to find this is by looking at the number in the "Commits" tab at the top of your PR:
Once you've run that command, it should open up your editor of choice with a list of commits that should look something like this:
The comments at the bottom explain what you can do in here, but I'm only going to focus on the
squash (or just
s if you prefer) command.
This means that the
Add styles for current time section commit would be combined with the
Add flip clock styles commit if the former had an
squash beside it.
Once you've set up everything the way you like it, save your changes and exit the editor. Now git will roll back to where you branched off of
master and start applying (from top to bottom) the commits where you had left
pick. When it gets to a
squash command, it collects all the other commits you want to squash (until it finds the next
pick) and fires up your editor again:
Here's where you get to change the commit message. The format I like to do it is as follows so that all the steps that make up the new single commit are at least preserved in some way:
The first line is the main thing you want to focus on as this is what will be most visible in the commit history.
Use the Force, Luke.
Next up, you need to do a force push in git.
Yep... you heard me right. You can't just do a normal push because you've just rewritten the history on your branch and it's now different to what's in your origin/upstream repo.
It sounds scary as hell at first, but remember that you're about to merge your PR and hopefully delete this branch anyway. As long as you're careful to specify the name of the branch exactly, you should never mess things up.
All that being said, you do it by adding a
-f flag like so:
git push -f origin your-branch-name
The End Result
Now when you go back to your PR on GitHub and refresh the page, you should see your new commits:
Congratulations! You're now ready to hit the merge button and get your feature live and keep everyone else on the project happy with a much cleaner commit log.
A final word: When not to do this
In an ideal world, PRs would be kept short and easy to manage, but this isn't always the case. As such, here are a few times you might want to avoid squerging:
- There may be further changes on this branch.
- It's a long running branch that's gotten out of date.
- There have been multiple contributors and the history is somewhat convoluted.