Fixing Dependent Branches After Rebasing and Squashing
Setup
Main has the following commits:
A -> B -> C
You create a feature branch off of main
A -> B -> C (main)
\
G -> H -> I (feature)
and then another feature branch off feature
A -> B -> C (main)
\
G -> H -> I (feature)
\
J -> K (feature2)
Some changes are merged into main:
A -> B -> C -> D -> E -> F (main)
\
G -> H -> I (feature)
\
J -> K (feature2)
You want to rebase feature.
Scenario 1: Rebase without Squashing
You checkout feature and run git rebase -i main. Your history then looks like:
A -> B -> C -> D -> E -> F (main)
\ \
| G' -> H' -> I' (feature)
|
G -> H -> I -> J -> K (feature2)
You want to rebase feature2 onto feature. From feature2, run git rebase --onto I' I. The result will be:
A -> B -> C -> D -> E -> F (main)
\
G' -> H' -> I' (feature)
\
J' -> K' (feature2)
Scenario 2: Rebase and Squash.
You checkout feature and run git rebase -i main and squash commits. Your history then looks like:
A -> B -> C -> D -> E -> F (main)
\ \
| G' (feature)
|
G -> H -> I -> J -> K (feature2)
If you just run git rebase -i feature feature2, git will get confused and think the common ancestore is C. In reality, commits G, H, and I on feature2 are really squashed into G' on feature. To fix this, run the following from feature2: git rebase --onto feature HEAD~2. We're essentially telling git to only replay commits J and K onto feature. Our history will then look like:
A -> B -> C -> D -> E -> F (main)
\
G' (feature)
\
J' -> K' (feature2)