Git Merge vs Rebase

Pick an operation. Watch what actually happens to your commits.

main
feature
merge commit
rebased commit
Initial state
main feature
Starting state: main is at commit C. feature has commits D and E, both branched from B. main has advanced (added C) since the branch was created — they have diverged.
The key difference

Both operations put feature's changes into main. The difference is history. Merge preserves the branching point — you can always see feature diverged from B. Rebase rewrites history — commits D and E get new SHAs as D' and E', as if they were always based on C. Neither is wrong; they serve different purposes.

git merge feature

  • Creates a new merge commit
  • Preserves full branch history
  • Non-destructive — never rewrites
  • Safe for public/shared branches
  • History shows parallel work

git rebase main

  • Replays commits on new base
  • Linear history — no fork point
  • Feature commits get new SHAs
  • Cleaner for local feature branches
  • Never rebase shared branches
Golden rule: Never rebase commits you've already pushed to a shared branch. When you rebase, commits get new SHAs — anyone who pulled the old commits will have divergent history and a painful merge ahead.

Common questions

Why do rebased commits get new SHA hashes?
A commit's SHA is computed from its content AND its parent's SHA. When you rebase, D's new parent is C instead of B — so D's SHA must change even though the code diff is identical. This is the precise meaning of "rewrites history": same work, new identity.
What exactly is a merge commit?
A merge commit has two parents — in this example, C and E. It's the point where two lines of history were joined. git log --graph shows both lines converging into M. The merge commit is permanent evidence that parallel work happened and was combined.
Can I fast-forward merge when branches have diverged?
No. Fast-forward only works when no new commits exist on the base since the branch was created. Here, main added C after the branch was created — so a fast-forward is impossible. You must either create a merge commit, or rebase first and then merge with --ff-only.
What does git pull --rebase do?
Instead of merging the remote's new commits into your local branch (creating a merge commit), it rebases your local commits on top of the remote's. History stays linear. Useful on branches with active collaboration where merge commits would clutter the log.
When should I use merge vs rebase?
Use merge for integrating public/shared branches — it's non-destructive. Use rebase to clean up a local feature branch before a PR — linear history is easier to review. The simplest rule: rebase branches you haven't pushed; merge everything else.
What is interactive rebase (git rebase -i)?
git rebase -i HEAD~N opens an editor where you can squash commits (combine multiple into one), reword commit messages, drop commits, or reorder them. Standard practice before opening a PR: squash your six "WIP" commits into two clean, logical units that tell the story of the change.