Skip to main content

Rebasing after originated branch is squash merged to master

When a feature branch, such as feat/feature-1, is squash merged into master, any branches based on it (e.g., feat/feature-2) need to be rebased to reflect the new state of master. Considering that the PR branch has been deleted after merge, so the following process will help you rebase successfully.


Fetch deleted PR references

First, run the following command to ensure you have access to all remote references, including deleted PR branches:

git fetch origin +refs/*:refs/remotes/origin/*
  • What this command does: This command fetches all references, even those that were automatically deleted after the PR was merged.

Locate the original branch for Rebasing

Next, locate the deleted branch that was merged via squash using:

git branch -r | grep "pull/PR_NUMBER/head"
  • Note: Replace PR_NUMBER with the actual PR number. This will give you access to the latest version of the deleted branch.

Rebase feature branch onto master

Once you have identified the correct branch reference, rebase your feature branch (e.g., feat/feature-2) onto master:

# On feat/feature-2 branch
git rebase --onto master origin/pull/PR_NUMBER/head
  • What this does:
    • git rebase --onto master: Rebases the branch starting from the point where it branched from feat/feature-1 onto master.
    • Instead of giving directly master, it is also possible to give the commit hash of the commit where the feat/feature-1 was merged into master. This might be needed if the changes in feature-2 is not yet compatible with the ones later in master.
    • origin/pull/PR_NUMBER/head: Uses the latest commit from the original feat/feature-1 branch before it was squashed and merged.

Verifying Changes:

After the rebase, verify the new commit history with:

git log --oneline -30 | cat

Ensure that the changes align with the intended commits after the rebase process.


Resolving Conflicts

During the rebase, you may need to resolve conflicts. Always pay careful attention to conflicts that arise and resolve them thoughtfully to maintain consistency with the changes from master.


Branch Tree for Squash Merge Scenario

Before Squash Merge of feat/feature-1 into master

A---B---C  master
\
D---E---F feat/feature-1
\
G---H feat/feature-2

Current status:

master...feature-1 -> 3 commits ahead, 1 commit behind
master...feature-2 -> 4 commits ahead, 1 commit behind
feature-1...feature-2 -> 2 commits ahead, 1 commit behind

After Squash Merge of feat/feature-1 into master

In repository, you can still access to reference of the branch even if ti was deleted.

A---B---C---S master
\
D---E---F origin/pull/PR_NUMBER/head (deleted feat/feature-1)
\
G---H feat/feature-2

= (S is the squash merge commit representing all changes from feat/feature-1. origin/pull/PR_NUMBER/head retains commits D, E, F as they originally were, and feat/feature-2 is still based on these commits.) If the feature-2 branch was kept rebased on top of the feat/feature-1 branch, it would have the F commit as the base, and it would be easier to rebase it onto the master branch.

Current status:

master...feature-2 -> 4 commits ahead, 2 commit behind

After Rebasing feat/feature-2 onto master with git rebase --onto master origin/pull/PR_NUMBER/head

A---B---C---S master
| \
| G'---H' feat/feature-2
\
D---E---F origin/pull/PR_NUMBER/head (deleted feat/feature-1)

(G' and H' are the rebased versions of commits G and H.)

Current status:

master...feature-2 -> 2 commits ahead