Search code examples
gitversion-controlgit-rebase

Git: How to rebase to a specific commit in past?


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.


Solution

  • 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)