IAnswerable

Rebase or Merge: Pick One and Move On

13 Mar 2026

Rebase your feature branch before you open the PR. Merge the PR into main with a merge commit. That’s the rule. Stop arguing about it.

Why this ends the debate

The rebase-vs-merge fight is really two different questions people conflate: “how do I clean up my branch” and “how do I integrate into main.” Answer them separately and the argument dissolves.

On your branch, before review: rebase onto main. Squash your “wip”, “fix typo”, “actually fix it” commits into something coherent. Nobody reviewing your PR wants to see your thought process; they want to see the change.

git fetch origin
git rebase -i origin/main

Merging into main: use a merge commit, or better, your host’s “squash and merge” button. Never rebase main itself, and never force-push to a shared branch.

Why not rebase everywhere

Rebase rewrites history. That’s fine on a branch only you push to. It’s a disaster on a branch other people have pulled — they rebase too, get diverging histories, and someone ends up force-pushing over someone else’s work. If two people are on the same feature branch, merge, don’t rebase.

Why not merge everywhere

A merge commit for every tiny commit on your branch turns git log --oneline on main into noise: fifteen “fix lint”, “address review comment”, “oops” commits mixed into fifty real changes. Six months later, git bisect and git blame are wading through commits that were never meant to stand alone.

The rule, concretely

  1. Work on your branch however you want. Commit garbage. Nobody cares.
  2. Before opening the PR (or before merging, if review comments added more commits): git rebase -i origin/main, squash into 1-3 logical commits with real messages.
  3. Merge to main via squash-merge or a merge commit — pick whichever your team already uses, don’t relitigate it. Never fast-forward-only if you want a record of what shipped as a unit.
  4. Never rebase a branch other people have based work on. Never force-push main.

The gotcha

git rebase -i origin/main on a branch that’s already been pushed means your next push needs --force-with-lease, not --force:

git push --force-with-lease

--force-with-lease refuses if someone else pushed to that branch since you last fetched. Plain --force overwrites blind. If you’ve ever force-pushed over a teammate’s commit, this is the flag that would have stopped you.

When someone insists on “always merge, never rebase”

That’s a defensible team rule too — some teams want the exact chronological record, warts and all. It’s worse for git bisect and git log readability, but it’s consistent, and consistent beats optimal. The failure mode is a team with no rule, where half the PRs are rebased, half are merged, some branches get force-pushed and break other people’s checkouts, and every PR review starts with “wait, why does this branch have forty commits.”

Pick rebase-to-clean / merge-to-integrate, write it in your CONTRIBUTING file in one sentence, and move on. The argument costs more engineering time than either choice does.