`git rebase --onto` Is the Branch Surgery Command You Need When One Topic Branch Contains Two Stories
A practical guide to `git rebase --onto` for developers who need to move part of a branch, detach work from the wrong base, or cleanly transplant commits without rewriting everything by hand.
Why this command matters: a lot of Git pain comes from realizing your branch is based on the wrong place, or that one feature branch secretly contains two unrelated ideas.
git rebase --ontois the clean tool for that exact mess.
What git rebase --onto actually does
Most developers learn git rebase as “move my branch on top of another branch.” That is useful, but incomplete. The more powerful form is:
git rebase --onto <newbase> <upstream> <branch>Git’s own documentation shows the classic example:
git rebase --onto master next topicThat means: take the commits in topic that are not in next, and replay them onto master.
The reason this matters is that Git is not rebasing “the whole branch” in a vague way. It is rebasing a specific commit range. Once you understand that, the command stops feeling magical and starts feeling surgical.
The real-world problem it solves
Here is the mistake many teams make:
- you branch from
feature-a - you start working on
feature-b - later you realize
feature-bshould have been based onmain
Now your branch history contains valid work, but it is attached to the wrong parent line. If you merge as-is, reviewers have to mentally subtract the unrelated base commits. That makes review worse and riskier.
git rebase --onto lets you transplant only the part you actually want.
A concrete example
Suppose your graph looks like this:
mainhas stable commitsfeature-aadds old experimental workfeature-bwas created fromfeature-a, but should really stand on its own
You can move feature-b off feature-a and onto main like this:
git rebase --onto main feature-a feature-bThat says:
- find commits reachable from
feature-b - exclude the part already contained in
feature-a - replay the remaining commits onto
main
This is much cleaner than making a new branch and cherry-picking commit by commit unless you truly need manual control over each commit.
Why this is better than panic-cherry-picking
Cherry-pick is fine, but many developers use it as a reflex because they do not trust rebase. The problem is that panic-cherry-picking often creates:
- duplicated commits
- missed commits
- changed order
- extra cleanup work when conflicts happen
git rebase --onto works better when the underlying problem is “this contiguous set of commits belongs somewhere else.” That is exactly its job.
Where people get confused
The command becomes dangerous when you do not know what <upstream> means in your case. Developers often guess, and guessing in history surgery is how you end up rewriting the wrong slice.
Before using it, inspect the graph:
git log --oneline --graph --decorate --allThat one command is often the difference between a clean history repair and an avoidable cleanup session.
Conflict handling is still normal Git work
git rebase --onto does not remove the need for judgment. If the rebased commits depended on code from the old base, conflicts may be legitimate. That is not Git being hostile. It is Git telling you the old branch relationship mattered more than you thought.
When conflicts appear:
- resolve them carefully
- run tests
- continue with
git rebase --continue - abort with
git rebase --abortif the plan was wrong
The right response is not fear. It is verification.
The highest-value use case
The best use of --onto is not “being clever with Git.” It is making review smaller and more truthful. If one branch accidentally contains two stories, separate them before review instead of asking teammates to decode your accident.
That directly improves:
- PR clarity
- rollback safety
- merge confidence
- team trust in history
Final recommendation
Learn git rebase --onto before you need it under pressure. It is one of the few Git commands that can turn a messy branch situation into a clean, reviewable history without forcing you into manual cherry-pick theater.