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 upcomingrelease-2.1.x
).Now, at some point another feature (namely,
critical-feature
) was developed and merged back tomaster/trunk
. We realize that this feature is so important, that we have to backport it torelease-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 correspondingcritical-feature
branch with conflict-resolving conflicts?Or should this be done as the
cherry-pick
of the commit, which merges thecritical-feature
intomaster/trunk
when it's done? Or maybe even as a set ofcherry-picks
for each commit in thecritical-feature
branch?Could you advise something for the conflict resolution procedure? What should one do if the current difference between
release-2.0.x
andmaster/trunk
is so huge, that "naive" backporting leads to a huge amount of conflicts due to code refactoring and missing features orAPI
, which were added after therelease-2.0.x
?Does
Git
orSubversion
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.
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
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.
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.
来源:https://stackoverflow.com/questions/12132594/feature-backporting-in-git-subversion