Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Feature backporting in Git / Subversion

What would be the preferred way to achieve the following workflow with either Git or Subversion (I have more interest in the Git version, but comparison will definitely be useful):

  • Let's say we had a major release of the product recently and there is a specific polisihin branch called release-2.0.x.

    The development then continued and several feature branches were merged into the master/trunk (they will later become the part of the upcoming release-2.1.x).

  • Now, at some point another feature (namely, critical-feature) was developed and merged back to master/trunk. We realize that this feature is so important, that we have to backport it to release-2.0.x.


Here is a small pseudographic illustration for the described case. Note that everything on the top brings in tree differences between release-2.0.x and current master/trunk and leads to merging problems (otherwise I could simply merge the critical-feature and avoid writing this question :)

    (features added since 2.0.x, which
     should not be backported)
              ^   ^    ^
              |   |    |    (code refactorings done
              |   |    |     in master/trunk)
              \   |    /     (*) (*) (*)          
-------------------------------------------------------> master/trunk
      |                                          |
      |                                          |
      |                                          |
      \ release-2.0.x                            \ critical-feature
                                                   (should be backported)

Questions:

  • What would be the best way to perform the feature backporting from the VCS perspective?

  • Should this be done as a simple merge of the corresponding critical-feature branch with conflict-resolving conflicts?

  • Or should this be done as the cherry-pick of the commit, which merges the critical-feature into master/trunk when it's done? Or maybe even as a set of cherry-picks for each commit in the critical-feature branch?

  • Could you advise something for the conflict resolution procedure? What should one do if the current difference between release-2.0.x and master/trunk is so huge, that "naive" backporting leads to a huge amount of conflicts due to code refactoring and missing features or API, which were added after the release-2.0.x?

  • Does Git or Subversion have something specific to offer for this routine except standard merging or cherry-picking approach? I guess that rebasing won't be helpful in case when the amount of conflicts is vast, but, obviously, I might be wrong.

like image 919
Yippie-Ki-Yay Avatar asked Aug 26 '12 18:08

Yippie-Ki-Yay


3 Answers

The all idea of backporting features looks broken for me. Only critical and non-destructive changes should be backported. For features and improvements you have to create new branch and start stabilization period.

Check out release process used in Apache Subversion project itself: https://subversion.apache.org/docs/community-guide/releasing.html#release-stabilization

like image 76
Ivan Zhakov Avatar answered Oct 24 '22 05:10

Ivan Zhakov


It depends. If the critical feature is relatively simple and small, you could just make several cherry-picks. However, of course it could cause a lot of merge conflicts, because the implementation of the feature could use the refactored code. However, as I understand it will be easiest solution. And only solution for SVN.

However this solution doesn't reflect actions in the history graph, it confuses.

With git there is another option to rebase the critical feature at the merge-base of the master and the release-2.0.x branches. It literally means that you should reimplement the feature using old code, which is common for both branches. In this case you then could merge the rebased feature. If you have merged the feature to the master already, when you would merge rebased feature into the master, it most probably will conflict (becasue master already has such implementation). So you will resolve conflicts, however in most cases it will be easy, because changes should be nearly the same.

The good thing about the rebased feature approach is that if you would find a bug in it, you could fix it in the feature branch and easily merge fixes into the release and the master branches.

Of course, the rebasing could cause a lot of conflicts, but it means there is no easy way to backport the feature into the release-2.0.x. Maybe it would be easier just re-implement it then.

like image 2
kan Avatar answered Oct 24 '22 05:10

kan


I have developed some tools specifically for making this process easier with git, and last week I wrote an extensive blog post about them. In particular, the git cherry-menu command referenced in that post can accept an arbitrary list of commits to backport, so using git log and your favourite text editor, you could build a reasonably carefully selected list of commits which constitute the critical feature to be backported, and then run something like:

git checkout -b release-2.0.y release-2.0.x
git cherry-menu cat commits-to-backport.txt

This is similar to kan's rebasing suggestion, except that the backporting process is more structured, and by using git notes under the hood, you get several handy extra features, including that all meta-data describing the process is persisted across multiple runs of git cherry-menu.

Of course, if you only have a handful of commits to backport, kan is right that you might as well just cherry-pick directly.

Unfortunately I think the accepted answer is slightly self-contradictory:

The all idea of backporting features looks broken for me. Only critical and nondestructive changes should be backported. For features and improvements you have to create new branch and start stabilization period.

because creating a new branch and starting a stabilization period is still backporting. The only difference is which branch you decide to put the backported commits into! You can either put them into the original release-2.0.x branch, or a different branch forked off it, like the release-2.0.y branch I suggested above. It's generally safer / cleaner to do the latter (and I guess that's Ivan's point), but really that depends on how you organize your repositories and branches. It still doesn't avoid the need to perform cherry-picking and potential conflict resolution though.

like image 2
Adam Spiers Avatar answered Oct 24 '22 05:10

Adam Spiers