DEV Community

Cover image for Hide your shameful commits with Git Squash
Yuval Oren
Yuval Oren

Posted on • Originally published at pushbuildtestdeploy.com

Hide your shameful commits with Git Squash

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.

Real Git log from one of my projects

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!
Are you tellimg me you built a time machine?

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

Also if you want to squash to a specific 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.

Want to learn more?
Head over to my signup page and never miss a post

Top comments (0)