Chapter 5.1 — Merge vs Rebase — The Big Debate☕ 22 min read

Merge vs Rebase — The Big Debate

Chay ki dukan pe debate khatam nahi hota, lekin code pe faisla karna padta hai.

01Merge Kya Hai

When branches diverge — different commits on the same base — you must combine them eventually. You cannot ignore divergence forever; at some point, the code needs to live together.

Git gives you TWO ways to combine branches: git merge and git rebase. Both produce the same code result, but they create different histories.

git merge: creates a new "merge commit" that has TWO parents. It preserves the complete history exactly as it happened — every branch, every parallel line of development.

git rebase: replays your commits on top of the other branch. It creates a linear history as if you wrote the code sequentially, one commit after another. No merge commit.

The debate is not about which is "better" — it is about which history your team prefers.

# MERGE approach — preserves branch history
git checkout main
git merge feature
# Creates: A---B---C main timeline
#               \   / (merge commit with 2 parents)
#                D   feature timeline

# REBASE approach — linear history
git checkout feature
git rebase main
# Creates: A---B---C---D' feature timeline
# All feature commits are replayed on top of main
# No merge commit, as if feature was written after C
02Rebase Kya Hai

git merge is NON-DESTRUCTIVE — it never changes existing commits, only adds a new one.

Fast-forward merge: if main hasn't changed since you branched, Git just moves the pointer forward. No merge commit needed — it's as if the branch never existed.

3-way merge: if main has new commits, Git finds the common ancestor of both branches and creates a merge commit that combines both histories.

Merge commits have two parents — you can always trace both branches' histories. This is why merge is called "safe": nothing is lost, nothing is rewritten.

Use --no-ff to FORCE a merge commit even when fast-forward is possible. This preserves branch topology — evidence that a feature branch existed.

Pros: safe, preserves true history, reversible, team-friendly.
Cons: history becomes a "spaghetti" graph with many merge commits, harder to read, git log is noisy.

# Fast-forward merge (main hasn't changed)
git checkout main
git merge feature
# Fast-forward — main pointer just moves to feature tip

# 3-way merge (main has new commits)
git checkout main
git merge feature
# Merge made by the 'ort' strategy.
# Creates a merge commit with 2 parents

# Force merge commit (preserve branch evidence)
git merge --no-ff feature
# Even if fast-forward possible, creates merge commit
# Useful: shows where feature started and ended

# View merge history
git log --oneline --graph
# *   abc1234 Merge branch 'feature'
# |\  
# | * def5678 feature commit 2
# | * ghi9012 feature commit 1
# * jkl3456 main commit
03Key Differences

git rebase MOVES your commits to a new base — it REWRITES history.

Process: Git temporarily removes your commits, updates your branch to the target, then re-applies your commits one by one on top of the new base.

Your old commits are DESTROYED and new ones are created with NEW SHA hashes — even if the code content is identical.

Rebase NEVER creates merge commits. History is perfectly linear.

Pros: clean history, easy to read, git log is a straight line, git bisect works better.
Cons: DANGEROUS on shared branches — if someone based work on your old commits, they're now broken.

The Golden Rule: NEVER rebase commits that have been pushed to a shared branch.

# Rebase your feature on top of main
git checkout feature
git rebase main
# First, rewinding head to replay your work on top of it...
# Applying: feature commit 1
# Applying: feature commit 2

# Your old commits are gone, new ones created
git log --oneline
# abc1234 feature commit 2    ← NEW hash
# def5678 feature commit 1    ← NEW hash
# ghi9012 main latest
# The old commits (with old hashes) no longer exist on this branch

# If conflicts occur during rebase
# CONFLICT (content): Merge conflict in file.txt
# Fix conflicts, then:
git add file.txt
git rebase --continue
# To abort and go back: git rebase --abort
💡 Think of it this way: Merge is a family tree — it shows every branch, every merge, the full story. Rebase is a timeline — it shows what happened in a clean, sequential order. Both are valid. Teams choose based on preference. The ONLY wrong answer is rebasing shared commits.
04Golden Rule

git merge --squash feature: takes ALL feature commits and combines them into ONE new commit on main.

No merge commit, no feature branch history visible — just one clean commit.

Use when: feature has 20 messy "WIP" commits that don't matter to main's history.

Process: git merge --squash feature → changes go to staging area → you commit manually.

Unlike regular merge, squash merge does NOT auto-commit. You must run git commit after.

Pros: clean main history, easy to revert entire feature with one commit.
Cons: loses granular history of HOW the feature was built.

# Feature branch with 15 messy commits
git log --oneline feature
# fix typo, add tests, debug, remove debug, WIP, final version...

# Squash merge: all 15 commits become ONE
git checkout main
git merge --squash feature
# Squash commit — not a real merge, changes are staged

git status
# Changes to be committed: (all feature changes combined)

git commit -m "feat: add complete authentication module"
# One clean commit. No trace of the 15 messy commits.

# Compare histories:
# Regular merge: main gets 1 merge commit + 15 feature commits visible
# Rebase: main gets 15 clean commits in a line
# Squash: main gets 1 single commit representing everything
05When To Use What

Merge: Use on shared/long-lived branches (main, develop) where history matters and safety is priority.

Rebase: Use on your LOCAL feature branch before pushing — clean up WIP commits, stay updated with main.

Squash merge: Use when merging a feature with messy WIP commits into main — keeps main clean.

Common team strategies:

  • "Merge only": preserves everything, simple, safe. No rebase ever. (Git Flow teams)
  • "Rebase + Squash": rebase local, squash-merge to main. Clean main, easy to revert. (Trunk-based teams)
  • "Rebase only": full linear history, requires team discipline, dangerous if done wrong.

NEVER: rebase main, rebase shared branches, rebase after PR approval.

# Strategy 1: Merge Only (safe, simple)
git checkout main
git merge --no-ff feature   # preserve all history

# Strategy 2: Rebase + Squash (clean main)
git checkout feature
git rebase main             # clean up feature locally
git checkout main
git merge --squash feature  # one commit on main

# Strategy 3: Rebase Only (full linear)
git checkout feature
git rebase main             # linear feature
git checkout main
git merge feature           # fast-forward merge (since rebased)
# OR: git rebase feature main (advanced, be careful)

# Strategy 4: GitHub's default (Squash and Merge button)
# Pull Request → Squash and Merge
# Same as: git merge --squash
Most modern teams use Strategy 2: rebase your feature branch daily to stay updated, then squash-merge into main. This gives you the best of both worlds — clean main history (one commit per feature), and developers can use rebase locally without affecting others. GitHub, GitLab, and Bitbucket all have a "Squash and Merge" button for exactly this workflow.

Lo kar liya — Key Points:

  • ✅ git merge creates a merge commit with two parents — preserves complete branch history exactly as it happened
  • ✅ git rebase replays commits on top of another branch — creates linear history with no merge commits
  • ✅ Rebase REWRITES history — old commits are destroyed and new ones are created with new SHA hashes
  • ✅ The Golden Rule of Rebase: NEVER rebase commits that have been pushed to a shared branch
  • ✅ git merge --squash combines all feature commits into one new commit — good for cleaning up WIP history
  • ✅ Merge is safe and preserves truth; Rebase is clean and preserves readability
  • ✅ Most modern teams: rebase local feature branches, squash-merge into main for clean history
Course Search
Search across all chapters & stages
📖

Search the course

Type any topic — branching, stash, rebase, hooks — and jump straight to that chapter.

merge branchesgit stashundo commitrebase