Git Rebase –onto: Mastering Professional Git History Surgery

Git tutorial - IT technology blog
Git tutorial - IT technology blog

Mastering Git Rebase –onto in 5 Minutes

Have you ever accidentally started coding feature-B based on feature-A, only to realize feature-A was cancelled or became too messy? At that point, you just want to pick your specific commits and move them to main without dealing with the chaos on the old branch. Don’t waste time running cherry-pick for each commit; git rebase --onto will solve it in an instant.

When you encounter this situation, remember this “magical” syntax:

bash
git rebase --onto <target-branch> <old-source-branch> <current-branch>

Suppose you are on feature-B and want to move directly onto main, skipping feature-A:

bash
git rebase --onto main feature-A feature-B

Think of this command as: “Take the code from feature-B (excluding what is already in feature-A), and place it on top of main”. With just one line, your Git history will be as smooth as if the branches were never tangled.

Understanding How –onto Works

Why is this command so powerful? The secret lies in how Git selects commits. While a standard rebase moves the entire branch, --onto allows you to specify an exact commit range to relocate.

The detailed structure consists of three components:

  • newbase: The new destination (where you want to place the commits).
  • upstream: The reference point Git uses to identify which parts to cut. Git ignores everything from this point backwards.
  • branch: The branch you want to move (optional if you are already on that branch).

Many developers resort to manually cherry-picking commits one by one. This isn’t wrong, but if you have 15-20 commits, it’s extremely time-consuming and prone to hash errors.

Real-world Scenario: Overlapping Features

Consider a common commit graph like this:


o---o---o (main)
     \
      o---o (feature-A)
           \
            o---o---o (feature-B)

Context: feature-A is still a work-in-progress, but your manager asks you to push feature-B to main immediately for a client demo. If you use a regular rebase main, Git will pull in all the buggy code from feature-A into main. That’s a disaster!

The solution with --onto:

bash
git rebase --onto main feature-A feature-B

The result:


o---o---o (main)
     |   \
     |    o'---o'---o' (new feature-B branching from main)
      \
       o---o (old feature-A remains in place)

Branch feature-B is now completely free of any traces from feature-A. This is the best way to clean up your commit history before creating a Pull Request for review.

Advanced Technique: Deleting Faulty Commits in the Middle of a Branch

Another extremely useful application is deleting a group of commits in the middle of a branch without using rebase -i. Suppose you have a chain of commits A -> B -> C -> D -> E, but commits B and C accidentally contain API keys or sensitive passwords.

bash
git rebase --onto <hash-of-A> <hash-of-C> master

This tells Git: “Take all commits after C (i.e., D and E), and attach them directly to A“. You’ve just removed sensitive data in seconds.

Hard-earned Lessons and Safety Tips

Using rebase means you are rewriting history. Always remember one golden rule: Never rebase on branches that have been pushed to the server and are being shared with others.

If you must push after a rebase, get into the habit of using:

bash
git push --force-with-lease

This command is safer than --force because it will fail if the server has new commits that you haven’t fetched yet. It prevents you from accidentally overwriting your colleagues’ work—a very common mistake in team environments.

Pro-tip: Before running any complex Git command, create a backup branch using git branch backup-branch. If things go wrong, just delete the broken branch and rename the backup. Safety first!

Summary of Steps

  1. Identify 3 points: Destination (newbase), the cut-off point (upstream), and the branch to move.
  2. Create a backup branch just in case.
  3. Run the git rebase --onto command.
  4. Resolve conflicts if they occur. Conflicts are perfectly normal when switching to a new code base.
  5. Verify the results with git log --oneline --graph.
  6. Push using --force-with-lease.

Hopefully, this guide makes you more confident when dealing with complex branch structures. git rebase --onto isn’t difficult; it just requires you to think clearly about “where to cut” and “where to paste.” Happy committing!

Share: