What exactly does git's rebase --preserve-merges do and why?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
git rebase --preserve-merges was Git's older way of rebasing a branch while attempting to keep merge commits instead of flattening them away. The goal was to preserve branch topology during the rebase, but the option was complicated and imperfect enough that modern Git replaced it with --rebase-merges.
What Normal Rebase Does
A plain rebase takes the non-base commits from your branch and replays them one by one on top of a new base commit. In the process, merge commits are usually flattened.
So if your branch history contained:
- feature commits
- a merge from another topic branch
- more feature commits
a plain rebase would typically replay only the linearized commits and discard the original merge structure.
What --preserve-merges Tried to Do
--preserve-merges told Git to recreate merge commits during the rebase instead of flattening the history completely.
Conceptually, it tried to do this:
- identify the merge structure in the rebased branch
- replay commits onto the new base
- recreate merge commits where the old history had them
That was useful when the merge commits carried real meaning, for example when the branch intentionally merged other topic branches and you wanted that structure to remain visible after rebasing.
Why Someone Would Want It
There are cases where merge commits are not noise. They may represent:
- integration points between topic branches
- reviewed branch combinations
- structure that is easier to understand than a flattened history
In those cases, plain rebase loses context by turning everything into a single linear stream. --preserve-merges existed to keep more of that historical shape.
Why It Was Problematic
The trouble was that preserving merge topology is harder than replaying a linear list of commits. Merge commits have two or more parents, conflict-resolution context, and historical meaning that cannot always be reconstructed cleanly.
As a result, --preserve-merges could be confusing in complex histories:
- merge commits were recreated, not literally preserved byte-for-byte
- conflict handling could be tricky
- interactive editing behavior was limited
So the option preserved the shape imperfectly rather than magically replaying history with full original semantics.
The Modern Replacement: --rebase-merges
Modern Git uses:
This is the successor to --preserve-merges and is generally more reliable and more expressive. If you are reading older Git discussions, mentally translate most advice about --preserve-merges into "use --rebase-merges instead unless you are stuck on old Git."
A Small Example
Suppose your history looks like this:
With plain rebase, the merge M may disappear into a flattened replay. With a merge-preserving rebase, Git tries to recreate a history that still shows a merge at that point after moving the branch onto a new base.
That can make the rebased branch easier to reason about if the merge mattered logically.
Common Pitfalls
The biggest pitfall is assuming --preserve-merges kept merge commits exactly as they originally were. It did not. It recreated merge structure as part of the rebase process.
Another common mistake is using it when the merge commits were not meaningful in the first place. If the branch history does not need preserved topology, a normal rebase is simpler and less surprising.
Developers also follow old tutorials literally even though the flag has been superseded. In current Git, --rebase-merges is the better option to learn.
Summary
- Plain rebase usually flattens merge commits.
- '
--preserve-mergeswas the old option for rebasing while trying to recreate merge topology.' - It existed for histories where merge structure had meaning.
- It was imperfect and has been superseded by
--rebase-merges. - For modern Git workflows, prefer
git rebase --rebase-mergesinstead of the older flag.
Related reading
- What exactly does the u do? git push -u origin master vs git push origin master
- What exactly is a Maven Snapshot and why do we need it?
- What Git branching models work for you?
- What goes into your .gitignore if you're using CocoaPods?
- What happens if you force push to a branch with an existing pull request?
- What if two Git repositories share common code
- What is a legit .gitignore for a Flutter project that is developed in Android Studio?
- What is a subproject commit?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.