Reputation: 19587
Very often git rebase
used in a context of some branch. For example, if I want to move the base of feature
branch on top of the master
branch (based on latest commits) - tutorials say:
git checkout feature
git rebase master
After tutorials like that, there are a lot of questions. Eg: how to perform the same action without checking out. How can I do the same action with --onto
option. What the difference between --onto
and just rebase. Can I pass a range of commits or it must be a whole branch? Etc..
I've read man page several times but still have a big gap.
So the main problem is: how git parse the args in different scenarios and how should I interpret/imagine them in my head? For example:
git rebase master
git rebase feature master
git rebase --onto master feature
git rebase HEAD~4 HEAD~2
git rebase --onto HEAD~4 HEAD~2
Let's assume we have the following repo:
Z -- W (HEAD, test-branch*)
A -- B -- C -- D -- E (master)
\
1 -- 2 -- 3 (feature)
test-branch is checked out.
Upvotes: 10
Views: 2140
Reputation: 164919
The full rebase command is this.
git rebase --onto <onto> <upstream> <branch-to-rebase>
Git will take all the changes in branch-to-rebase
which are not in upstream
and put them on top of onto
.
The defaults are...
git checkout feature; git rebase master
is really git rebase --onto master master feature
.
You generally want onto
and upstream
to be the same, but sometimes it's useful for them to be different for delicate surgery. The difference between upstream
and onto
is made clear in this example.
A--B--C--D master
\
E--F--G next
\
H--I--J topic
If you git rebase master topic
, it will rebase all the commits that topic
does not have in common with master
. All intervening branch heads will be ignored. That is E, F, G, H, I and J. Since onto
defaults to upstream
, it will put those on master
. You'll wind up with this.
A--B--C--D master
\ \
\ E'-F'-G'-H'-I'-J' topic
\
E--F--G next
What if you just want the commits from next
to topic
? This is where --onto
becomes useful. Tell Git that the upstream is next
, but you want to rebase onto master
. So run git rebase --onto master next topic
. This will select just H, I and J.
A--B--C--D master
\ \
\ H'-I'-J' topic
\
E--F--G next
Upvotes: 16
Reputation: 1325137
git rebase master
rebases the current branch on top of master
(meaning master
is checked out, and the current branch is reset to master
, its commits are rebased on top of it).Considering the current branch is test-branch:
A -- B -- C -- D -- E -- Z' -- W' (test-branch)
(master)
git rebase feature master
replays master
commits on top of feature
(rare, the best practice is to do the opposite)That is:
A -- B
\
1 -- 2 -- 3 -- C' -- D' -- E' (master)
(feature)
git rebase --onto master feature
would move all commits after feature up to the current branch on top of the new base master
.
Since feature
and test-branch
are not related, that wouldn't move any commit.
git rebase HEAD~4 HEAD~2
reset the current branch to @~2
For a test-branch
like Z -- Y -- X -- W
, that would mean Z -- Y
git rebase --onto HEAD~4 HEAD~2
would remove @~3
and @~2
from the current branch since it replay all commit from after @~2
(that is @~1
and @
) onto the new base @~4
.Upvotes: 2