Rebase without re-checkout

TL;DR: when using multiple branches, prefer to use “git rebase –onto origin/master origin/master ${branch}” if you want to checkout and then rebase a branch.

Let’s say you have the working history:

       /-*-* A
*-*-*-*-*-*-* origin/master
        \-*-*-* B

and you want to push the branch A because your CL has been approved. You have to rebase A on origin/master, then build and run test and do git cl push. Once this is done, you now have the following history:

*-*-*-*-*-*-*-@ origin/master (after push)
        \-*-*-* B

Now you want to go back to work on B. Until recently, I used the following commands (striked-ed out as I now consider them broken):

$ git checkout B
$ git rebase origin/master

This has the disadvantage of marking as dirty all the files that are in the delta between the point B diverged from origin/master in addition to all the files modified in B since the branch was created.

There is however a better way:

$ git rebase –onto origin/master origin/master B

This will still rebase B on top of origin/master, but will not checkout B first, so only the files that have been modified in B will be touched and considered dirty by the build. Depending on how large the change in origin/master have been, this can be the difference between rebuilding thousand of files and rebuilding just a few tens.

Leave a Reply