What is the difference between a fast-forward merge and a three-way merge?
Learn how a Git fast-forward merge differs from a three-way merge, when each occurs, the role of the merge base, and how --no-ff and --ff-only change behavior.
Expected Interview Answer
A fast-forward merge simply moves the branch pointer forward when the target branch has not diverged, creating no new commit; a three-way merge is used when both branches have new commits, so Git combines them and records a new merge commit with two parents.
Fast-forward is possible only when the current branch's tip is a direct ancestor of the branch being merged in — history is linear, so Git just advances the pointer. A three-way merge happens when the histories have diverged: Git finds the common ancestor (merge base) and compares it against both branch tips (the three ways), reconciles the changes, and creates a merge commit that ties both lines together. You can force a merge commit even for a fast-forwardable case with git merge --no-ff, or require linear history with git merge --ff-only.
- Fast-forward keeps history perfectly linear and simple
- Fast-forward adds no extra merge commit
- Three-way preserves the true branching history
- Three-way records exactly when and where lines rejoined
- --no-ff and --ff-only let teams enforce their preferred style
AI Mentor Explanation
A fast-forward merge is like a rain-free innings where the second batter simply continues the first batter's exact running total on the same scoreline — no adjustment, the score just rolls forward. A three-way merge is like two innings played on different grounds that must be reconciled by a scorer who consults the original starting total (the merge base) and blends both into one official combined result recorded as a new entry.
Step-by-Step Explanation
Step 1
Check divergence
Git determines whether the current branch tip is an ancestor of the branch being merged; if so, fast-forward is possible.
Step 2
Fast-forward path
When linear, Git just moves the current branch pointer up to the target tip — no new commit, no merge base needed.
Step 3
Find the merge base
When histories diverged, Git locates the common ancestor of both branch tips using merge-base.
Step 4
Three-way compare
Git diffs the merge base against each tip and combines the changes, flagging overlaps as conflicts.
Step 5
Record a merge commit
Git writes a new commit with two parents, tying both branches together in history.
What Interviewer Expects
- Understanding that fast-forward requires non-divergent history
- Knowing a three-way merge uses the common ancestor plus both tips
- Awareness that only three-way merges create merge commits
- Familiarity with --no-ff and --ff-only flags
- Ability to explain when each occurs in practice
Common Mistakes
- Thinking every merge creates a merge commit
- Believing fast-forward merges combine changes when they only move a pointer
- Not knowing the role of the merge base in a three-way merge
- Confusing --no-ff (force merge commit) with --ff-only (require linear)
- Assuming a three-way merge always causes conflicts
Best Answer (HR Friendly)
“A fast-forward merge happens when nothing changed on the main line, so Git just slides the pointer forward without making a new commit. A three-way merge happens when both sides have new work, so Git compares them against their shared starting point and records a special merge commit that joins the two histories.”
Code Example
# Fast-forward: main has no new commits since feature branched
git checkout main
git merge feature # Updating a1b2c3..d4e5f6 -> Fast-forward
# Force a merge commit even when fast-forward is possible
git merge --no-ff feature
# Three-way: both branches diverged, Git creates a merge commit
git merge feature # Merge made by the 'recursive' strategy
# Require linear history, abort if a merge commit would be needed
git merge --ff-only featureFollow-up Questions
- When would you prefer --no-ff over a fast-forward merge?
- What does --ff-only enforce and why use it?
- How does git rebase differ from a three-way merge?
- What is a merge base and how does Git compute it?
- How many parents does a merge commit have?
MCQ Practice
1. A fast-forward merge is possible when?
Fast-forward requires linear history: the current branch tip must be a direct ancestor of the branch being merged, so Git only moves the pointer.
2. Which merge creates a new commit with two parents?
A three-way merge reconciles diverged branches and records a merge commit that has two parents, one from each branch.
3. What does git merge --no-ff do?
--no-ff always creates a merge commit, preserving the fact that a branch existed even when a fast-forward could have occurred.
Flash Cards
When does a fast-forward merge happen? — When the current branch has not diverged; Git just moves the pointer, adding no merge commit.
When does a three-way merge happen? — When both branches have new commits; Git uses the merge base plus both tips and records a merge commit.
What are the 'three ways'? — The common ancestor (merge base) and the two branch tips being compared.
What does --ff-only do? — Aborts the merge unless it can be done as a fast-forward, enforcing linear history.