Introduction
Before we start talking about how to squash commits in git, let's briefly understand-What is Squash ?
In Git, the term "squash" refers to the consolidation of several commits into a single one. Git's "Interactive Rebase" functionality allows you to do this at any moment, however, while merging branches is the most common time to do so.
Squashing commits in Git allows you to combine multiple commits into a single, cleaner commit. Squashing commits helps maintain a clean and concise commit history.
This tutorial will walk you through the process of squashing commits in Git.
When to Squash Your Commits
As was previously stated, "squashing" refers to the act of combining numerous existing commits into a single one. To some extent, whether you should do this or not depends on your preferences. For instance, in some teams, squashing commits is the preferred method of merging a feature branch back into a long-running branch like "master" or "main".
But why would you do that? Consider the typical scenario of a feature development. You likely worked on a separate feature branch and made several commits in this situation. Depending on how complicated and time-consuming your task is, there may even be a significant number of commits. You should eventually merge your changes back into the main branch. Usually, at this point, you'll determine whether to squash or not:
(a) All of those independent commits from your feature branch will be consolidated into a single commit if you choose to squash before merging. Hence, there will be just one commit for this integration in the main commit history.
(b) All of your individual commits will remain intact if you opt NOT to squash them.
Some teams believe that choosing option (a) and employing squash has a benefit because the main commit history just contains one commit, as opposed to numerous separate ones that might be unneeded and perhaps overwhelming. This can help keep things in order!
Therefore, you cannot claim that option (a) or option (b) is the "right" course of action. Both methods have advantages and disadvantages, so it primarily comes down to personal preference and custom.
How to Squash Your Commits
When it comes to squashing commits, there are several techniques and tools. In this tutorial, you will learn two main ways to squash commits: Interactive Rebase and Merge.
Interactive Rebase
With the "Interactive Rebase" feature of Git, you can manually squash your commits whenever you like. We won't dive into the details of Interactive Rebase in this post, but you can find some free, introductory videos on the subject in the First Aid Kit for Git. So, let's work through a basic example case.
Say you've finished working on a new feature branch, "feature/login" in the example below, and you want to merge it back into the "main" branch. But first, you'd like to tidy up and squash the latest commits into one:
Start an interactive rebase session to achieve this:
git rebase -i HEAD~3
The selected part of your commit history can then be modified in an editor window that opens up. Although Interactive Rebase enables you to conduct a wide range of operations on your commit history, in this example, we're only concerned with the "squash" action keyword. In the event that you designate one or more lines as "squash," they will be added to the preceding line:
The Interactive Rebase is finished after entering a commit message for the new, combining commit, which merges the three previous commits into one.
Using Interactive Rebase in Tower: If you're using the Tower Git client, squashing some commits with Interactive Rebase is quite easy: simply right-click any of the commits you want to combine, and choose the "Squash Revisions..." option from the contextual menu.
Merge
When merging branches, there is also the option of squashing:
git merge --squash feature/login
Auto-merging imprint.html
Removing img/iconBlog.png
Auto-merging about.html
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested
The outcome is pretty similar to what we've just discussed: all changes will be integrated exactly as with a normal merge, but with the --squash
, instead of a merge commit being automatically created, you're left with local changes in your working copy that you can then commit yourself.
In the end, you are able to prevent the automatic commit that ordinarily follows a merge. It will seem as though your feature's development was completed in just one commit.
Pull Requests
When a Pull Request is closed, the technique of employing squash when merging is frequently used. When merging a Pull Request, code hosting services such as GitHub, GitLab, or Bitbucket enable this as an option.
FAQs to Squash Commits in Git
Why should I squash commits?
Squashing commits can provide a cleaner commit history by reducing the number of commits and making the repository history easier to understand and navigate.
How do I squash commits using Git rebase?
Start by using the git rebase -i <commit>
command, where <commit>
is the commit hash or reference before the commits you wish to squash. In the interactive rebase editor, change pick
to squash
or s
for the commits you want to squash.
Can I squash multiple commits at once?
Yes, during the interactive rebase, mark multiple commits as squash
or s
to squash them into a single commit. Git will prompt you to provide a new commit message or create one by combining the original commit messages.
What if I want to modify the commit message while squashing?
In the interactive rebase editor, change pick
to reword
or r
for the commit you want to modify. Git will prompt you to edit the commit message during the rebase process.
Can I undo a commit squash operation?
If you squash commits and later decide to undo the squash operation, you can use git reflog
to find the commit hash before the squash operation and then use the git reset <commit>
command to revert to that state.
Can I squash commits across multiple branches?
Yes, you can use the interactive rebase on a specific branch and squash commits as desired. However, it's essential to consider the impact on other developers working on the same branch or merges into the branch.
Can I squash commits that have already been pushed to a remote repository?
Yes, you can squash commits even after they have been pushed to a remote repository. However, you'll need to use git push --force
to overwrite the existing remote branch with the rewritten branch history.
Conclusion
In this tutorial, you learned two different ways to squash commits: using Interactive Rebase and Merge. If you have any suggestions or queries, kindly leave them in the comments section.