Last Updated: January 3, 2026
Squashing allows you to combine multiple commits into a single cohesive commit, significantly streamlining your project history. This is particularly useful for cleaning up the commit log before merging branches or when you want to create a more readable project history.
Understanding how to effectively squash commits not only simplifies your Git history but also helps in maintaining clarity and coherence in collaborative projects.
At its core, commit squashing is the process of taking several commits and condensing them into a single commit. This can be particularly beneficial for:
When you squash commits, the resulting commit combines the changes from each commit being squashed, and you can provide a single, descriptive commit message that summarizes the collective changes.
Git provides a straightforward way to squash commits through interactive rebasing. Here, we'll outline the steps to perform this operation effectively.
To squash commits using interactive rebase, follow these steps:
First, determine how many commits you want to squash. You can do this by running:
This command gives you a concise view of your commit history.
Once you've identified the base commit (the commit before the first commit you want to squash), initiate the interactive rebase. For example, to squash the last three commits, you would run:
After you run the above command, Git opens your default text editor, showing a list of commits. The first commit will be marked as "pick", while the others will be listed below it. To squash commits, change "pick" to "squash" (or simply "s") for the commits you want to combine:
After making your changes, save the file and close the editor. Git will then combine the selected commits into the first one.
Finally, Git will prompt you to edit the commit message for the new squashed commit. You can choose to keep the existing messages or write a new one that summarizes the changes.
After saving your new commit message, the rebase completes, and your commit history is now cleaner.
To fully appreciate commit squashing, it's essential to understand what happens to your Git history and the underlying object model during the process.
Each commit in Git is represented as an object that contains:
When you squash commits, you create a new commit object that references the same tree objects as the squashed commits but with a new commit message. The original commits remain in the repository's history until they are garbage collected.
Consider this simple scenario where we have three commits:
Here, commit C is the latest, and you want to squash it with commits A and B. After squashing, the history will look like this:
In this representation, commit D contains the combined changes of commits B and C, with a new message that reflects the overall changes.
Squashing commits can be particularly useful in various scenarios:
When working on a feature branch, developers often make numerous small commits to track progress. Before merging this branch into the main branch, squashing these commits into a single one provides a clearer presentation of what the feature accomplishes.
For example, imagine you are working on a feature that adds user authentication. You might have several commits, such as:
Squashing these into a single commit titled "Implement user authentication" offers a cleaner and more informative history.
Before submitting code for review, squashing commits can help reviewers focus on the essential changes instead of getting lost in incremental updates. A single commit often gives a better context for reviewing the functionality that has been added or modified.
In team environments, squashing commits helps maintain a neat and organized project history. It reduces the noise from personal commits that may not be relevant to others and allows the team to focus on key features and bug fixes.
While squashing commits is beneficial, it’s important to bear in mind certain nuances that can impact your workflow.
Squashing can lead to a loss of detailed history. If your commits contain meaningful messages that describe incremental changes, you may want to retain those instead of squashing them all together. Always assess whether the details lost in squashing are important for future reference.
If there are conflicts when squashing commits, Git will pause and ask you to resolve them. After resolving the conflicts, you need to mark them as resolved with:
Then continue the rebase with:
This process introduces additional steps, making it essential to be diligent when squashing commits with potential conflicts.
The interactive rebase interface can become unwieldy if you are squashing a large number of commits. In such cases, consider breaking down your squashing into smaller groups or using tools that can automate parts of the process.
Now that you understand how to squash commits and the benefits it brings to your Git workflow, you are ready to explore reordering commits.
In the next chapter, we will look at how to arrange your commits in a meaningful way to further enhance your project's history and coherence.