Understanding git rebase so it sticks

I endlessly misremember how to use git rebase. That ends today. Here are my notes to help me remember.

Rebase is traditionally documented as:

git rebase [--onto newbase] [upstream [branch]]

This is confusing for several reasons. A slight improvement is to rename the args:

git rebase [--onto target] [exclude [include]]


  • include is the tip of the branch to be transplanted. If omitted, it defaults to the current branch.
  • exclude excludes all its ancestors from being transplanted. Hence the transplanted branch will have its tip at include, and its base at the common ancestor of include and exclude. If --onto isn’t specified, exclude is also used as the destination for the transplant.
  • target is the place to transplant the branch to. If not specified, it defaults to the value of exclude.

Hence, a simple before and after:

o---o---o---o---o---o exclude
      1---2---3 current branch
                or include
git rebase exclude [include]
o---o---o---o---o---1---2---3 current branch
                              or include

See how the commits to be transplanted start at include and go back to the common ancestor of that and exclude. Since --onto isn’t specified, exclude is also used as the transplant destination.

Or a more complex one:

 o---o---o---o---o target
       o---o---o exclude
             1---2 current branch
                   or include
git rebase --onto target exclude [include]
o---o---o---o---o---1---2 current branch
     \                    or include

Again, the commits to be transplanted are defined by include and exclude, but this time a separate destination is specified using --onto.

Leave a Reply