What is the difference between merge and rebase in Git?
Technical · Fresher
Answer guide
Read the answer guide
Merge integrates another branch’s history. If the current branch is an ancestor of the incoming branch, the default fast-forward advances the branch pointer without a new commit. If histories have diverged, a normal successful merge creates a merge commit that preserves both lines of history; --no-ff can also request a merge commit for a fast-forwardable merge. Rebase takes your commits and replays them on top of another base, giving a straight, tidy history but creating new commits with new IDs, so it rewrites history. That is fine for your own local branch before sharing, but rebasing commits others have already pulled forces them to fix their copies. Neither is always better; agree a policy. If a rebase goes wrong, git reflog usually lets you recover the previous state.
What the interviewer is assessing
Basic Git understanding of history rewriting and when rebase is safe compared with merge.
Common mistakes
Rebasing a branch that teammates have already pulled and pushed.
Thinking merge and rebase produce the same commit history.
Practise a follow-up
What is git reflog and how could it rescue you after a bad rebase?
What does squash merging do to history, and when would you prefer it?
In a disposable repository, compare the commit count and parent list. Branch main has no new work before the first merge, so Git can fast-forward. --no-ff in the second example requests a merge commit.
git init -b main merge-demo
cd merge-demo
git -c user.name=Demo -c user.email=demo@example.invalid commit --allow-empty -m base
git switch -c feature
git -c user.name=Demo -c user.email=demo@example.invalid commit --allow-empty -m feature
git switch main
git merge feature
git rev-list --count HEAD
# Expected: 2 (no merge commit)
git switch -c feature-two
git -c user.name=Demo -c user.email=demo@example.invalid commit --allow-empty -m feature-two
git switch main
git -c user.name=Demo -c user.email=demo@example.invalid merge --no-ff feature-two -m merge
git rev-list --count HEAD
# Expected: 4
git rev-list --parents -n 1 HEAD
# Expected: current commit ID followed by two parent IDs
Rebase instead replays commits and usually changes their IDs. Avoid rewriting history others depend on without coordination.