The Linux kernel project—with over 27 million lines of code and thousands of contributors—uses rebasing extensively. Meanwhile, many enterprise teams forbid it entirely. Why such different approaches to the same tool?
The rebase vs merge question isn't just about knowing two Git commands. It's a window into how you work on real teams, whether you understand distributed version control deeply, and whether you've learned the "golden rule" that prevents catastrophic history rewrites. This question quickly reveals developers who've moved beyond tutorials into real collaborative coding.
The 30-Second Answer
When you're in an interview and get hit with "What's the difference between rebase and merge?", here's what you need to communicate concisely:
Merge combines two branches by creating a new commit with two parents, preserving the complete history of both branches. Rebase takes your commits and replays them onto another branch, creating new commits with new hashes and resulting in a linear history. I use merge for integrating completed work into shared branches, and rebase for keeping my feature branch up-to-date with main before creating a pull request. The golden rule I always follow is to never rebase commits that have been pushed to a shared branch.
That last sentence is crucial. Mentioning the golden rule unprompted shows you understand the real-world consequences of rebasing, not just the mechanics.
The 2-Minute Answer
When an interviewer wants you to go deeper, this is your opportunity to demonstrate thorough understanding. Here's how I explain it in technical discussions:
Think of merge like recording a jam session. When you merge two branches, Git creates a new commit that says "these two musical tracks were combined here." Both original tracks are preserved exactly as they were recorded, and the merge commit documents the exact moment they came together. You can always go back and see exactly what each branch looked like before the merge. This is why merge is considered "non-destructive" - it doesn't change any existing commits.
Rebase, on the other hand, is like re-recording your parts over a new backing track. When you rebase your feature branch onto main, Git takes each of your commits and replays them one by one on top of the latest main. The result looks like you wrote all your code after everyone else's changes, even if you actually started weeks ago. The original commits are effectively replaced with new ones that have different parent commits and therefore different SHA hashes.
Here's where it gets interesting: because rebase creates new commits with new hashes, anyone who based work on your original commits now has a problem. Their work references commits that no longer exist in the same form. This is why the golden rule exists: never rebase commits that have been pushed to a shared repository where others might have based work on them.
A pattern that's served me well is using rebase to keep my local feature branch updated with main while I'm developing, but using merge when integrating my completed feature into the shared main branch. This gives me the clean history benefits of rebase during development while avoiding the dangers of rewriting shared history.
Understanding the Visual Difference
One technique that consistently impresses interviewers is sketching out what happens to the commit graph. Let me walk you through this because being able to draw it on a whiteboard demonstrates deep understanding.
Imagine you have a main branch with three commits (A, B, C), and you created a feature branch from commit B. You've made two commits on your feature branch (D, E). Here's what that looks like:
main: A---B---C
\
feature: D---E
When you merge the feature branch into main, Git creates a new merge commit (M) that has two parents: the latest commit on main (C) and the latest commit on feature (E). The graph now looks like this:
main: A---B---C-------M
\ /
feature: D---E---/
The merge commit M is like a knot tying two threads together. Both threads are preserved exactly as they were, and M documents where they came together.
Now let's see what rebase does instead. Starting from the same situation, when you rebase feature onto main, Git identifies the commits unique to feature (D and E), temporarily sets them aside, moves the feature branch pointer to point at C (the tip of main), and then replays D and E one at a time on top of C:
main: A---B---C
\
feature: D'---E'
Notice I've used D' and E' instead of D and E. These are new commits with different SHA hashes, even though they contain the same code changes as the originals. The original D and E still exist in Git's object database temporarily, but they're now orphaned and will eventually be garbage collected.
After rebasing, if you merge feature into main, it can be a "fast-forward" merge because feature is now directly ahead of main:
main: A---B---C---D'---E'
This linear history is easier to read and understand, which is why many teams prefer it.
The Golden Rule: When Rebase Becomes Dangerous
The candidates who impress me most are those who can explain not just how rebase works, but when it becomes dangerous. Let me illustrate with a scenario I've actually seen cause problems.
Imagine you're working on a feature branch and you've pushed it to the remote so your teammate can review your code or collaborate with you. Your teammate creates their own branch from yours to work on a related piece:
Your feature: A---B---C (pushed to origin)
\
Teammate's: D---E
Now you decide to rebase your feature branch onto the latest main to pick up some recent changes:
Your feature: A---B'---C' (rebased, new commits!)
Teammate's: D---E (still points to original C, which "no longer exists")
Your teammate's branch D and E are now based on commit C that has effectively been replaced by C'. When they try to push or you try to integrate their work, Git sees completely divergent histories. You'll get duplicate commits, confusing merge conflicts, and a lot of frustration.
The fix for this situation exists, but it's painful. Your teammate would need to rebase their work onto your new branch:
# Teammate's recovery steps
git fetch origin
git rebase origin/your-feature
# Or more drastically
git reset --hard origin/your-feature
git cherry-pick D EThis is error-prone and risks losing work. The lesson I share with my teams: if you've pushed commits to a branch where others might be basing work, treat those commits as immutable. Use merge instead of rebase.
The only exception is when you're absolutely certain you're the only one working on a branch. Even then, I recommend using git push --force-with-lease instead of git push --force. The --force-with-lease flag checks that the remote branch is where you expect it to be, refusing to push if someone else has added commits since you last fetched.
Interactive Rebase: The Senior Developer Skill
Interactive rebase is where Git goes from being a version control tool to being a storytelling tool. When I ask about interactive rebase in interviews, I'm checking whether the candidate understands that commit history is documentation, and like any documentation, it should be clear and purposeful.
Let me show you with code. Say you've been working on a login feature and your commit history looks like this:
abc123 Add login form
def456 Fix typo in login form
ghi789 Add validation to login form
jkl012 Fix validation bug
mno345 Add password strength indicator
pqr678 Fix password strength indicator styling
This history tells the story of your messy development process, which is normal and fine while you're working. But when it's time to create a pull request, you want to tell a clear story for your reviewers. Interactive rebase lets you transform this into:
abc123 Add login form with validation
def456 Add password strength indicator
Here's how you do it. Run git rebase -i HEAD~6 to interactively rebase the last 6 commits. Git opens your editor with something like:
pick abc123 Add login form
pick def456 Fix typo in login form
pick ghi789 Add validation to login form
pick jkl012 Fix validation bug
pick mno345 Add password strength indicator
pick pqr678 Fix password strength indicator styling
You edit this to:
pick abc123 Add login form
squash def456 Fix typo in login form
squash ghi789 Add validation to login form
squash jkl012 Fix validation bug
pick mno345 Add password strength indicator
squash pqr678 Fix password strength indicator styling
When you save and close, Git will squash those commits together and prompt you to write new commit messages. The result is a clean, logical history that tells the story of what you built, not how you stumbled through building it.
The available commands in interactive rebase give you powerful control:
The pick command keeps a commit as-is. The reword command lets you keep the commit but edit its message. The edit command pauses the rebase so you can amend the commit, useful if you need to add a forgotten file or fix something. The squash command combines a commit with the previous one and prompts you to write a new message. The fixup command is like squash but discards the commit message. The drop command removes a commit entirely.
A real scenario where I use interactive rebase frequently: sometimes I'll commit something and then realize I need to make a small fix. Rather than creating a new "Fix thing I just did" commit, I'll make the fix, stage it, and run git commit --fixup=abc123 where abc123 is the commit I'm fixing. This creates a commit labeled "fixup! Add login form". Later, when I run git rebase -i --autosquash HEAD~5, Git automatically reorders the fixup commits and marks them for squashing.
Handling Conflicts: The Real-World Challenge
Both merge and rebase can result in conflicts, but they handle them differently, and understanding this difference is crucial for interviews and real work.
With merge, you resolve all conflicts at once. Git tries to combine the two branch tips, finds all the places where automatic merging fails, marks them all as conflicted, and waits for you to resolve everything before creating the merge commit. If you have conflicts in five files, you fix all five, stage them, and complete the merge with a single commit.
With rebase, conflicts are handled commit-by-commit. Git replays each of your commits onto the target branch one at a time. If the first commit causes a conflict, you resolve it and continue. If the third commit causes a conflict, you resolve that too. This means you might resolve the same conflict multiple times if several of your commits touched the same lines.
Let me walk through the rebase conflict workflow:
# Start the rebase
git rebase main
# Git stops at the first conflicting commit
# CONFLICT (content): Merge conflict in src/auth.js
# Open the file and resolve the conflict
# The file will contain markers like:
<<<<<<< HEAD
const AUTH_URL = '/api/v2/auth';
=======
const AUTH_URL = '/api/v1/auth';
>>>>>>> feat: Add login form
# Edit the file to resolve the conflict
const AUTH_URL = '/api/v2/auth';
# Stage the resolved file
git add src/auth.js
# Continue to the next commit
git rebase --continue
# Repeat until all commits are replayedIf things go badly wrong during a rebase, you can always abort and return to your pre-rebase state:
git rebase --abortThis is one of the beautiful things about Git: it's very hard to lose work permanently. Even if you complete a rebase and realize it was a mistake, git reflog keeps a record of where your branch was before the rebase, and you can reset back to that state.
What Interviewers Are Really Looking For
After conducting hundreds of technical interviews, I can tell you exactly what the rebase vs merge question reveals about a candidate:
First, I'm looking for conceptual understanding. Can you explain how each operation affects the commit graph? If you can sketch the before and after diagrams, you've demonstrated that you understand Git's data model, not just its commands.
Second, I'm listening for awareness of the golden rule. When a candidate mentions unprompted that you should never rebase shared commits, it tells me they've either experienced the pain of violating this rule or learned from others who have. Either way, they'll be a safer team member.
Third, I'm evaluating real workflow experience. Can you describe your typical feature branch workflow? Do you understand why different teams might choose different approaches? Someone who can discuss the tradeoffs between a linear history and a preserved branch structure has clearly worked on real collaborative projects.
Fourth, I'm testing problem-solving ability. If I describe a scenario where a rebase went wrong, can you figure out how to recover? Knowledge of git reflog and how to use it to undo a bad rebase separates experienced developers from those who've only worked on simple projects.
Finally, I'm assessing team awareness. The best developers think about how their actions affect others. Knowing that rebase can break teammates' work shows you understand collaborative development, not just personal productivity.
Common Follow-Up Questions
Interviewers often dig deeper with follow-up questions. Here's how I'd answer the common ones:
"What's the difference between merge --squash and a rebase followed by merge?"
Great question, because both can result in cleaner history but in different ways. When you run git merge --squash feature, Git takes all the commits from the feature branch and combines them into a single set of staged changes on your current branch. You then commit those changes as a single commit. The original branch history isn't recorded in the merge, so you lose visibility into the individual commits.
With rebase followed by merge, you first rebase your feature branch onto main (creating new commits in a linear sequence), then merge the rebased branch into main. If main hasn't moved since you rebased, this is a fast-forward merge and your individual commits are preserved in the linear history.
The choice depends on whether you want to preserve individual commits. For a feature with logical, well-crafted commits, I'd use rebase + merge. For a branch with messy work-in-progress commits, squash merge gives a cleaner result.
"How do you undo a rebase that's already been pushed?"
This is a tricky situation because you've now shared rewritten history. First, use git reflog to find the commit before the rebase. Then reset to it with git reset --hard HEAD@{n}. Now you need to force push to update the remote, but be aware this will cause problems for anyone who pulled the rebased version. You'll need to coordinate with your team. This is why the golden rule is so important: it's much easier to avoid this situation than to recover from it.
"What's the difference between git reset and git revert?"
Both undo changes, but in fundamentally different ways. git reset moves the branch pointer backward and optionally modifies the staging area and working directory. It rewrites history by making commits unreachable. This is fine for local work but dangerous for shared branches.
git revert creates a new commit that undoes the changes from a previous commit. The original commit stays in history, and the new commit documents that you undid it. This is safe for shared branches because you're adding to history, not rewriting it.
My rule: use reset for local mistakes, use revert for shared branches.
"What is git cherry-pick and when would you use it?"
Cherry-pick copies a specific commit from one branch and applies it to another. Unlike merge or rebase, which work with entire branches, cherry-pick works with individual commits.
I use it when I need a specific bug fix from a release branch in my feature branch, when a commit was accidentally made on the wrong branch, or when I want to selectively apply changes without bringing in everything else. It's a precision tool for specific situations rather than an everyday operation.
The Real-World Workflow
Let me describe the workflow that's served me and my teams well over many projects. This is what I describe in interviews when asked about my Git workflow:
When I start a new feature, I create a branch from the latest main. As I work, I make commits frequently, even messy ones like "WIP" or "fix typo." These commits help me track my progress and provide save points I can return to if something goes wrong.
Periodically, especially if the feature takes more than a day or two, I update my branch with changes from main. I do this with rebase: git fetch origin && git rebase origin/main. This replays my commits on top of the latest main, ensuring I'm working with current code and catching any integration issues early.
Before creating a pull request, I clean up my commit history with interactive rebase. I squash the WIP commits into logical units, write clear commit messages that explain what each commit does and why, and make sure each commit represents a complete, working state of the code.
When my PR is approved, it gets merged into main. Some teams use squash merge here for a clean history; others use regular merge to preserve the individual commits. Either approach is fine as long as the team is consistent.
The key principles: rebase for updating local branches, merge for integrating into shared branches, and interactive rebase for cleaning up history before sharing.
Quick Reference: Rebase vs Merge at a Glance
| Aspect | Merge | Rebase |
|---|---|---|
| History preservation | Preserves complete history | Creates linear history |
| Commit modification | Creates new merge commit only | Creates new versions of all rebased commits |
| Safety for shared branches | Safe, doesn't modify existing commits | Dangerous, rewrites history |
| Conflict resolution | Resolve all at once | Resolve commit-by-commit |
| Use case | Integrating completed features | Updating local feature branches |
| Reversibility | Can revert the merge commit | Use reflog to recover |
| Best for | Shared branches, documenting integration | Personal branches, clean history |
Practice Questions with Answers
Test your understanding with these scenarios:
Question 1: You've been working on a feature branch for a week. Main has had 15 new commits during that time. How do you update your feature branch?
Answer: I would use rebase to maintain a linear history. First, I'd fetch the latest changes with git fetch origin. Then I'd rebase my feature branch onto main with git rebase origin/main. If there are conflicts, I'd resolve them commit-by-commit. After the rebase completes, I'd test to make sure everything still works. If I'd previously pushed the feature branch, I'd update the remote with git push --force-with-lease to ensure I don't accidentally overwrite any new commits someone else might have added.
Question 2: You notice that your third-to-last commit has a typo in the commit message. How do you fix it without changing the code?
Answer: I'd use interactive rebase with git rebase -i HEAD~3. In the editor, I'd change pick to reword for the commit with the typo. When I save and close, Git will open another editor where I can fix the commit message. This creates a new commit with the corrected message (and new hash), along with new versions of the subsequent commits since their parent changed.
Question 3: Your colleague tells you their branch is "broken" after you rebased your shared feature branch and force-pushed. What happened and how do you help them?
Answer: When I rebased and force-pushed, I replaced the commits they had based their work on with new commits that have different hashes. Their branch is now pointing to "orphaned" commits that no longer exist in the shared history. To fix this, they have a few options: they can rebase their branch onto my new feature branch with git fetch && git rebase origin/feature. Alternatively, they can reset to my new branch and cherry-pick their unique commits. The real lesson here is that I shouldn't have rebased a shared branch. Going forward, we should use merge for updating shared branches or coordinate more carefully before rebasing.
Question 4: You made 8 commits on your feature branch, but many are small fixes and WIP commits. You want to create a clean PR with 3 logical commits. Walk through the process.
Answer: I'd use interactive rebase with git rebase -i HEAD~8. In the editor, I'd identify which commits belong together logically. I'd mark the first commit of each logical group as pick and mark the subsequent related commits as squash or fixup. For example, if commits 1-3 are all about adding a form, I'd pick commit 1 and squash commits 2 and 3 into it. After saving, Git will combine the squashed commits and prompt me to write new commit messages for each logical group. The result is 3 clean commits that tell a clear story of what I built.
Wrapping Up: The Mindset That Gets You Hired
The rebase vs merge question is ultimately about demonstrating that you think about Git as a communication tool, not just a backup system. The best developers understand that commit history is documentation for future developers, including your future self, who will need to understand why changes were made.
When you answer this question well, you show that you've moved beyond following Git tutorials to actually understanding how version control supports team collaboration. You demonstrate awareness of how your actions affect others. You show that you can weigh tradeoffs and make pragmatic decisions based on context.
The candidates who get hired aren't just those who can recite the commands. They're the ones who can explain their thinking, acknowledge the tradeoffs, and describe how they'd work effectively on a real team. That's what this question is really testing, and now you're ready to ace it.
Ready to Master Git Interview Questions?
Understanding rebase vs merge is essential, but it's just one piece of the version control puzzle. Our comprehensive question bank covers everything from Git internals and branching strategies to advanced workflows that senior developers are expected to know.
Access 800+ Git and DevOps Interview Questions and practice with real interview scenarios, detailed explanations, and expert tips that helped thousands of developers land their dream jobs.
Whether you're preparing for your first developer role or targeting senior positions at top tech companies, our curated question collection gives you the edge you need. Start practicing today and walk into your next interview with confidence.
Related Articles
If you found this helpful, check out these related guides:
- Complete DevOps Engineer Interview Guide - comprehensive preparation guide for DevOps interviews
- 5 Tricky Git Interview Questions - Git internals and advanced commands
- System Design Interview Guide - Scalability, reliability, and distributed systems
- CI/CD & GitHub Actions Interview Guide - Git workflows that trigger CI/CD pipelines
