Q&A
Git: Should I merge or rebase my feature branch?
Overview
You've been working on a feature branch while main advanced. To incorporate main's new commits (or to integrate your work back), you choose between merge and rebase. They reach a similar end state but shape history differently: merge keeps a faithful (sometimes messy) record; rebase rewrites your commits for a clean, linear story.
graph TD
A[Integrate main into feature] --> B[Merge: keeps both histories + merge commit]
A --> C[Rebase: replays feature commits onto main, linear]
B --> B1[Preserves context, non-destructive]
C --> C1[Clean linear history, but rewrites hashes]
C1 --> D[⚠ Never rebase shared/pushed commits]
style C fill:#1e1b4b,color:#fff
style D fill:#6366f1,color:#fff
Merge
git checkout feature
git merge main # bring main's commits into feature
Git creates a merge commit with two parents, tying the branches together. History shows exactly what happened, including the parallel development:
* merge commit
|\
| * main commit
* | feature commit
|/
* common ancestor
Pros: non-destructive (no hashes change), preserves true history and context, safe for shared branches. Cons: history becomes a web of merge commits ("merge bubbles"), which can be noisy.
Rebase
git checkout feature
git rebase main # replay feature's commits on top of main
Rebase takes each commit unique to feature and re-applies it after the tip of main, producing a straight line:
* feature commit (new hash)
* main commit
* common ancestor
Pros: clean, linear history that's easy to read and git bisect; no merge bubbles.
Cons: rewrites commit hashes (the replayed commits are new objects); resolving conflicts can happen commit-by-commit; dangerous on shared branches.
The Golden Rule
Never rebase commits that exist outside your local repository (i.e., anything already pushed and that others may have based work on).
Rebasing shared commits rewrites history everyone else has, forcing painful recovery and --force pushes that can clobber teammates' work. Rebase your own unpushed/local feature commits freely; merge (or use a careful, coordinated --force-with-lease) for anything shared.
Common Workflows
- Rebase to update, merge to integrate: while developing,
git rebase mainto keep your feature current on top of the latestmain; when done,git merge(often a--no-ffmerge or a PR merge) to land it. - Squash and merge: many teams rebase/squash a feature into one clean commit, then merge - combining linear tidiness with a single logical unit.
- Pull with rebase:
git pull --rebaseavoids a merge commit when syncing your branch.
Interactive Rebase (bonus)
git rebase -i lets you reorder, squash, edit, or drop your own commits before sharing - great for cleaning up a messy local history:
git rebase -i HEAD~5 # tidy the last 5 commits
Why This Matters in Interviews
This is a top Git interview question. The expected answer: explain what each does (merge = merge commit preserving history; rebase = replay for linear history, rewriting hashes), the trade-offs, and - most importantly - the golden rule about never rebasing shared/pushed commits. Mentioning practical workflows (rebase to update, merge to integrate; squash-and-merge; pull --rebase) shows real experience. There's no universally "right" answer; judgment about context is what's assessed.
Common Pitfalls
- Rebasing already-pushed commits and then force-pushing over teammates' work.
- Believing rebase "loses" commits - it rewrites them (new hashes), the content remains.
- Force-pushing with plain
--forceinstead of safer--force-with-lease. - Treating it as dogma ("always rebase"/"always merge") rather than context-dependent.
References
- Pro Git - Rebasing: https://git-scm.com/book/en/v2/Git-Branching-Rebasing
git merge/git rebasedocs: https://git-scm.com/docs