Merge vs Rebase
Merge vs Rebase
Section titled “Merge vs Rebase”Both merge and rebase integrate changes from one branch into another, but they produce different histories.
git merge
Section titled “git merge”Creates a merge commit that joins two branch histories:
Before: A---B---C main \ D---E feature
After merge: A---B---C---F main \ / D---EF is the merge commit. History shows exactly when and how branches joined.
git switch maingit merge feature/loginAdvantages:
- Non-destructive — no existing commits are changed
- Complete record of when branches merged
- Safe for shared branches
Disadvantages:
- Creates an extra commit for every merge
- History can become cluttered with merge commits
git rebase
Section titled “git rebase”Re-applies commits from one branch on top of another, rewriting history:
Before: A---B---C main \ D---E feature
After rebase: A---B---C main \ D'---E' feature (new commits, same changes)D' and E' are new commits with the same changes as D and E but different parent commits and hashes.
git switch feature/logingit rebase mainAdvantages:
- Linear, clean history — easy to read with
git log --oneline - No noise from merge commits
- Makes
git bisectandgit blameeasier to use
Disadvantages:
- Rewrites history — changes commit SHAs
- Dangerous on shared branches (others may have based work on the original commits)
The Golden Rule of Rebasing
Section titled “The Golden Rule of Rebasing”Never rebase commits that have been pushed to a shared branch.
Rebasing rewrites history. If others have based work on the original commits, rewriting creates divergent histories and painful conflicts.
Safe to rebase:
- Your local feature branch (before pushing)
- After pushing but before anyone else has based work on it
Unsafe to rebase:
main,develop— shared branches- Any branch others are actively using
Interactive Rebase
Section titled “Interactive Rebase”Rewrite history for your local commits:
git rebase -i HEAD~3 # rewrite last 3 commitsOpens an editor where you can:
pick abc1234 Add user modelpick def5678 Add user controllerpick ghi9012 Fix typo in controller
# Commands:# p, pick = use commit# r, reword = change commit message# e, edit = stop and amend commit# s, squash = merge into previous commit# f, fixup = merge into previous (discard message)# d, drop = remove commitSquash commits before merging a PR:
git rebase -i origin/main# Mark all but the first commit as 'squash'# Write a single clean commit messagegit push --force-with-lease—force-with-lease vs —force
Section titled “—force-with-lease vs —force”After rebasing a branch you’ve already pushed, you need to force push:
# Safe — fails if the remote has been updated by someone elsegit push --force-with-lease
# Dangerous — overwrites remote regardlessgit push --forceAlways use --force-with-lease when force pushing.
When to Use Each
Section titled “When to Use Each”| Scenario | Recommendation |
|---|---|
| Merging a PR into main | Squash and merge (clean history) or merge commit |
| Keeping a feature branch up to date | Rebase onto main (linear history) |
| Integrating long-running branches | Merge (preserves context) |
| Shared branch that others use | Merge only |
| Cleaning up local commits before PR | Interactive rebase + squash |
Merge Strategies in GitHub
Section titled “Merge Strategies in GitHub”GitHub offers three merge strategies per repository:
- Merge commit —
git merge --no-ff— preserves full branch history - Squash and merge — all PR commits squashed into one — cleanest main history
- Rebase and merge — commits replayed linearly — no merge commit
Squash and merge is the most popular choice for keeping main clean.