Squash Merge
In short
A squash merge combines all the commits from a branch into one new commit on the target branch, keeping the main history short and easy to read.
What is a squash merge?
A squash merge takes every commit on a feature branch and condenses them into a single commit that is added to the target branch, usually main. The final code is the same as with a regular merge, but the history shows one tidy commit per feature instead of every 'fix typo' and 'try again' step the developer made along the way.
On the command line, git merge --squash feature stages all of the branch's changes as if they were made in one go, and you then run git commit to record them with a single message. Most code hosting platforms offer a 'Squash and merge' option on pull requests that does the same thing and usually fills in the commit message from the pull request title. The new commit has only one parent, so Git does not record that the feature branch was merged.
Think of it like handing in the final draft of an essay instead of every rough draft: reviewers see the finished result, and the history stays readable. Many teams squash merge small and medium pull requests by default, because each commit on main then maps to one reviewed change, which makes it easy to revert a feature or trace when a bug appeared.
Squash merging is often confused with a regular merge and with rebasing. A regular merge keeps all the original commits and adds a merge commit with two parents, preserving full detail, while rebasing replays each commit on top of the target branch, rewriting them but keeping them separate. The main downside of squashing is lost detail: individual commits disappear from main, and because Git doesn't know the branch was merged, you should delete the branch afterward instead of continuing to work on it.
Key takeaways
- A squash merge turns all of a branch's commits into one commit on the target branch.
- It keeps the main branch history clean, with one commit per feature or pull request.
- The resulting commit has one parent, so Git does not record the branch as merged.
- The individual commits are not kept in the main branch history.
- Delete the feature branch after squash merging to avoid confusing conflicts later.
Example
# Switch to the branch that should receive the changes
git switch main
# Stage all changes from the feature branch as one combined change
git merge --squash feature/login
# Record them as a single commit
git commit -m "Add login page"
# Delete the branch; -D is needed because Git does not see it as merged
git branch -D feature/loginReaders ask
What is the difference between a squash merge and a rebase merge?
A squash merge combines all of a branch's commits into one new commit, while a rebase merge replays each commit individually on top of the target branch. Both produce a linear history, but only rebasing keeps every commit separate.
Is squash merging a good practice?
It is a popular choice for teams that want a clean main branch where each commit is one reviewed pull request. It is less suitable when each commit in a branch is carefully crafted and meaningful on its own, because that detail is lost.
Can you undo a squash merge?
Yes. Because the whole feature lands as one commit, you can undo it with a single git revert <commit>, which creates a new commit that reverses those changes.
See also
- MergeVersion Control, p. 29A merge in Git combines the changes from one branch into another, joining separate lines of development back together into a single, shared history.
- CommitVersion Control, p. 5A commit is a saved snapshot of a project's files in Git, recorded with a unique ID, an author, a timestamp, and a message describing what changed.
- RebaseVersion Control, p. 33A rebase in Git replays a branch's commits on top of another commit, rewriting history to produce a cleaner, linear sequence of changes without merge commits.
- Pull RequestVersion Control, p. 32A pull request is a proposal to merge changes from one branch into another, giving teammates a place to review, discuss, and test the code before it is merged.
- BranchVersion Control, p. 2A branch in Git is an independent line of development that lets you work on a feature or fix in isolation, without affecting the main code until you merge it.
- Code ReviewVersion Control, p. 4A code review is the practice of having other developers check code changes before they are merged, to catch bugs, improve quality, and share knowledge.
Spotted a mistake or something missing on this page?Suggest an edit