Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git rebase arguments context explanation needed

Tags:

git

github

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.
like image 219
Timur Fayzrakhmanov Avatar asked Sep 13 '15 18:09

Timur Fayzrakhmanov


People also ask

Why git rebase is required?

The Rebase Option But, instead of using a merge commit, rebasing re-writes the project history by creating brand new commits for each commit in the original branch. The major benefit of rebasing is that you get a much cleaner project history. First, it eliminates the unnecessary merge commits required by git merge .

What is git rebase with example?

Rebasing is a process to reapply commits on top of another base trip. It is used to apply a sequence of commits from distinct branches into a final commit. It is an alternative of git merge command. It is a linear process of merging.

How do I stop rebase abortion?

You can run git rebase --abort to completely undo the rebase. Git will return you to your branch's state as it was before git rebase was called. You can run git rebase --skip to completely skip the commit.


1 Answers

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...

  • branch-to-rebase: current branch
  • upstream: branch-to-rebase's tracking branch
  • onto: upstream

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
like image 185
Schwern Avatar answered Nov 08 '22 17:11

Schwern