The Hook (The "Byte-Sized" Intro)
This is the Git holy war: merge vs rebase. Teams have argued about it, blog posts have been written, and Linus Torvalds himself has strong opinions. The truth? Both are useful. Merge preserves history as it actually happened. Rebase rewrites history to make it look like it happened linearly. Choosing the right one depends on the situation, and knowing both makes you dangerous.
📖 What is Rebase vs Merge?
Both combine work from one branch into another, but they do it differently:
- Merge creates a new "merge commit" that ties two histories together → history looks branched
- Rebase replays your commits on top of another branch → history looks linear
Conceptual Clarity
Merge: preserving reality
Before: A - B - E (main)
\
C - D (feature)
After: A - B - E - F (main) ← F is the merge commit
\ /
C - D
Rebase: rewriting history
Before: A - B - E (main)
\
C - D (feature)
After: A - B - E - C' - D' (feature)
↑
(C and D replayed on top of E with new hashes)
| Aspect | Merge | Rebase |
|---|---|---|
| History | Preserves real timeline (branched) | Creates linear timeline (clean) |
| New commit? | Yes — merge commit with two parents | No — replays existing commits |
| Commit hashes | Original hashes preserved | New hashes (commits are recreated) |
| Conflict resolution | Once, in the merge commit | Potentially once per replayed commit |
| Safe on shared branches? | ✅ Yes | ❌ No — rewrites history |
| Best for | Integrating feature branches into main | Keeping feature branches up-to-date |
Real-Life Analogy
- Merge = Two rivers joining at a confluence. Both rivers' histories are visible — you can trace them back separately.
- Rebase = Cutting a section of river and transplanting it downstream so it looks like it always flowed from that point. Cleaner, but the original flow path is erased.
Visual Architecture
Why It Matters
- Merge is the safe default — it never rewrites history, never causes problems on shared branches.
- Rebase makes
git logbeautiful — a clean, linear story without merge-commit clutter. - The golden rule: Never rebase commits that have been pushed to a shared branch.
- Common workflow: Rebase your local feature branch onto
mainto stay current, then merge it in.
Code
# ─── Merge workflow (safe, always works) ───
git switch main
git merge feature/login
# Creates a merge commit if histories diverged
# ─── Rebase workflow (clean history) ───
# While on your feature branch:
git switch feature/login
git rebase main
# Replays feature commits on top of main's latest commit
# Then merge (now it's a fast-forward!):
git switch main
git merge feature/login
# No merge commit needed — history is linear
# ─── Interactive rebase (squash, reorder, edit commits) ───
git rebase -i HEAD~3
# Opens editor showing last 3 commits:
# pick a1b2c3d Add login form
# pick e4f5g6h Fix typo in login
# pick i7j8k9l Add validation
#
# Change to:
# pick a1b2c3d Add login form
# squash e4f5g6h Fix typo in login ← combines with previous
# pick i7j8k9l Add validation
# ─── Abort a conflicting rebase ───
git rebase --abort
# ─── Continue after resolving a rebase conflict ───
git add resolved-file.js
git rebase --continueThe Golden Rule
Never rebase commits that have been pushed to a shared branch.
If you rebase pushed commits, their hashes change. Teammates who pulled the original commits now have a different history. This causes duplicate commits, confusing merges, and broken trust.
Safe: Rebasing your local, unpushed feature branch onto the latest main.
Dangerous: Rebasing main or any branch others have pulled.
When to Use Each
| Scenario | Use |
|---|---|
Merging a feature branch into main | Merge (or merge with --no-ff) |
Keeping your feature branch up-to-date with main | Rebase (local, before pushing) |
| Cleaning up messy local commits before PR | Interactive rebase (git rebase -i) |
| Working on a shared branch with others | Merge only |
| Solo project where you want linear history | Rebase freely |
Key Takeaways
- Merge preserves history as-is and is always safe. Rebase rewrites history for a linear log.
- Never rebase commits that have been pushed to a shared branch.
- Common pattern: rebase your local feature branch onto
main, then merge with fast-forward. - Interactive rebase (
git rebase -i) lets you squash, reorder, and edit commits.
Interview Prep
-
Q: What is the difference between merge and rebase? A: Merge creates a new merge commit that joins two branches' histories, preserving the branching structure. Rebase replays commits from one branch on top of another, creating new commit objects with new hashes and producing a linear history.
-
Q: What is the "golden rule" of rebasing? A: Never rebase commits that have been pushed to a shared branch. Rebasing changes commit hashes, which creates divergent histories for anyone who has already pulled the original commits.
-
Q: What is interactive rebase and when would you use it? A: Interactive rebase (
git rebase -i) lets you modify a series of commits — squash them together, reorder them, edit messages, or drop commits entirely. It's commonly used to clean up commit history before opening a pull request.