Understanding the Difference Between Git Merge and Rebase
When working with Git, you often need to integrate changes from a remote branch into your local branch. The two primary strategies for doing this are merge and rebase. Both achieve the same goal — combining your work with the latest remote changes — but the way they record history and handle conflicts is fundamentally different. Understanding these differences is key to keeping a clean, maintainable codebase.
Merge: Preserving History
A merge takes your local commits and the commits from the remote branch and combines them into a new merge commit. Consider this example:
origin/main: A --- B --- C
your local: A --- B --- D --- E
After git pull (merge), Git produces:
A --- B --- C
\ \
D --- E --- M
Here, M is the merge commit that brings together your local work (D and E) with the remote changes (C). Advantages of merge include:
- Preserving original commit hashes
- Maintaining a complete record of how branches diverged and converged
Merge Process Model
apply_merge(D + E vs C)
if 冲突:
改代码(一次性处理所有冲突)
git add
git commit # 生成 merge commit
Drawbacks:
- Non-linear history can be messy in long-running branches
- Conflicts across multiple commits are resolved in a single merge commit, which can be harder to reason about
Rebase: Rewriting History
A rebase works differently. Instead of creating a merge commit, it moves your local commits on top of the latest remote commits, effectively rewriting your commit history:
origin/main: A --- B --- C
your local: A --- B --- D --- E
After git pull --rebase, Git produces:
A --- B --- C --- D' --- E'
Here, D' and E' are rewritten versions of your original commits. The code outcome is identical to merge, but the history is linear. Each commit is applied one by one:
-
Dis applied on top ofC; conflicts are resolved if they exist. -
Eis applied next; conflicts, if any, are resolved commit by commit.
Rebase Process Model
for commit in [D, E]:
apply(commit)
if conflict:
# 🔴 Git stop
# forbidden pull / push
1.Resolve the conflicts manually (there may be multiple files).
2.git add . # the current commit conficts is resolved
3.git rebase --continue # commit current, contine next commit
else
without confilcts commits auto
# all commit replay done
git push
(It is not necessary to run git commit, as git rebase --continue automatically creates the commit..)
Advantages of rebase:
- Linear, clean history that is easier to read and debug
- Conflicts are isolated to individual commits, simplifying resolution
- Looks as if you developed your changes after the latest remote commits
Drawbacks:
- Original commit hashes are rewritten
- Rebasing public/shared branches can disrupt collaborators’ work if they’ve based commits on your original branch
Choosing Between Merge and Rebase
- Solo or small-team branches: Prefer rebase for a clean, linear history.
- Large teams / long-lived shared branches: Merge is safer because it preserves history without rewriting it.
Mental shortcut:
- Merge = “show history as it actually happened”
- Rebase = “pretend my commits came after the latest remote changes”
In summary, both strategies integrate your work with the remote branch, but merge preserves history and can get messy, while rebase rewrites history for a clean, linear timeline. For developers who value clarity, incremental conflict resolution, and maintainable history, rebase is often the preferred approach.