Rebasing vs Merging
Both git merge and git rebase solve the same fundamental problem — integrating changes from one branch into another — but they produce very different history shapes and carry different risk profiles. Merging preserves history exactly as it happened, including all the branching and merging points, at the cost of a more tangled graph. Rebasing rewrites your branch's commits so they appear to have been made sequentially on top of the target branch, producing a clean, linear history at the cost of generating entirely new commit objects with new hashes. Choosing between them is less about correctness and more about which trade-off a team values for its history.
Cricket analogy: This is like choosing between keeping a match's full ball-by-ball history including every rain delay and DLS recalculation (merge), versus presenting the innings as if it were played straight through without interruption (rebase) — both give a valid result, but one preserves the messy truth and one presents a clean narrative.
How rebase actually works
git rebase <base> takes the commits unique to your current branch, temporarily sets them aside, resets your branch to match <base>, and then replays each of your original commits one at a time on top of that new base — applying each as a diff and creating a brand-new commit object for it. Because these replayed commits have different parent hashes than the originals, they are entirely new commits with new SHA-1 identifiers, even though their content (the diff they introduce) may be identical. This is the crucial fact that explains rebase's most important rule.
Cricket analogy: This is like a batter replaying each shot from a rain-interrupted innings individually onto a freshly reset pitch condition — each shot (commit) is reapplied one at a time as if played under the new conditions, producing a fresh set of deliveries even though the shot selection is identical.
The golden rule of rebasing
Because rebasing rewrites commit history, you should never rebase commits that other people have already fetched or based work on. If a shared branch's history is rewritten and force-pushed, every collaborator who already has the old commits will find their local history has diverged unrecoverably from the remote, typically producing confusing duplicate commits or failed pushes when they try to sync. The safe rule of thumb: rebase freely on your own local, not-yet-shared feature branches; use merge (or ask collaborators to coordinate a shared rebase carefully) for branches others depend on.
Cricket analogy: This is like a captain never rewriting the official scorecard of a match that's already been broadcast and recorded by every news outlet — once fans and commentators have the official record, rewriting it just to look cleaner causes chaos when everyone's own notes no longer match the new version.
# Merge approach: preserves exact history, creates a merge commit
$ git switch feature/notifications
$ git merge main
# Rebase approach: replays feature commits on top of latest main
$ git switch feature/notifications
$ git rebase main
Successfully rebased and updated refs/heads/feature/notifications.
$ git log --oneline --graph -4
* 3f2e1d0 (HEAD -> feature/notifications) Add push notification handler
* 9c8b7a6 Wire notification service into user settings
* 7d6e5f4 (main) Fix off-by-one error in pagination
* 4a3b2c1 Initial API scaffold
# ^ note: perfectly linear, no merge commit
# After rebasing a branch already pushed to a shared remote,
# a force-push (with lease, for safety) is required:
$ git push --force-with-lease origin feature/notificationsInteractive rebase (git rebase -i) is the same mechanism used for a normal rebase, but lets you reorder, squash, reword, or drop individual commits during the replay — it's a general-purpose history cleanup tool, not only a way to change a branch's base.
Never run git rebase (or force-push its result) on a branch like main or develop that other people are actively pulling from — doing so rewrites shared history and will corrupt collaborators' local repositories, typically requiring painful manual recovery.
- Merging preserves exact history and creates a two-parent merge commit; rebasing rewrites commits to sit linearly atop a new base.
- Rebased commits are brand-new objects with new SHA-1 hashes, even if their diff content is unchanged from the originals.
- The golden rule: never rebase commits that have already been shared with, and possibly built upon by, other collaborators.
- Interactive rebase (
-i) extends the same replay mechanism to let you reorder, squash, reword, or drop commits. - A rebased branch that was already pushed requires a force-push, ideally
--force-with-leasefor safety against overwriting others' work. - Neither approach is universally 'correct' — merge favors history fidelity and safety, rebase favors a clean, linear, easy-to-read log.
Practice what you learned
1. What is the fundamental difference in outcome between `git merge` and `git rebase` when integrating a feature branch into main?
2. Why do rebased commits have different SHA-1 hashes than the originals, even if the code change is identical?
3. What is the 'golden rule' of rebasing?
4. What does `git rebase -i` add beyond a standard rebase?
5. Why is `--force-with-lease` generally preferred over a plain `--force` push after rebasing a shared branch?
Was this page helpful?
You May Also Like
Merging Branches
Understand how git merge combines diverged branch histories, the difference between fast-forward and three-way merges, and when each occurs.
Interactive Rebase
Interactive rebase lets you reorder, squash, edit, or drop commits before they land, turning a messy work-in-progress history into a clean, reviewable narrative.
Resolving Merge Conflicts
Learn how Git detects merge conflicts, how to read conflict markers, and the practical workflow for resolving them safely and finishing the merge.
Commit Message Conventions
Why disciplined, structured commit messages make history searchable and automatable, and how conventions like Conventional Commits standardize their format.
Related Reading
Related Study Notes in Software Engineering
Browse all study notesMicroservices Study Notes
Software Architecture · 30 topics
Software EngineeringTesting & TDD Study Notes
Software Testing · 30 topics
Software EngineeringDesign Patterns Study Notes
Software Design · 30 topics
Software EngineeringSoftware Engineering Study Notes
Python · 40 topics
Software EngineeringSystem Design Study Notes
Architecture · 40 topics