rebase vs merge: When to Use Which
The Trade-off Between Preserving and Linearizing History
Both can produce identical final files. The difference is the shape of the history.
merge
Creates a new commit (merge commit) that joins two branches. The original commits stay. Branching and converging show up in the graph as-is.
rebase
Takes your branch's commits, detaches them, and replays them on top of another branch (usually main). The originals are discarded; new commits with new hashes are created.
The core rule
Don't rebase shared branches. If someone else has pulled those commits, rebasing changes their hashes and breaks their history. This is the Golden Rule of Rebase.
Personal feature branches are cleaner when rebased onto main. Running git rebase main before opening a PR keeps the reviewer's diff minimal.
squash merge
GitHub's 'Squash and merge' button collapses all PR commits into one before merging into main. Main stays clean, but per-commit context is lost. It's a trade-off.
How It Works
merge: `git checkout main && git merge feature` -> creates merge commit
rebase: `git checkout feature && git rebase main` -> replays feature commits on top of main
interactive rebase: `git rebase -i HEAD~5` -> squash/edit/reorder commits
On conflict: resolve then `git rebase --continue`, or `git rebase --abort`
Pros
- ✓ merge: preserves original history, safe
- ✓ rebase: linear history, easier to review
Cons
- ✗ merge: accumulating merge commits clutters the graph
- ✗ rebase: disastrous on shared branches, requires force push