Git Rebase & Advanced History
TL;DR — Quick Summary
- Rebase replays your commits on top of another branch — creating clean, linear history.
- Interactive rebase (
git rebase -i HEAD~N) lets you squash, reorder, edit, and delete commits. - Golden Rule: Never rebase commits already pushed to a shared branch.
- Use rebase for local cleanup; use merge for integrating into shared branches.
Lesson Overview
📐 Rebase: Rewriting the Story
While git merge preserves the complete, branching history of your project, git rebase takes a different approach — it rewrites your commits as if they happened on top of a different starting point, creating a perfectly linear history.
Imagine your feature branch diverged from main 10 commits ago. Instead of merging (which creates a merge commit), rebasing replays your feature branch commits, one by one, on top of the current tip of main. The result looks like you wrote your feature after all those main commits — even if you actually wrote it before.
🆚 Merge vs. Rebase at a Glance
- Merge: Non-destructive. Preserves true history. Creates merge commits. History can get "noisy" on busy projects.
- Rebase: Rewrites history. Creates clean linear history. No merge commits. Makes
git loga joy to read.
⚡ Interactive Rebase — The Power Tool
Interactive rebase (git rebase -i) lets you rewrite the last N commits however you like:
- squash: Combine multiple commits into one
- reword: Change a commit message
- edit: Pause and amend a specific commit
- drop: Delete a commit entirely
- reorder: Move commits up or down
The Golden Rule of Rebasing: Never rebase commits that have been pushed to a shared branch. Rebase rewrites history — if others have those commits, you'll create diverging histories and chaos.
Conceptual Deep Dive
main: A - B - C - D
feature: A - B - E - F (branched off after B)
After git rebase main from feature branch:
main: A - B - C - D
feature: A - B - C - D - E' - F' (E and F replayed on top of D)
E' and F' are new commits with new SHA hashes — same changes, different parents. This is why rebasing rewrites history.Implementation Lab
# Scenario: your feature branch is behind main by several commits
git checkout feature/new-dashboard
# Rebase: replay your feature commits on top of current main
git rebase main
# Git will replay your commits one by one
# If a conflict occurs at any step, Git pauses and shows:
# CONFLICT (content): Merge conflict in src/Dashboard.jsx
# Resolve the conflict in the file, then:
git add src/Dashboard.jsx
git rebase --continue # continue replaying remaining commits
# Or to completely abandon the rebase:
git rebase --abort
# After successful rebase, your branch is 'ahead' of main cleanly
git log --oneline --graph
# * f9a2b3c (HEAD -> feature/new-dashboard) Add analytics widgets
# * c1d4e5f Add dashboard layout
# * 8a9b0c1 (main) Latest main commit
# * ... (main history)
# Now merge into main — it'll be a fast-forward (no merge commit!)
git checkout main
git merge feature/new-dashboard# You made 5 messy commits on your feature branch
git log --oneline
# f9a2b3c Fix typo again
# c1d4e5f Fix typo
# 8a9b0c1 oops forgot a file
# 7b8c9d0 WIP saving progress
# 6a7b8c9 Add user profile page
# Interactive rebase of the last 5 commits
git rebase -i HEAD~5
# Your editor opens with:
# pick 6a7b8c9 Add user profile page
# pick 7b8c9d0 WIP saving progress
# pick 8a9b0c1 oops forgot a file
# pick c1d4e5f Fix typo
# pick f9a2b3c Fix typo again
# Change to:
# pick 6a7b8c9 Add user profile page
# squash 7b8c9d0 WIP saving progress
# squash 8a9b0c1 oops forgot a file
# squash c1d4e5f Fix typo
# squash f9a2b3c Fix typo again
# Save and close. Git combines all into one commit.
# You'll be prompted to write the final commit message:
# 'Add user profile page with avatar and bio section'
# Result — clean single commit:
git log --oneline
# a1b2c3d Add user profile page with avatar and bio sectionPro Tips — Senior Dev Insights
git push --force-with-lease is safer than --force — it checks that no one else has pushed to the branch since your last fetch.
Configure your editor for better interactive rebase: git config --global core.editor "code --wait".
git rebase -i --autosquash combined with git commit --fixup lets you mark commits to be auto-squashed during rebase.
After squashing commits with rebase, your commit count on the PR will change — let reviewers know so they're not confused by the history rewrite.
Common Developer Pitfalls
Rebasing a branch that teammates are also working on — this forces everyone to reset their local branch.
git push --force-with-lease after rebasing a pushed branch — a regular push will be rejected because history diverges.Using interactive rebase to rewrite commits already in main — this is extremely disruptive to an entire team.
git rebase --abort always available, you can safely experiment.Interview Mastery
Use rebase when: (1) you want to update a feature branch with latest main changes while keeping history linear, (2) you want to squash/clean up messy local commits before opening a PR, (3) your team prefers linear git log history. Use merge when: (1) integrating finished, reviewed PRs into main, (2) you want to preserve the true history of parallel development, (3) the branch has been shared and you can't rewrite history.
Never rebase commits that have already been pushed to a shared (public) branch. Rebasing rewrites commit history by creating new SHA hashes. If others have already cloned or pulled those commits, their history will diverge from yours after the rebase, causing serious synchronization problems. Rebase is safe only on local commits or branches that only you are using.
squash: combines the commit with the previous one, and lets you edit the combined commit message. fixup: same as squash but automatically discards the squashed commit's message. reword: keeps the commit's changes as-is but opens an editor to let you rewrite the commit message.
Real-World Blueprint
git rebase -i HEAD~6 and squash them into 2 clean logical commits. The reviewer sees clean, professional commits instead of a messy diary of their working process. The PR gets approved faster and the main branch history stays pristine.Hands-on Lab Exercises
git rebase -i HEAD~4 to squash them into one clean commit.Make your feature branch fall behind main by adding commits to main. Then rebase your feature branch onto main and observe how git log changes.
git rebase --abort: start a rebase that will have conflicts, then abort it and verify your branch is unchanged.reword in interactive rebase to fix a commit message that has a typo.Real-World Practice Scenarios
Your feature branch has 8 commits including 'wip', 'fix', 'forgot file', 'ugh another fix'. Before opening a PR, how do you clean this up?
main and now has merge conflicts with it. Should you merge main into your branch, or rebase onto main? Why?A junior developer rebased their branch that 3 colleagues are also working on and force-pushed. What went wrong and how do teammates recover?
You want to split one big commit into two smaller logical commits. How would you use interactive rebase to do this?
Git Rebase & Advanced History
TL;DR — Quick Summary
- Rebase replays your commits on top of another branch — creating clean, linear history.
- Interactive rebase (
git rebase -i HEAD~N) lets you squash, reorder, edit, and delete commits. - Golden Rule: Never rebase commits already pushed to a shared branch.
- Use rebase for local cleanup; use merge for integrating into shared branches.
Overview
📐 Rebase: Rewriting the Story
While git merge preserves the complete, branching history of your project, git rebase takes a different approach — it rewrites your commits as if they happened on top of a different starting point, creating a perfectly linear history.
Imagine your feature branch diverged from main 10 commits ago. Instead of merging (which creates a merge commit), rebasing replays your feature branch commits, one by one, on top of the current tip of main. The result looks like you wrote your feature after all those main commits — even if you actually wrote it before.
🆚 Merge vs. Rebase at a Glance
- Merge: Non-destructive. Preserves true history. Creates merge commits. History can get "noisy" on busy projects.
- Rebase: Rewrites history. Creates clean linear history. No merge commits. Makes
git loga joy to read.
⚡ Interactive Rebase — The Power Tool
Interactive rebase (git rebase -i) lets you rewrite the last N commits however you like:
- squash: Combine multiple commits into one
- reword: Change a commit message
- edit: Pause and amend a specific commit
- drop: Delete a commit entirely
- reorder: Move commits up or down
The Golden Rule of Rebasing: Never rebase commits that have been pushed to a shared branch. Rebase rewrites history — if others have those commits, you'll create diverging histories and chaos.
Deep Dive Analysis
Here's a visual of what rebase does: <strong>Before rebase:</strong> <code>main: A - B - C - D</code> <code>feature: A - B - E - F</code> (branched off after B) <strong>After <code>git rebase main</code> from feature branch:</strong> <code>main: A - B - C - D</code> <code>feature: A - B - C - D - E' - F'</code> (E and F replayed on top of D) E' and F' are new commits with new SHA hashes — same changes, different parents. This is why rebasing <em>rewrites</em> history.
Implementation Reference
# Scenario: your feature branch is behind main by several commits
git checkout feature/new-dashboard
# Rebase: replay your feature commits on top of current main
git rebase main
# Git will replay your commits one by one
# If a conflict occurs at any step, Git pauses and shows:
# CONFLICT (content): Merge conflict in src/Dashboard.jsx
# Resolve the conflict in the file, then:
git add src/Dashboard.jsx
git rebase --continue # continue replaying remaining commits
# Or to completely abandon the rebase:
git rebase --abort
# After successful rebase, your branch is 'ahead' of main cleanly
git log --oneline --graph
# * f9a2b3c (HEAD -> feature/new-dashboard) Add analytics widgets
# * c1d4e5f Add dashboard layout
# * 8a9b0c1 (main) Latest main commit
# * ... (main history)
# Now merge into main — it'll be a fast-forward (no merge commit!)
git checkout main
git merge feature/new-dashboard# You made 5 messy commits on your feature branch
git log --oneline
# f9a2b3c Fix typo again
# c1d4e5f Fix typo
# 8a9b0c1 oops forgot a file
# 7b8c9d0 WIP saving progress
# 6a7b8c9 Add user profile page
# Interactive rebase of the last 5 commits
git rebase -i HEAD~5
# Your editor opens with:
# pick 6a7b8c9 Add user profile page
# pick 7b8c9d0 WIP saving progress
# pick 8a9b0c1 oops forgot a file
# pick c1d4e5f Fix typo
# pick f9a2b3c Fix typo again
# Change to:
# pick 6a7b8c9 Add user profile page
# squash 7b8c9d0 WIP saving progress
# squash 8a9b0c1 oops forgot a file
# squash c1d4e5f Fix typo
# squash f9a2b3c Fix typo again
# Save and close. Git combines all into one commit.
# You'll be prompted to write the final commit message:
# 'Add user profile page with avatar and bio section'
# Result — clean single commit:
git log --oneline
# a1b2c3d Add user profile page with avatar and bio sectionCommon Pitfalls
- •Rebasing a branch that teammates are also working on — this forces everyone to reset their local branch.
- •Forgetting <code>git push --force-with-lease</code> after rebasing a pushed branch — a regular push will be rejected because history diverges.
- •Using interactive rebase to rewrite commits already in main — this is extremely disruptive to an entire team.
- •Being afraid of rebase — with <code>git rebase --abort</code> always available, you can safely experiment.
Key Takeaways
Hands-on Practice
- ✓Create a feature branch with 4 messy commits ('wip', 'fix', 'more fix', 'final'). Use <code>git rebase -i HEAD~4</code> to squash them into one clean commit.
- ✓Make your feature branch fall behind main by adding commits to main. Then rebase your feature branch onto main and observe how git log changes.
- ✓Practice <code>git rebase --abort</code>: start a rebase that will have conflicts, then abort it and verify your branch is unchanged.
- ✓Use <code>reword</code> in interactive rebase to fix a commit message that has a typo.
Expert Pro Tips
Interview Preparation
Q: When would you use rebase over merge?
Master Answer:
Use <strong>rebase</strong> when: (1) you want to update a feature branch with latest main changes while keeping history linear, (2) you want to squash/clean up messy local commits before opening a PR, (3) your team prefers linear git log history. Use <strong>merge</strong> when: (1) integrating finished, reviewed PRs into main, (2) you want to preserve the true history of parallel development, (3) the branch has been shared and you can't rewrite history.
Q: What is the Golden Rule of rebasing?
Master Answer:
Never rebase commits that have already been pushed to a shared (public) branch. Rebasing rewrites commit history by creating new SHA hashes. If others have already cloned or pulled those commits, their history will diverge from yours after the rebase, causing serious synchronization problems. Rebase is safe only on local commits or branches that only you are using.
Q: What is the difference between squash, fixup, and reword in interactive rebase?
Master Answer:
<strong>squash</strong>: combines the commit with the previous one, and lets you edit the combined commit message. <strong>fixup</strong>: same as squash but automatically discards the squashed commit's message. <strong>reword</strong>: keeps the commit's changes as-is but opens an editor to let you rewrite the commit message.
Industrial Blueprint
"A developer has 6 commits on their feature branch including 'WIP', 'fix typo', and 'forgot to add file'. Before opening the PR, they run <code>git rebase -i HEAD~6</code> and squash them into 2 clean logical commits. The reviewer sees clean, professional commits instead of a messy diary of their working process. The PR gets approved faster and the main branch history stays pristine."
Simulated Scenarios
© 2026 DevHub Engineering • All Proprietary Rights Reserved
Generated on March 7, 2026 • Ver: 4.0.2
Document Class: Master Education
Confidential Information • Licensed to User