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"