How to squash commits
Content on WhatAnswers is provided "as is" for informational purposes. While we strive for accuracy, we make no guarantees. Content is AI-assisted and should not be used as professional advice.
Last updated: April 4, 2026
Key Facts
- Git squashing was popularized with Git 1.7.0 in 2010 as part of rebase improvements
- Use 'squash' (or 's') in interactive rebase to merge commits together
- Squashing is commonly done before merging feature branches into main branches
- Squashed commits retain all code changes while reducing commit clutter
- Only squash commits that haven't been pushed to shared repositories
What It Is
Git commit squashing is a version control technique that combines multiple sequential commits into a single, unified commit. When you squash commits, all changes from the individual commits are preserved, but the commit history becomes cleaner and more logical. This technique is essential in professional development where commit history serves as documentation of intentional code changes. Squashing helps prevent cluttered commit logs filled with 'fix typo' or 'oops forgot this' commits.
The squashing technique emerged as Git usage matured in the early 2010s, with developers recognizing that verbose commit histories hindered code review and debugging. Git 1.7.0, released in February 2010, introduced improvements to interactive rebase that made squashing straightforward. By 2015, squashing became standard practice in open-source projects and enterprise environments worldwide. Today, most popular projects require squashed commits in pull requests, making this skill essential for modern developers.
There are several squashing approaches: interactive rebase (`git rebase -i`), soft reset (`git reset --soft`), and specialized commands in platforms like GitHub. Interactive rebase is the most common method, allowing precise control over which commits to squash and in what order. Soft reset works well for squashing all uncommitted changes into a single commit without rewriting history. Different workflows and team preferences determine which method is most appropriate for specific situations.
How It Works
The squashing mechanism operates through Git's rebase functionality, which replays commits on top of a different base commit. When you run `git rebase -i HEAD~3`, you tell Git to prepare the last three commits for modification. Git opens an editor showing each commit with an action keyword like 'pick', 'squash', or 'reword'. You change 'pick' to 'squash' (or 's') for commits you want to combine, and Git merges them during the rebase process.
In a practical example, imagine a developer named Sarah working on a feature branch who made three commits: 'Add login form', 'Fix validation bug', and 'Update styling'. She runs `git rebase -i HEAD~3`, changes the last two commits from 'pick' to 'squash', and Git combines all three into a single 'Add login form' commit. The resulting commit contains all changes from the three original commits but appears as one logical unit in the repository history. This keeps the main branch's history clean and focused on feature completion.
To implement squashing, create a feature branch, make multiple commits during development, then before merging run `git rebase -i HEAD~n` where n is your commit count. In the interactive editor, keep the first commit as 'pick' and change subsequent commits to 'squash'. Git will prompt you to edit the combined commit message, allowing you to write a single comprehensive message. Finally, force-push the rebased branch (if it's your personal branch) or create a pull request with the squashed history.
Why It Matters
Clean commit histories are critical for code maintenance, with studies showing developers spend 23% of their time reading code and 17% understanding existing work. A squashed, well-organized commit history reduces the time needed to understand what changes were made and why. Version control systems that prioritize clear history enable faster debugging using `git bisect` to identify problematic commits. Google and Microsoft both report that clean commit histories directly correlate with reduced bug introduction rates in their codebases.
Enterprise development teams, open-source projects like Linux and Kubernetes, and companies like GitHub itself mandate squashed commits in pull requests. Netflix's microservices architecture requires each service's commits to tell a coherent story, necessitating aggressive squashing practices. Facebook's Sapienz automated testing relies on clear commits to correlate code changes with test failures. These industry leaders recognize that squashing is not optional overhead but essential infrastructure for maintainable software.
Future version control systems are moving toward even stricter commit standards, with some platforms automatically squashing pull requests by default. Conventional Commits, a specification gaining industry adoption, pairs perfectly with squashing to create semantically meaningful commit histories. AI-powered code review tools increasingly analyze commit messages to understand intent, making clear, squashed commits vital for automated analysis. As codebases grow larger, the importance of pristine commit history only increases.
Common Misconceptions
A widespread misconception is that squashing deletes or loses code changes. In reality, squashing only changes the commit history representation; all code changes are preserved exactly as they were. Git stores the combined code changes in the squashed commit, so functionality is never affected. This misunderstanding leads some developers to fear squashing, when in reality it's completely safe for rewriting local history.
Many developers believe they can safely squash commits that have already been pushed to shared repositories. This is dangerous because squashing rewrites history, causing conflicts for other developers who have based work on the original commits. The golden rule is to only squash commits on personal branches before sharing them. If you accidentally squash published commits, a force-push can correct this, but it's disruptive and should be avoided through proper workflow discipline.
Another myth is that squashing should always reduce commits to exactly one. In fact, best practice is to create 'logical commits' that represent coherent feature pieces. A single feature might warrant 2-3 squashed commits if they represent distinct, reviewable changes. The goal isn't minimal commits but rather clean, understandable history where each commit represents intentional progress. Teams should balance cleanliness with preserving meaningful separation of concerns.
Common Misconceptions
Why It Matters
How It Works
Related Questions
What's the difference between squashing and rebasing?
Rebasing replays your commits on a different base branch, updating your branch to include newer changes from the target branch. Squashing combines multiple commits into one within interactive rebase. You can rebase without squashing (keeping all commits) or squash without rebasing (combining commits on the same base).
What's the difference between squashing and rebasing?
Rebasing is a broader operation that replays commits on top of a new base, potentially reordering or modifying them; squashing is a specific rebasing action that combines multiple commits into one. You use git rebase to change commit order and content, and within that, you can squash to merge commits together. Rebasing is the tool, squashing is one application of it.
How do I squash commits that are already on my branch?
Run `git rebase -i HEAD~n` where n is the number of commits you want to squash. In the editor, change the action from 'pick' to 'squash' for all but the first commit. Save the editor and Git will combine them into one commit with a merged commit message.
Will squashing affect my teammates working on the same branch?
Yes, force pushing after squashing will cause conflicts for teammates pulling the old history. Squashing should only happen on personal feature branches before merging to shared branches, or use GitHub's 'Squash and merge' which handles it automatically. Coordinate with teammates if squashing a shared branch, or use pull request workflows to squash at merge time instead.
Can I undo a squash if I made a mistake?
Yes, Git stores references to recent commits in the reflog. Run `git reflog` to find the commit hash before squashing, then `git reset --hard <hash>` to restore it. This recovery window typically lasts 30 days, giving you ample time to undo accidental squashes.
Can I undo a squash if I make a mistake?
Yes, git reflog shows all your local operations including rebases, so you can reset to a previous state with git reset --hard before you pushed. If you already force-pushed, teammates need to be notified to rebase their work. Most teams prevent this by using protected branches and pull request reviews, which ensure mistakes are caught before squashing shared history.
More How To in Daily Life
Also in Daily Life
More "How To" Questions
Trending on WhatAnswers
Browse by Topic
Browse by Question Type
Sources
- Git - WikipediaCC-BY-SA-4.0
Missing an answer?
Suggest a question and we'll generate an answer for it.