Rebasing Onto A Squashed Commit | Ellen Shapiro
When you're using Github's nice "Squash and Merge" button (or the GitLab equivalent, or
git merge --squash
Let's say I have
master
fix
m
n
o
o
feature
p
q
r
| (branch feature) | commit r | commit q | commit p / / / | (branch fix) | commit o | commit n | commit m / / / -/ | (master)
Next, I'd make a PR from branch
fix
master
| (branch feature) | commit r | commit q PR | commit p \ / \ / \ / | (branch fix) | commit o | commit n | commit m / / / -/ | (master)
Once that PR is merged, you wind up with something which looks something like this:
| (branch feature) | commit r | commit q | commit p | commit o | commit n | commit m \ \ (master) \ / including the squashed commits of `fix` branch: m, n, and o \-/ | | (master~1)
If I merge branch
feature
master
fix
master
Alternatively, if I merge branch
feature
fix
master
If I try to do a vanilla
rebase
rebase
m
n
o
This is because the metadata about the individual commits that made up the squashed merge are gone. In fact, this is the only difference between a squashed merge and a normal merge: Both put the merged commits on top of the destination branch, but while a normal merge does this in a special merge commit that includes metadata about the commit hashes of the branches that have been merged, a squash merge omits that metadata, and "pretends" the merge commit is a normal commit.
Now, if you've got a branch which you created off of the commits which were squashed and merged, using a plain vanilla
rebase
This gets annoying very quickly. I asked in our Slack if anyone knew a good way around this. A few people banged their heads together, and we wound up with an answer that takes the commits at the end of branch
feature
| PR | | (branch feature) | commit r | commit q | commit p \ \ \ \- | | (master) including squashed commits of `fix` branch
There's a slightly obscure
git rebase
git checkout
git rebase --onto master [hash for commit o] [hash for commit r]
What this does is tell Git that it should rebase a range of commits on to
master
One thing to note is that this exact command will cause the result to appear as a
detached HEAD
HEAD
feature
feature
reset --hard
Now, you're able to make a PR that looks like the most recent ASCII art above, and have a clean commit history while still taking advantage of branching, squashing, and merging.