Squashing and rebasing both rewrite git history, and both get lumped together as "the scary git commands," but they solve different problems. Squashing collapses multiple commits into one. Rebasing replays commits onto a new base. You can squash without rebasing, rebase without squashing, or do both at once — understanding the difference stops you from reaching for the wrong one under pressure.
What changed in 2026
- GitHub, GitLab, and Bitbucket all now default new repositories to "squash and merge" for pull requests, making squash-on-merge the norm rather than something teams configure manually.
- Interactive rebase tooling in editors (VS Code, JetBrains IDEs) got substantially better visual diffs, reducing the historical fear of
git rebase -i for junior developers.
git rebase --update-refs matured, making it far safer to rebase a stack of dependent branches at once without breaking the stack.
What squashing does
Squashing combines several commits into a single commit, discarding (or folding into one message) the intermediate history. If you made five small "wip" commits while building a feature, squashing turns them into one clean commit before it lands on the main branch. The individual commit messages are gone; only the net change and a summary message remain.
What rebasing does
Rebasing takes a sequence of commits and replays them on top of a different base commit — typically the latest version of the main branch. This makes your branch look as if you had started your work from the current tip of main, producing a linear history without merge commits. Interactive rebase (git rebase -i) additionally lets you reorder, edit, drop, or squash commits during the replay.
Squash vs rebase vs merge
| Action |
What it does to history |
Best for |
git merge |
Adds a merge commit joining two histories |
Preserving exact history, shared long-lived branches |
git rebase |
Replays your commits onto a new base, linear history |
Cleaning up a branch before merging, keeping history linear |
git squash (merge --squash or interactive) |
Collapses many commits into one |
Turning messy WIP commits into one reviewable commit |
| Squash and merge (PR button) |
Combines rebase-like linearity with squash into one commit on merge |
Team default for keeping main branch history readable |
When to use which
Rebase your own feature branch onto main before opening a pull request, so reviewers see a clean, current diff. Use squash — either via interactive rebase or the platform "squash and merge" button — when your commit history has noisy, non-meaningful intermediate commits. Clean, rebased history also makes automated tools like AI code review tools more effective, since they are reviewing one coherent diff instead of five WIP commits. Avoid rebasing a branch that other people have already pulled and built on top of; rewriting shared history forces everyone downstream to reconcile diverged commits, which is the single most common way rebase causes real damage.
Common mistakes
- Rebasing a shared branch. If someone else has pulled your branch, rebasing rewrites commit hashes and breaks their local history. Coordinate or avoid it entirely on shared branches.
- Squashing away meaningful history. If individual commits represent genuinely separate, revertable changes, squashing them into one commit makes future
git revert and git bisect less precise.
- Force-pushing without
--force-with-lease. A plain git push --force after a rebase can silently overwrite commits made by someone else; --force-with-lease fails safely if the remote has changes you have not seen.
- Confusing rebase with merge conflict resolution. Both can produce conflicts, but resolving a rebase conflict happens per-commit as history replays, which can mean resolving the same conflict multiple times for a long-lived branch.
FAQ
Does squashing lose my commit history forever?
On the branch, yes — the intermediate commits are gone after squashing. The original commits still exist in git reflog for a limited time, but functionally, treat a squash as permanent once merged.
Is squash and merge the same as git rebase?
No, though they produce a similar-looking linear result. Squash and merge always creates one new commit; rebase replays your existing commits (possibly many) onto a new base without necessarily combining them.
Why does my team default to squash and merge on pull requests?
It keeps the main branch history readable — one commit per feature or fix, regardless of how many WIP commits happened during development. It also simplifies rollbacks: reverting one PR is one git revert.
Can I undo a rebase if I make a mistake?
Usually yes, via git reflog to find the commit hash before the rebase and git reset --hard <hash> to return to it, as long as you act before garbage collection clears the reflog.
Where to go next