Git merge and rebase are two strategies for integrating changes from one branch into another. Merge preserves the complete history by creating a merge commit, while rebase rewrites history to produce a clean, linear sequence of commits. Both achieve the same end result — combining work — but they differ in how the commit history reads afterward, with important implications for team collaboration.
| Aspect | Merge | Rebase |
|---|---|---|
| History shape | Non-linear with merge commits | Linear, flat |
| Commit preservation | Original commits kept | Commits rewritten with new hashes |
| Conflict resolution | Resolve once in merge commit | Resolve per replayed commit |
| Safe for shared branches | Yes | No — rewrites public history |
| Bisect friendliness | Harder with merge commits | Easier with linear history |
| Reversibility | Revert the merge commit | Original history is lost |
How does git merge work?
Git merge takes two branch tips and their common ancestor, then creates a new merge commit that combines both sets of changes. The merge commit has two parents, preserving the full branching history. If both branches modified the same lines, Git pauses for manual conflict resolution. The --no-ff flag forces a merge commit even when a fast-forward is possible, which is useful for tracking feature branch integration points.
How does git rebase work?
Git rebase takes each commit from your branch and replays it on top of the target branch, creating new commits with new hashes. The result looks as if you started your work from the latest commit on the target branch. Interactive rebase (git rebase -i) also lets you squash, reorder, edit, or drop commits before replaying them, making it a powerful tool for cleaning up commit history before merging.
What is the golden rule of rebasing?
Never rebase commits that have been pushed to a shared branch. Rebasing rewrites commit hashes, so anyone who based work on the original commits will have divergent history. This leads to duplicate commits and confusing merge conflicts. Rebase is safe for local branches that only you work on. Once commits are pushed and shared, use merge to integrate changes.
Which strategy produces better history?
Rebase produces a cleaner, linear history that is easier to read with git log and easier to navigate with git bisect. Merge preserves the true history of how development actually happened, including when branches were created and integrated. Teams that value traceability prefer merge. Teams that value readability prefer rebase. A common middle ground is to rebase locally, then merge with --no-ff to create a single merge commit per feature.
When to Use Which
Use merge when integrating shared branches (main, develop), when you need to preserve the complete history of how changes were combined, and when multiple people are working on the same branch. Use rebase to clean up local feature branch history before merging, to keep a linear history in your branch, and to incorporate upstream changes into a branch that only you work on. Many teams combine both: rebase locally, then merge to main.
Key Takeaways
Merge is safe and preserves history; rebase is clean and rewrites history. Neither is universally better — they serve different purposes. Use merge for public, shared integration points. Use rebase for private, local history cleanup. The most effective teams establish a clear convention (merge-only, rebase-then-merge, or squash-merge) and follow it consistently. Whatever strategy you choose, never rebase commits that others have based work on.