We all do it, and I’m sure that you do too. You know, the rapid commits when you are testing something, then fixing a typo, then commit again, push, test and on and on.
I usually do it when I’m working on deployment or build code, positive that it’s just a tiny fix, one little modification and that’s it. So I commit with a meaningless message, push test and, see an error. Let’s call it BDD: Brute-Force Driven Development.
Now I’m left with a branch full of, well, embarrassing commits that are heading straight to a pull request and code review.
However, I do have a little trick up my sleeve that helps me push those changes like that 10x engineer on my team.
Use git squash. Other than looking smarter, you can keep the history of the branch cleaner and much more readable for others.
Git Squash
Squashing commits can be done in a few ways, where your end goal is to rewrite the commit history and leave just one commit instead of multiple meaningless ones. You can choose to leave the commit message history or rewrite that as well, so it’s another opportunity to communicate the changes you introduce.
git log - before
The best way to understand git squash is to look at the git log. In this example, I have a feature branch that has three commits.
* 510b129 (HEAD -> docker-rmi) missing flag
* cd62deb typo #2
* dba34d5 typo
* 46e95a5 Listing local docker images
* e30e77d (master) Starting the build process
* 9409666 Adding the build script
git log after
After performing a “squash”, the git log looks like this:
* 617c65c (HEAD -> docker-rmi) Listing all the local docker images
* 46e95a5 Listing local docker images
* e30e77d (master) Starting the build process
* 9409666 Adding the build script
It’s like we went back in time!
You can see that instead of all the “typo” commit messages and the missing flag, we now have just one commit message that includes all of the changes we made.
There are a few ways to squash commits, and I’ll show you two that cover different use cases. There is a wonderful thread on StackOverflow if you want to see more methods.
Squash on the same branch
When you want to alter the branch history, squashing a few commits back, the git reset --soft
command can come in handy.
WARNING - Make sure you don’t have uncommitted changes. Either commit or stash them before performing the reset command.
If you want to squash your last three commits run the command:
git reset --soft HEAD~3 && git commit
git reset --soft 46e95a5 && git commit
To push your changes, you have to use the –force flag, as you altered the branch history.
git push --force
Again, for more, see the link above to the StackOverflow thread.
Squash on merge
If you are a confident person and just want to keep the master (or any other) branch clean, you can use the git merge --squash
command. Most of the pull request UIs allow you squash merge as well.
git checkout master
git merge --squash featurebranch
By default, the commit includes all the original messages but, you can rewrite it as well. Your original branch keeps the original history, so that you can reference it.
Do this now
Like everything Git, knowing about the method adds another tool to your belt. But then again, there is always this “fear” of running commands for the first time on your existing codebase. So go ahead and create a clean git repo and try these methods out in a safe environment. Your hand will be less likely to shake once you see how it works on your own.