How Git Merge vs Rebase Actually Works (With Visual Examples)
Every team has this argument. โAlways merge.โ โAlways rebase.โ โIt depends.โ The reason the argument never ends is that most developers donโt understand what merge and rebase actually do to their commit history. Once you see it, the right choice becomes obvious for each situation.
The setup
You have main with commits A โ B โ C. You created a branch feature from B and made commits D โ E.
Meanwhile, someone pushed commit F to main.
main: A โ B โ C โ F
feature: A โ B โ D โ E
You need to get F into your feature branch (or get your feature into main). Merge and rebase do this differently.
What merge does
git checkout feature
git merge main
Merge creates a new โmerge commitโ (M) that has two parents: E (your last feature commit) and F (the latest on main).
main: A โ B โ C โ F
feature: A โ B โ D โ E โ M
โ โ
C โ F ------
Your commits D and E are untouched. The merge commit M ties the two histories together. The full history is preserved โ you can see exactly when the branch diverged and when it was merged.
Whatโs in the merge commit: No code changes of its own (usually). It just records โthese two lines of history came together here.โ If there were conflicts, the merge commit contains the conflict resolutions.
What rebase does
git checkout feature
git rebase main
Rebase takes your commits (D and E), temporarily removes them, moves your branch to the tip of main (F), and replays your commits on top.
Before: A โ B โ D โ E (feature)
โ C โ F (main)
After: A โ B โ C โ F โ D' โ E' (feature)
Dโ and Eโ are new commits. They have the same changes as D and E, but different hashes and different parent commits. The originals are gone (technically still in the reflog for 30 days, but not in the visible history).
The result: A perfectly linear history. It looks like you wrote your feature after F was committed, even though you didnโt.
Why this matters
Merge preserves truth
The history shows what actually happened: two people worked in parallel, and their work was combined. This is useful for debugging โ you can see exactly when a change was introduced and in what context.
Rebase preserves clarity
The history is clean and linear. git log reads like a story instead of a subway map. This is useful for code review โ reviewers see a logical sequence of changes without merge noise.
When to use which
Use merge when:
- Combining a long-lived feature branch into main
- You want to preserve the full history of when work happened
- Multiple people worked on the feature branch
- The branch has already been pushed and others are working on it
Use rebase when:
- Updating your local feature branch with the latest main
- Cleaning up your commit history before a pull request
- Youโre the only person working on the branch
- You want a clean, linear history in the PR
Never rebase when:
- The branch has been pushed and others have based work on it
- Youโre on main or a shared branch
- You donโt understand what youโre doing (merge is always safe)
The golden rule
Donโt rebase commits that exist outside your local repository.
If youโve pushed commits and someone else might have pulled them, rebasing rewrites those commits. The other person now has commits that no longer exist in the remote. This causes merge conflicts, duplicated commits, and confused teammates.
Interactive rebase: the real power
git rebase -i HEAD~3
This opens an editor showing your last 3 commits. You can:
- pick โ keep the commit as-is
- squash โ combine with the previous commit
- reword โ change the commit message
- drop โ delete the commit entirely
- reorder โ move commits up or down
This is how you turn โfix typo,โ โactually fix typo,โ โok really fix it this timeโ into a single clean commit before opening a PR.
The team strategy that works
Most successful teams use both:
- Rebase your feature branch onto main before opening a PR (keeps history clean)
- Merge the PR into main with a merge commit (preserves the PR as a unit of work)
GitHubโs โSquash and mergeโ button does both in one step โ squashes all your feature commits into one and merges it. This is the most common strategy in 2026.
The one-sentence summary
Merge combines histories and preserves truth. Rebase rewrites history for clarity. Use rebase on your local branches, merge for shared branches, and squash-merge for PRs.
FAQ
Should I merge or rebase?
Use rebase to update your local feature branch with the latest changes from main โ it keeps history clean and linear. Use merge when combining a completed feature branch into main, especially if others have worked on it. Most teams rebase locally, then merge (or squash-merge) the PR.
Is rebase dangerous?
Only if you rebase commits that have already been pushed and shared with others. Rebase rewrites commit history, so if someone else has based work on those commits, it causes conflicts and duplicated commits. On local branches that only you use, rebase is perfectly safe.
When should I use rebase?
Use rebase when updating your feature branch with the latest main before opening a PR, when cleaning up messy commit history with interactive rebase (git rebase -i), and when youโre the only person working on the branch. Never rebase shared or public branches.
Related: Git cheat sheet ยท Git Merge Conflict โ how to fix ยท Git Rebase Conflict โ fix ยท Git Stash cheat sheet