In my last post, I was describing the rebase feature and highlighted the advantages of using this instead of the merge approach. With my second post, I want to give you an even more advanced feature which you will certainly need and use quite often if you follow the rebase principle in your team. This command is basically just an option for the well-known rebase and is called: rebase –onto.
The problem situation
Again, I would like to give a simple example for using this option in real-life. Let’s suppose you’re working with a colleague on a specific feature. Your colleague is implementing some kind of persistence and business logic and you’re the one building up the UI on top of this. Thus the current Git graph could look like the following:
Important here is that only the stable branch is released to all other colleagues not working on this feature. Thus the other two, persistence and ui, are in a draft and are allowed to be changed completely. In the meantime of the development of the feature, the stable branch will continue to have more and more commits on which the whole feature must be rebased on. Hence the persistence colleague just executes a simple rebase against stable to be up-to-date here and pushes this to our feature repository :
But as we can see easily in the above picture, we are still basing our work on the old persistence commits. A simple rebase against the new persistence branch would result in the problem, that we rebase the old persistence commits in addition against the new ones. This is certainly not what we want to achieve here.
The solution to this problem is an option to the swiss army knife of Git:
git rebase --onto <target> <range_from> <range_to>
This option basically needs 3 parameters:
- target: This is the target branch / commit on which we want to rebase on.
- range_from: This is the starting range of our commits for the rebase operation. Important for this one is, that the specified commit will not be copied to the target.
- range_to: The end range of our commits. And this time, the commit is included in the operation.
The following picture highlights these three parameters for our example graph:
The whole command, which we need to execute here, would be:
git rebase --onto persistence ui^^ ui
The commit definition ui^^ is one way to go back two commits from the ui commit. Another way would be to use ui~2 or even use the hash code. After executing the above, our resulting graph will become to:
Cherry Pick as an alternative?
For very simple cases, like you want to just copy one of your commits to a target branch, the cherry-pick command might be an alternative. But once you’re used to rebase –onto, you will likely stick with this. An advantage is to have all the rebase features along with it; like rebase –abort if something goes wrong and you want to start over.