Side by side
MergevsSquash Merge
What is the difference between a merge and a squash merge?
Updated 3 min read7 differences
In short
A regular merge keeps every commit from a branch and joins it with a merge commit; a squash merge folds all of the branch's commits into one new commit.
Merge
A merge in Git combines the changes from one branch into another, joining separate lines of development back together into a single, shared history.
Read the page on MergeSquash Merge
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.
Read the page on Squash MergeMerge and Squash Merge compared
| Aspect | Merge | Squash Merge |
|---|---|---|
| Commits added to the target | All of the branch's commits, plus a merge commit | One new commit holding all the changes |
| Parents of the new commit | Two: the target branch and the merged branch | One: the previous commit on the target branch |
| History | Complete and branching; shows every step | Short and linear; one commit per change |
| Branch recorded as merged | Yes; Git knows its commits are included | No; the branch should be deleted afterward |
| Reverting the feature | git revert -m 1 on the merge commit | A plain git revert of one commit |
| On the command line | git merge feature | git merge --squash feature, then git commit |
| Best for | Long-lived branches and meaningful individual commits | Small pull requests with messy work-in-progress commits |
The difference, explained
Both bring a finished branch into a target branch such as main, and both leave the same final code. A regular merge keeps every commit from the branch and, when both branches have moved on, adds a merge commit with two parents. A squash merge takes all of the branch's changes and records them as one new commit, with a single parent, on the target branch.
The difference is what the history remembers. After a regular merge, git log shows every step the developer took and exactly where the branch split off and came back. After a squash merge, main shows one commit per pull request, which is easy to read, revert and search with git bisect, but the individual commits and the link to the branch are gone from it.
Code hosting platforms offer both on pull requests, often as 'Create a merge commit' and 'Squash and merge', and many teams pick one per repository. Squashing suits small, focused pull requests full of 'fix typo' commits; a regular merge suits long-lived branches, or branches whose commits were carefully written to stand on their own. Because Git doesn't record a squashed branch as merged, delete it afterward: building on it again leads to duplicate changes and conflicts.
A common misconception is that squashing throws work away. The code is all there, and the platform usually keeps the original commits in the pull request; only the target branch's history is condensed. Another is that a regular merge always adds a merge commit: if the target branch hasn't changed, Git simply fast-forwards it, unless you pass --no-ff.
Which one should you use?
Choose Merge when…
- Each commit on the branch is meaningful and worth keeping on its own.
- The branch is long-lived or shared, and others build on it.
- You want an exact record of how the work was done.
Choose Squash Merge when…
- Pull requests are small and their commits are mostly work in progress.
- You want
mainto have one reviewed commit per change. - You want to revert or find a feature as a single commit.
Merging a feature branch both ways
# Regular merge: keep every commit, add a merge commit
git switch main
git merge --no-ff feature
git log --oneline --graph
# * Merge branch 'feature'
# |\
# | * Fix typo in signup form
# | * Add signup form
# |/# Squash merge: stage all the changes, commit them once
git switch main
git merge --squash feature
git commit -m "Add signup form"
git branch -D feature # Git doesn't see it as merged
git log --oneline
# * Add signup formReaders ask
Is squash merging bad practice?
No, it is a common default for teams that want one commit per pull request. It is a poor fit only when individual commits carry meaning that should stay in the target branch's history.
Can I still see the original commits after a squash merge?
Usually, yes: in the pull request on the hosting platform, and on the branch until it is deleted. They are just not part of the target branch's history.
Why does Git say my branch is not merged after a squash?
Because the squash commit has a single parent and no link to the branch's commits. Git compares commits, not content, so delete the branch with git branch -D once you've confirmed the changes are in.