I am now using git since more than a year as my primary scm. I tend to use it also against svn repo,  I can so focusing on git  becoming always more comfortable using it. To be honest up to now my git use has always been quite basic, while projects I was working on never needed more that a master/develop/topic branches workflow. Recently I faced a more complex issue related to the necessary  support for proper support branch that was going to diverge for a long time from the develop branch.

We have a develop branch where is done the job for new version 2.0 while we still have a stable branch where we support version 1.0. The issue comes from the fact that version 1.0 is not going to receive only simple hotfixes but will also be improved with new feature that need to be ported to version 2.0..

For the first month or so we still were able to merge the 2 branches but not they have diverged too much. Merge is not an option and so we had to find a new strategy.

Our goal was to carry all the changes made on a topic branch borned by the 2.0 branch into the same 2.0 and also to the 1.0 without merging 2.0 into 1.0. This can be solved cherry-picking any single commit from the topic branch to the 2.0 and then merge topic into 1.0. While this works fine we faced situations where the topic branch were actually getting too long and cherry picking many commits can be buggy and tricky.

We finally solved our issue using a git feature called rebas –onto.

An example (you can clone example code here https://github.com/andreacfm/git-test): <p style="text-align: center;"></p> Our repo has a develop branch checked out  from a master branch. Both master and develop have commits made after they diverged. A topic branch is also borned by develop and some job was made on it.

Rebase onto helps us cause it allows us to say to git to rebase the topic branch on master VIA develop. Basically git makes a diff between master and topic excluding all the job that was made on develop after that devlelop diverged from master. This diff gets applied to master.

Our goal is to bring the 2 commits made on topic branch to master and to develop branch without having to merge develop into master. Topic needs to be rebased –onto master and merged into develop. To make this we need a temporary copy of topic.

$ git checkout topic
$ git checkout -b temp

The temp branch allows us to perform the 2 different actions (merge on develop and rebase onto master) leaving git calculate the diff for us. More on this in the next post.

$ git rebase --onto master develop topic
$ git co master
$ git merge topic
$ git checkout develop
$ git merge temp
$ git branch -D topic
$ git branch -d temp

Before we rebase –onto topic to master via develop. We need then to go to master and to fast-forward master to topic by merging. We can now merge the temp branch into develop and delete both topic and branch. Here is what we obtain:

As you see both develop and master branch has received just the commits made on the topic branch but still develop has not been merged into master. Rebase –onto saved our day cause avoid us to make very long cherry picking session on many different branches (forgot to say our project is much more complex that this example). Respect to the cherry picking technique rebase –onto is also less error prone cause let git calculate the commits you need to apply. Sometimes reading the git tree commits is very hard on big projects and this increase the possibility to loose some commits around.

More on this to come.


andreacfm