Rebase vs Merge

Updated

October 30, 2026

The Debate: Rebase vs Merge

After this page you can pick a default for desk-api and know what you are giving up.

Same trees, different graphs

Both operations can produce a working tree that contains both sides of the work. Merge records a join. Rebase copies a chain.

 start                         after merge

 A ← B ← C ← G   main          A ← B ← C ← G ← M   main
      ↑                             ↑          ↑
      D ← E      feat               D ← E      feat

 start                         after rebase feat onto main

 A ← B ← C ← G   main          A ← B ← C ← G          main
      ↑                                      ↖
      D ← E      feat                          D' ← E'  feat
Merge Rebase
Hashes of your old commits Unchanged New
Extra commit Often a merge commit None if you fast-forward after
Conflicts Once, at the join Once per copied commit
Safe on published main Yes Usually no
Safe on your unpushed feature Yes Yes, and often cleaner

A default that scales

  • Feature branch you own: rebase onto main, then fast-forward main (or open a pull request that the forge squash-merges).
  • main / shared long-lived branch: merge or fast-forward only. Do not rebase commits other people have.
  • Hotfix already on main: revert (chapter 10), do not rebase main.

Forges add a third option: squash merge (many commits become one on main). That is a server-side rewrite. Chapter 15 and chapter 31. Locally, rebase is how you squash before you push.

rerere, tests, Linux

Run the test command you actually have after every --continue. On Linux that is whatever desk-api uses (python -m pytest, a shell script, make test). Rebase does not run tests for you.

You can mix

Rebase the feature. Merge into main with --no-ff if the team wants a join node for git log --first-parent. That is Git Flow’s “feature into develop” shape. Trunk-based skips the join and fast-forwards.

There is no global winner. There is a default per branch class. Write it down in the repo (chapter 15). The hands-on page next squashes a messy feature on Linux.