Git Merge vs Rebase: When the Wrong Choice Breaks Your Team
The article explains the fundamental differences between Git merge and rebase, shows how each command reshapes commit history, provides a golden rule against rebasing public branches, and offers practical scenarios, guidelines, and common pitfalls to help teams choose the right strategy.
Merge vs Rebase – Core Differences
merge: keep history branching
git merge featurePreserves complete branch history
Creates a merge commit
Branch graph shows a fork
rebase: rewrite history into a linear line
git rebase mainHistory becomes linear, no forks
Generates new commits (hashes change)
Appears as if changes happened after the target branch
Core differences
History record : merge keeps original commits; rebase rewrites them.
Commit hash : unchanged with merge; regenerated with rebase.
Merge conflicts : resolved once with merge; each rebase commit may cause a conflict.
Typical scenario : merge for shared/public branches; rebase for private/local branches.
Safety : merge is safe (does not alter history); rebase carries risk on public branches.
Rebase Golden Rule
Do not rebase public branches!
# ❌ Dangerous: rebase a public branch
git checkout main
git rebase feature # NEVER DO THIS!
# ✅ Safe: rebase a private feature branch
git checkout feature
git rebase main # OK ┌─────────────────────────────────────────────────────────────────┐
│ Rebase public branch disaster │
├─────────────────────────────────────────────────────────────────┤
│ 1. Multiple developers work on main │
│ 2. You rebase main → commit hashes on main change │
│ 3. Others push and find history diverged → forced push needed │
│ 4. Everyone's local branches become inconsistent → chaos │
└─────────────────────────────────────────────────────────────────┘Practical Scenarios
Scenario 1 – Local development: rebase to keep history clean
# 1. Create feature branch from main
git checkout main
git pull origin main
git checkout -b feature/payment
# 2. Develop and commit
git add .
git commit -m "feat: add payment API"
# 3. Main receives new commits → rebase to sync
git fetch origin
git rebase origin/main
# 4. Resolve conflicts then continue
git add .
git rebase --continue
# 5. Finish development → merge to main via PR
git push origin feature/payment
# Create PR on GitHub/GitLab and mergeScenario 2 – Squash multiple commits (interactive rebase)
# Merge the last 3 commits
git rebase -i HEAD~3
# In the editor, change "pick" to "squash" for the 2nd and 3rd lines
pick f1a2b3c feat: add payment step 1
squash d4e5f6g feat: add payment step 2
squash h7i8j9k feat: add payment step 3
# Write a new commit message
feat: add complete payment featureScenario 3 – Resolve merge conflicts
# Merge conflict handling
git merge feature
# Conflict reported: CONFLICT in file.txt
# 1. Edit file to resolve conflict
vim file.txt
# 2. Mark as resolved
git add file.txt
# 3. Complete merge
git commit
# Rebase conflict handling
git rebase main
# Conflict reported: CONFLICT in file.txt
# 1. Edit file
git add file.txt
# 2. Mark as resolved
git add file.txt
# 3. Continue rebase
git rebase --continueWhen to Use Merge vs Rebase
Public branch merging – use merge (safe, does not rewrite history)
Personal development branch sync – use rebase (keeps history tidy)
Release version merging – use merge (clearly marks release point)
Commit cleanup before merging – use rebase -i (organise commits)
PR merging – depends on team policy
Common Misconceptions
Misconception 1 – Use rebase instead of merge for PR
# ❌ Wrong: rebase feature onto main then force‑push
git checkout main
git rebase feature
git push --force # dangerous
# ✅ Correct: merge or PR merge
git checkout main
git merge feature
git pushMisconception 2 – Force‑push to a public branch
# ❌ Dangerous force push
git push --force # overwrites remote history
# ✅ Safe alternative
git push --force-with-lease # checks for new remote commits firstMisconception 3 – Not knowing how to resolve rebase conflicts
# Abort a messy rebase
git rebase --abort
# Switch to merge instead
git merge mainCommand Cheat Sheet
git merge <branch> # merge a branch
git rebase <branch> # rebase onto target branch
git rebase -i HEAD~n # interactive rebase (squash, edit, etc.)
git rebase --continue # continue after resolving conflicts
git rebase --abort # abort the rebase
git push --force-with-lease # safe forced pushSigned-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Coder Trainee
Experienced in Java and Python, we share and learn together. For submissions or collaborations, DM us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
