Git Rebase vs Merge — When to Use Each (2026 Guide)
The real difference between git rebase and git merge, when to pick each, the golden rule (never rebase public commits), and how to recover when things go sideways.
"Should I merge or rebase?" is the most-argued Git question ever. Short answer: merge to integrate someone else's history into yours; rebase to reshape your OWN history before sharing it. Long answer below.
What each command actually does
Merge
git checkout feature
git merge main
Creates a NEW commit (the "merge commit") whose parents are the tips of both branches. The full history of both branches is preserved. Non-linear — you'll see branch shapes in the graph.
Rebase
git checkout feature
git rebase main
Takes every commit that's on feature but not on main, then REPLAYS them one at a time on top of main. The old commits are thrown away; new ones with different SHAs take their place. History looks linear — as if you'd started your feature from today's main.
Side-by-side comparison
| Merge | Rebase | |
|---|---|---|
| History shape | Non-linear (branching graph) | Linear (straight line) |
| Preserves commit SHAs | Yes | No — rewrites them |
| Preserves timestamps | Yes | Yes (AuthorDate) / No (CommitDate) |
| Safe on shared branches | Yes | NO — never rebase public commits |
| Conflict resolution | Once, at the merge | Potentially once per commit replayed |
| Reverting | Easy (revert the merge commit) | Harder (revert each replayed commit) |
| Bisect (git bisect) | Works, sometimes sees merge chaos | Cleaner — every commit builds standalone |
The golden rule
Never rebase commits that have been pushed to a shared branch anyone else is using. Rebasing rewrites SHAs, and anyone with the old SHAs will have a corrupted view of history until they manually reset. If you rebase and force-push a shared branch, you WILL make someone else angry.
When to rebase
- Before opening a PR —
git rebase mainon your feature branch so your PR is a clean "these commits added feature X on top of current main" - Cleaning up local commits —
git rebase -i HEAD~5to squash, reorder, or reword before pushing - Keeping a long-lived feature branch current — periodically rebase onto main to avoid a massive merge conflict at the end
When to merge
- Integrating a completed feature into main — merge preserves the fact that this work happened as a unit
- Anything on a shared branch — always merge; never rebase
- When you want an easily-revertable unit — one merge commit reverts cleanly
Three main workflows in the wild
1. Merge everything ("git flow" purists)
Every feature branch merges into main with --no-ff to force a merge commit. History is a graph. Preserved forever.
2. Squash and merge (GitHub default)
Feature branch commits are squashed into ONE commit that lands on main. Simple linear history on main; ugly WIP commits from the branch are lost.
3. Rebase and merge
Feature branch is rebased onto main, then fast-forwarded. Linear history that keeps every commit. This is what most disciplined teams settle on.
Recovering from a bad rebase
If you rebased and things went wrong, git reflog is your friend. Every rebase move is recorded. Find the SHA before the rebase, then git reset --hard <that-sha>. Yes even after a force push — as long as no one else fetched during the window, you can restore the old branch.
git reflog
# find the SHA before the rebase
git reset --hard HEAD@{5}
Interactive rebase — the power tool
git rebase -i HEAD~5
Opens an editor with the last 5 commits. Change pick to:
reword— change the commit messageedit— pause here so you can amend the diffsquash— combine with the previous commit, keep both messagesfixup— combine with the previous commit, DROP this messagedrop— remove this commit entirely
Reorder the lines and Git will replay commits in the new order. If a replay conflicts, resolve it, git add ., git rebase --continue.
Related
Git Cheat Sheet · Diff Checker to inspect what a merge or rebase actually changed.
Featured Tools
Try these free related tools directly in your browser — no sign-up required.
Diff Checker
Compare two texts or code files side by side and highlight differences. Find added, removed, and changed lines instantly with colour-coded diff output.
JSON Formatter
Format, beautify, and validate JSON instantly. Paste raw JSON and get a clean, indented, human-readable output with syntax error detection.