Skip to main content

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 Merge

Squash 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 Merge

Merge and Squash Merge compared

AspectMergeSquash Merge
Commits added to the targetAll of the branch's commits, plus a merge commitOne new commit holding all the changes
Parents of the new commitTwo: the target branch and the merged branchOne: the previous commit on the target branch
HistoryComplete and branching; shows every stepShort and linear; one commit per change
Branch recorded as mergedYes; Git knows its commits are includedNo; the branch should be deleted afterward
Reverting the featuregit revert -m 1 on the merge commitA plain git revert of one commit
On the command linegit merge featuregit merge --squash feature, then git commit
Best forLong-lived branches and meaningful individual commitsSmall 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 main to have one reviewed commit per change.
  • You want to revert or find a feature as a single commit.

Merging a feature branch both ways

Mergebash
# 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 Mergebash
# 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 form

Readers 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.

More

Settings