Home/Learn/Git/Merge vs Rebase — When to Use Which

Merge vs Rebase — When to Use Which

Intermediate
Intermediate

Merge preserves true history with a merge commit; rebase replays commits onto a new base for a clean linear history. The golden rule: never rebase commits that have been pushed to a shared branch.

Overview

The merge-vs-rebase debate is one of the most discussed topics in Git. Neither is universally better. Merge preserves the exact history of how work was integrated — useful for auditing, especially in open-source projects. Rebase rewrites history to appear as if the feature was developed on top of the latest main — producing a clean, linear history that is easier to read with git log and bisect. The key constraint: rebase rewrites commit hashes. If you rebase commits others have already based work on, you create parallel histories that must be force-pushed and confuse teammates.

Merge — Preserves True History

git merge creates a merge commit that joins two lines of development. The history shows exactly when branches diverged and when they were integrated. Preferred for integrating into long-lived branches (main, develop) and open-source projects where accurate history is valued.

Merge — preserving branch history
//  BEFORE MERGE
//
//  main:    A ── B ── E ── F
//                â””── C ── D  ← feature/cart
//
//  git switch main
//  git merge feature/cart
//
//  AFTER MERGE
//
//  main:    A ── B ── E ── F ── M   ← merge commit
//                â””── C ── D ───┘
//
//  The merge commit M has TWO parents: F and D
//  History clearly shows the branch existed

git switch main
git merge feature/cart
git log --oneline --graph
# *   a3f8c12 Merge branch 'feature/cart'
# |# | * 7b2e441 Add cart animation
# | * 3d9f2e0 Implement cart data structure
# * | 9c1a8b7 Fix checkout bug
# |/
# * 1a2b3c4 Initial commit

Rebase — Rewrites for Linear History

git rebase moves commits from one branch, replays them on top of another. Each replayed commit gets a NEW hash — it is literally a new commit with the same changes but a different parent. The result is linear history as if you developed the feature directly on top of main.

Rebase — clean linear history
//  BEFORE REBASE
//
//  main:    A ── B ── E ── F
//                â””── C ── D  ← feature/cart (branched at B)
//
//  git switch feature/cart
//  git rebase main
//
//  AFTER REBASE
//
//  main:    A ── B ── E ── F
//                          â””── C' ── D'  ← feature/cart
//
//  C' and D' are NEW commits (new SHA-1) with same changes
//  as C and D, but parent is now F instead of B

# Rebase feature branch onto main
git switch feature/cart
git rebase main

# Resolve any conflicts that arise
git add <resolved-files>
git rebase --continue   # move to next commit
git rebase --abort      # cancel and return to original state

# After rebase, merge back to main (will fast-forward)
git switch main
git merge feature/cart  # ← fast-forward, no merge commit
git log --oneline       # perfectly linear

The Golden Rule of Rebasing

Never rebase commits that exist in the remote shared branch. When you rebase, the original commits still exist until garbage collected — if teammates pulled them, they now have "orphaned" commits that conflict with your rewritten history. This is the main source of "I messed up Git" disasters.

The golden rule of rebasing
// ❌ DANGEROUS — rebasing commits already on shared branch
//
//  Remote main: A──B──C
//  Alice pulled C. Bob has been working on top of C.
//
//  You do: git rebase main (rewrites B → B', C → C')
//  You do: git push --force origin main
//
//  Now Alice and Bob have commits pointing to the OLD C
//  which no longer exists in the "official" history.
//  They must re-sync manually. Confusion ensues.

// ✅ SAFE — rebase only local, unshared branches
git switch feature/my-feature   // ONLY you have this branch
git rebase main                  // rewrite it safely
git push -u origin feature/my-feature  // first push, no problem

// Rule of thumb:
// - Rebase your feature branch ONTO main/develop (before PR)
// - Merge feature INTO main/develop (after PR approval)
// - Never rebase main, develop, or any branch teammates use

Key Points to Remember

  • 1Merge creates a merge commit and preserves true history — you can see when and how branches were integrated
  • 2Rebase replays commits with new hashes onto a new base — produces linear history, easier to read
  • 3Golden rule: NEVER rebase commits that have been pushed to a shared/remote branch
  • 4Typical workflow: rebase feature onto main before PR, then merge (or squash merge) PR into main
  • 5git rebase --abort undoes an in-progress rebase completely — safe escape hatch

Interview Questions

Sign in to ask Aria
1

What is the difference between git merge and git rebase?

Medium
2

Why is rebasing shared branches dangerous?

Medium
3

When would you choose merge over rebase and vice versa?

Hard
4

What is a "squash merge" and when is it used?

Hard

Ask Aria about Merge vs Rebase — When to Use Which

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…