Topic: Learning notes
Git Merge vs Rebase: Which Should You Use?
Learn how Git merge and rebase change commit history, when each workflow fits, and how to avoid rewriting shared branches or creating needless conflicts.
Animated meme (expand/collapse)
Imagine you’re writing a novel with your friends. Everyone is working on different chapters at the same time. When it’s time to combine all the work, you have two choices: staple all the drafts together with sticky notes showing who wrote what and when (merge), or rewrite everyone’s chapters onto clean paper as if they were written in perfect sequence (rebase).
Welcome to the eternal debate of Git: merge vs rebase!
1. The Basics: What Problem Are We Solving?
In Git, when you work on a feature branch and the main branch has moved forward, you need to integrate those changes. Both git merge and git rebase accomplish this, but they do it very differently.
# Your feature branch diverged from main
main: A --- B --- C --- D
\
feature: E --- F --- G
The question is: how do we bring D’s changes into our feature branch (or vice versa)?
2. Git Merge: The “Family Photo” Approach 📸
git merge combines two branches by creating a new “merge commit” that ties their histories together.
How It Works
git checkout feature
git merge main
The result looks like this:
main: A --- B --- C --- D --------
\ \
feature: E --- F --- G --- M (merge commit)
Pros of Merge
- Preserves complete history: Every commit, every branch, every decision is recorded
- Non-destructive: Original commits remain unchanged
- Easy to understand: The merge commit clearly shows when branches were combined
- Safe for shared branches: Never rewrites public history
Cons of Merge
- Messy history: Your git log becomes a tangled web of merge commits
- Noise: Frequent merges create many “Merge branch ‘main’ into feature” commits
When to Use Merge
✅ Merging feature branches back into main
✅ Working on shared branches with multiple contributors
✅ When you want to preserve the exact history of development
✅ If you’re unsure — merge is always the safer choice!
3. Git Rebase: The “Time Machine” Approach ⏰
git rebase takes your commits and replays them on top of another branch, as if you started your work from there.
How It Works
git checkout feature
git rebase main
The result looks like this:
main: A --- B --- C --- D
\
feature: E' --- F' --- G'
Notice the commits are now E', F', G' — they’re new commits with the same changes but different commit hashes!
The Magic Behind Rebase
- Git finds the common ancestor of the two branches (B)
- Git “detaches” your commits (E, F, G)
- Git moves the feature branch pointer to the tip of main (D)
- Git replays your commits one by one on top of D
Pros of Rebase
- Linear history: Clean, straight line of commits
- Easy to read:
git logtells a clear story - No merge commits: Less clutter in history
- Easier bisecting: Finding bugs with
git bisectis simpler
Cons of Rebase
- Rewrites history: Creates new commit hashes
- ⚠️ Dangerous for shared branches: Never rebase commits that others are using!
- Conflicts may repeat: You might resolve the same conflict multiple times
When to Use Rebase
✅ Cleaning up local commits before pushing
✅ Keeping a feature branch up-to-date with main (locally)
✅ Squashing messy work-in-progress commits
✅ When you want a clean, linear project history
4. Interactive Rebase: The Secret Weapon 🗡️
git rebase -i (interactive rebase) is one of Git’s most powerful features. It lets you edit, combine, reorder, or delete commits.
git rebase -i HEAD~3 # Rebase the last 3 commits
This opens an editor:
pick e3a1b35 Add user authentication
pick 7c82d14 Fix typo in auth
pick 9f4e821 Add password validation
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# d, drop = remove commit
Common Use Cases
Squash messy commits:
pick e3a1b35 Add user authentication
squash 7c82d14 Fix typo in auth
squash 9f4e821 Add password validation
This combines all three into one clean commit!
Reorder commits: Just change the order of the lines.
Edit a commit message:
Change pick to reword.
5. The Golden Rule ⚠️
Never rebase commits that have been pushed to a shared repository.
When you rebase, you’re creating new commits with new hashes. If others have based their work on the original commits, you’ll create a nightmare of duplicate commits and conflicts.
# Before rebase (what your teammate sees)
main: A --- B --- C
\
feature: D --- E ← teammate is working here
# After your rebase
main: A --- B --- C
\
feature: D' --- E' ← different commits!
# When teammate tries to push... CHAOS! 💥
Animated meme (expand/collapse)
6. A Practical Workflow
Here’s a workflow that gives you the best of both worlds:
Developing a Feature
# 1. Create feature branch
git checkout -b feature/awesome-thing main
# 2. Make commits as you work
git commit -m "Add initial implementation"
git commit -m "Fix bug"
git commit -m "WIP: trying something"
git commit -m "Actually fix the bug"
# 3. Before pushing, clean up with interactive rebase
git rebase -i main
# Squash the messy commits into logical units
# 4. Push your clean branch
git push origin feature/awesome-thing
Integrating Changes from Main
# Option A: Rebase (if you haven't pushed yet)
git fetch origin
git rebase origin/main
# Option B: Merge (if you've already pushed)
git fetch origin
git merge origin/main
Final Integration
# When feature is complete, merge into main
git checkout main
git merge --no-ff feature/awesome-thing
# --no-ff creates a merge commit even if fast-forward is possible
# This preserves the feature branch in history
7. Resolving Conflicts
Both merge and rebase can result in conflicts. Here’s how to handle them:
During Merge
git merge main
# CONFLICT! Edit the files to resolve
git add resolved-file.js
git commit # Complete the merge
During Rebase
git rebase main
# CONFLICT! Edit the files to resolve
git add resolved-file.js
git rebase --continue # Continue to next commit
# If things go wrong:
git rebase --abort # Go back to before the rebase
8. Quick Reference Card
| Aspect | Merge | Rebase |
|---|---|---|
| History | Non-linear, preserves all | Linear, rewrites commits |
| Merge commits | Creates one | None |
| Original commits | Preserved | Replaced with new ones |
| Conflict resolution | Once | Per commit |
| Safe for shared branches | ✅ Yes | ❌ No |
| Readability | Can be messy | Clean and linear |
9. TL;DR (Too Long; Didn’t Read)
- Use
mergefor public/shared branches and when preserving history matters - Use
rebasefor local cleanup and keeping feature branches updated - Never rebase commits that have been pushed and shared
- When in doubt, merge is always safe
External References
Official Documentation
Tutorials and Guides
Visual Learning
- Learn Git Branching (Interactive tutorial — highly recommended!)