I’m not Git expert and I regularly learn things in Git that changes my view of the tool. When I was showed git rebase -i , I stopped over-thinking about my commits. When I discovered git reflog , I became more confident in rebasing. But I think one of the most important command I was taught was git rebase --onto .

IMHO, the documentation has room for improvement regarding the result of option. If taking the image of the tree, it basically uproots a part of the tree to replant it somewhere else.

Let’s have an example with the following tree:

o---o---o---o master \ \---o---o branch1 \ \---o branch2

Suppose we want to transplant branch2 from branch1 to master:

o---o---o---o master \ \ \ \---o' branch2 \ \---o---o branch1

This is a great use-case! On branch branch2 , the command would be git rebase --onto master branch1 . That approximately translates to move everything from branch2 starting from branch1 to the tip of master . I try to remember the syntax by thinking the first argument is the new commit, the second is the old one.

So, but what use-cases are there to move parts of the tree?

Delete commits While my first reflex when I want to delete commits is to git rebase -i , it’s not always the most convenient. It requires the following steps: Locating the first commit to be removed Effectively run the git rebase -i command In the editor, for every commits that needs to be removed, delete the line Quit the editor If the commits to be removed are adjacent, it’s easier to rebase --onto , because you only need the new and the old commit and can do the "deletion" in one line. Here’s an example: o---A---X---Y---Z master To remove the last 3 commits X , Y and Z , you just need: git rebase --onto A Z

Long-lived remote branches While it’s in general a bad idea to have long-lived branches, it’s sometimes required. Suppose you need to migrate part of your application to a new framework, library, whatever. With small applications, a small task-force can be dedicated to that. The main development team goes on week-end with instructions to commit everything before leaving on Friday. When they come back on Monday, everything has been migrated. Sadly, life is not always so easy and applications can be too big for such an ideal scenario. In that case, the task force works on a dedicated migration branch for more than a week-end, in parallel with the main team. But they need to keep up-to-date with the main branch, and still keep their work. Hence, every now and then, they rebase the migration branch at the top of master : git rebase --onto master old-root-of-migration This is different from merging, because you keep the history linear.

Local branches Sometimes, I want to keep my changes locally, for a number of reasons. For example, I might tinker with additional (or harsher) rules for the code quality tool. In that case, I want to take time to evaluate whether this is relevant for the whole team or not. As above, this is achieved by regularly rebasing my local tinker branch onto master . As above, it lets me keep my history linear and change the commits relevant to tinker if the need be. Merging would prevent me from doing this.