I would like to rebase to a specific commit that is not the HEAD of the other branch, but going backwards:
A --- B --- C master
\
\-- D --- E topic
to
A --- B --- C master
\
\-- D --- E topic
How do I achieve this in an elegant and general way?
By general I mean that the target commit (B) may not necessarily be the direct ancestor of HEAD (I might as well rebase to A or a previous commit) and that there may be many more than just two commits on topic branch. I might also want to rebase from B to A.
Using git cherry-pick
git rebase
is a git cherry-pick
on steroids.
If you only have a few commits to move : you may use git cherry-pick
to pick them one by one
# move back to B
git checkout B
# start a branch here, and use it as the active branch
git checkout -b wip
# cherry-pick the commits you want to have
git cherry-pick D
git cherry-pick E
# if all went well : move the 'topic' branch to the current branch :
git checkout topic
git reset --hard wip
# delete the temporary 'wip' branch
git branch -d wip
Using git rebase
As mentioned in the comments : git rebase
can take extra options to move only a range of commits.
You can do the same as the above cherry-pick
sequence using :
git rebase --onto B master topic
Extra note : git rebase -i
git rebase
also has an --interactive|-i
flag :
git rebase -i --onto B master topic
With the -i
flag : before doing anything, git will open a text editor for you, where all the rebased commit will be listed.
This step has the obvious benefit of showing you what will be applied (before actually applying it), and also to describe more actions than just "picking that commit".
You can search the web for more complete tutorials on git rebase -i
, here is one :
Git Interactive Rebase, Squash, Amend and Other Ways of Rewriting History (thoughtbot.com)