๐Ÿ”€

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

1

merge: `git checkout main && git merge feature` -> creates merge commit

2

rebase: `git checkout feature && git rebase main` -> replays feature commits on top of main

3

interactive rebase: `git rebase -i HEAD~5` -> squash/edit/reorder commits

4

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

Use Cases

merge: integrating official team branches (main <- develop, main <- release) rebase: cleaning up personal branches before opening a PR squash: collapsing small fixup commits to keep main history clean

References