Rebasing a Branch Created from Another Branch to Main After Squash Merge: A Step-by-Step Guide

Rebasing a branch made of another branch to the main branch gets tricky after a squash merge. In this article, I provide a step-by-step guide to tackle this problem.

What is the issue?

Before and after rebase

In a project using Git as a version control system, we have a main branch from which we have created a feature branch (the blue branch). While making changes in this branch, we decided to add another feature on top of the changes we made in this feature branch, so we created another feature branch (referred to as the red branch) on top of the earlier branch. Now we squash merge the first feature branch to the main branch. (Note: the diagram is drawn to make it easier to understand the structure of branches and commits. When we do a squash merge, the new m3 commit will have only one parent.)

Now, we want to rebase the red branch to the latest commit on the main branch. Though in this simple case, it is not needed, let’s imagine a situation where we need to do this to ensure we have the latest changes on the main branch (supposedly with some extra commits after m3). What will happen?

If we try to rebase, something strange happens. The history of the red branch doesn’t only include b1 and b2 but also a1 and a2. Why so? Simply because b1 is based on a2, which is based on a1. Because of the nature of squash merge, we don’t have a1 and a2 on m3. We only have their changes but not any reference to those commits. So there are possibilities of conflict between a1 and a2 changes and the changes in m3 (if there are more commits, reverting each other in the blue branch).

What to do? Should we resolve all of these conflicts? What is the point? We only want to rebase the red branch with its own commits on the main branch, which now has the changes made in the blue branch. Why include other commits? Well, this is what this post is all about.

What to do?

We must clean up the red branch history while rebasing it to the main branch. Now let’s go step by step:

  1. If this is your first time doing this, it is good to make a backup by making a copy of the branch by git branch --copy red-branch-backup.
  2. Make sure you know the first commit of the red branch, either by its commit SHA or the commit message (if it is unique and meaningful).
  3. While on the red branch, run git rebase --interactive main command. You get a text file open in your editor. This (temporary) file lists all the commits in the red branch compared to the new base commit (m3). Here, you can do different things, but we only want one thing: Remove all the lines containing commits from the blue branch.
  4. Save the temporary file. Now you notice rebase starts to apply changes from the remaining commits you left in the file (should be b1 and b2). You are done if your b1 and b2 commits don’t conflict with the main branch. Otherwise, resolve conflicts as you usually do.
  5. You can check the commit history. You should have the same commits but with new SHA (since they are different commits with different histories than b1 and b2).
  6. You are done.

Is there any better way to achieve the same result? Please share it in the comments.