Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

The Multiple Usages of git rebase --onto

DZone's Guide to

The Multiple Usages of git rebase --onto

Learn about different use cases for the command git rebase --onto for the version control tool Git, like deleting commits and creating local branches.

· DevOps Zone
Free Resource

Download the blueprint that can take a company of any maturity level all the way up to enterprise-scale continuous delivery using a combination of Automic Release Automation, Automic’s 20+ years of business automation experience, and the proven tools and practices the company is already leveraging.

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 the 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:

  1. Locating the first commit to be removed
  2. Effectively run the git rebase -i command
  3. In the editor, for every commits that needs to be removed, delete the line
  4. 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 generally 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.

Conclusion

git rebase --onto can have different use-cases. The most important ones are related to the handling of long-lived branches, whether local or remote.

As always, it's just one more tool in your toolbelt, so that not everything looks like a nail.

As every command that changes the Git history, git rebase --onto should only change local commits. You've been warned!

Download the ‘Practical Blueprint to Continuous Delivery’ to learn how Automic Release Automation can help you begin or continue your company’s digital transformation.

Topics:
devops ,git ,version control

Published at DZone with permission of Nicolas Frankel, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}