Let's say I've developed a feature on branch1
and sent it out for code review using a GitHub Pull Request. While it's being reviewed, I do some follow-on work on branch2
.
branch2 -> D --> E --> F
/
branch1 -> A --> B --> C
/
master M
My reviewer loves my work! No changes are required. I merge the pull request for branch1
using GitHub's Squash and merge feature.
After running git pull
on master
and deleting branch1
, I'm left with this situation:
branch2 -> A --> B --> C -> D --> E --> F
/
master M --> S
To send out a clean-looking PR for branch2
, I'd like to get my commit tree looking like this:
branch2 -> D' --> E' --> F'
/
master M --> S
The code at S
(the commit generated by "Squash and merge" for branch1
) is identical to C
, since it's just the squashed version of A --> B --> C
.
One way to achieve this would be to run a sequence like this on branch2
:
git reset --hard S
git cherry-pick D E F
But listing all the commits out this way gets tedious, and this really feels like a rebase. git rebase master
won't work, of course, since commits A
, B
and C
need to disappear.
What's the best way to rebase a branch off a squashed version of one of its ancestor commits?
cherry-pick D..F
– GymnosophistD^
so as to copyD
itself. The range notation is akin to a half-open interval, excluding the start and including the end. (Though actually it's a set-subtraction!) – Hickie