Skip to content

Rebase Onto

Master branch, with two interdependent feature branches, foo and bar:

gitGraph
    commit id: "m1"
    commit
    commit
    commit id: "m4" tag: "master"
    branch foo
    checkout foo
    commit
    commit
    commit
    commit id: "f4" tag: "foo"
    branch bar
    checkout bar
    commit
    commit
    commit
    commit id: "b4" tag: "bar"

Let's say master gets a few commits:

gitGraph
    commit id: "m1"
    commit id: "m2"
    commit id: "m3"
    commit id: "m4" tag: "master"
    branch foo
    checkout foo
    commit id: "f1"
    commit id: "f2"
    commit id: "f3"
    commit id: "f4" tag: "foo"
    branch bar
    checkout bar
    commit id: "b1"
    commit id: "b2"
    commit id: "b3"
    commit id: "b4" tag: "bar"
gitGraph
    branch master
    commit id: "m1"
    commit id: "m2"
    commit id: "m3"
    commit id: "m4"
    branch foo
    checkout foo
    commit id: "f1"
    commit id: "f2"
    commit id: "f3"
    commit id: "f4" tag: "foo"
    branch bar
    checkout bar
    commit id: "b1"
    commit id: "b2"
    commit id: "b3"
    commit id: "b4" tag: "bar"
    checkout master
    commit id: "m5"
    commit id: "m6"
    commit id: "m7" tag: "master"

And now we go to foo and use git rebase master:

gitGraph
    branch master
    commit id: "m1"
    commit id: "m2"
    commit id: "m3"
    commit id: "m4"
    commit id: "m5"
    commit id: "m6"
    commit id: "m7"
    branch foo
    checkout foo
    commit id: "f1"
    commit id: "f2"
    commit id: "f3"
    commit id: "f4"
    checkout master
    branch old-foo
    checkout old-foo
    commit id: "f1"
    commit id: "f2"
    commit id: "f3"
    commit id: "f4" tag: "fec1d4"
    branch bar
    checkout bar
    commit id: "b1"
    commit id: "b2"
    commit id: "b3"
    commit id: "b4"

foo, as its known by name, is no longer part of the history of bar. Instead, bar begins with four commits that used to be known as foo, but now have no name. I've given the old foo a commit id, just for the purpose of this description. fec1d4 is the commit id of the old foo.

Question is: how do I get bar onto the new foo, so everything looks like the first picture?

Answer: git rebase --onto foo fec1d4 bar

Now I have:

gitGraph LR:
    commit id:"A"
    commit id:"B"
    commit id:"C"
    commit id:"D"
    commit id:"E"
    commit id:"F"
    commit id:"G"
    branch foo
    checkout foo
    commit id:"H"
    commit id:"I"
    commit id:"J"
    commit id:"K"
    branch bar
    checkout bar
    commit id:"L"
    commit id:"M"
    commit id:"N"
    commit id:"O"
    checkout main
    branch fec1d4
    checkout fec1d4
    commit id:"P"
    commit id:"Q"
    commit id:"R"
    commit id:"fec1d4" tag:"fec1d4"
    branch a661bd
    checkout a661bd
    commit id:"S"
    commit id:"T"
    commit id:"U"
    commit id:"a661bd" tag:"(a661bd) DANGLING"
gitGraph
    branch master
    commit id: "m1"
    commit id: "m2"
    commit id: "m3"
    branch old-foo
    commit id: "f1"
    checkout master
    commit
    checkout old-foo
    commit
    checkout master
    commit
    checkout old-foo
    commit
    checkout master
    commit tag: "master"
    branch foo
    merge foo
    commit
    checkout old-foo
    commit id: "f4" tag: "fec1d4"
    checkout foo
    commit
    commit
    checkout old-foo
    commit
    branch old-bar
    commit
    checkout foo
    commit tag: "foo"
    branch bar
    commit
    checkout old-bar
    commit id: "b4" tag: "a661bd DANGLING"
    checkout bar
    commit id: "b1'"
    commit id: "b2'"
    commit id: "b3'"
    commit id: "b4'" tag: "bar"

Note that fec1d4 didn't itself get rebased, but everything after it until bar did, onto foo (the new foo).

You can also manage this sort of situation mostly automatically using topgit.

    commit id:"A"
    commit id:"B"
    commit id:"C"
    commit id:"D"
    commit id:"E"
    commit id:"F"
    commit id:"G"
    branch foo
    checkout foo
    commit id:"H"
    commit id:"I"
    commit id:"J"
    commit id:"K"
    branch bar
    checkout bar
    commit id:"L"
    commit id:"M"
    commit id:"N"
    commit id:"O"
    checkout main
    branch fec1d4
    checkout fec1d4
    commit id:"P"
    commit id:"Q"
    commit id:"R"
    commit id:"fec1d4" tag:"(fec1d4)"
    branch a661bd
    checkout a661bd
    commit id:"S"
    commit id:"T"
    commit id:"U"
    commit id:"a661bd" tag:"(a661bd) DANGLING"