Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use the git-flow model with Subversion?

We use Subversion and aside from a few individuals such as myself there is little to no experience with branching and merging in Subversion. My Subversion experience is limited to simple feature branches where merge and tree-conflicts, while not exactly rare, are not exceedingly difficult to resolve.

Given that, I am helping to manage a project where our current commit to trunk method is simply unsustainable for our needs. I introduced feature branching and merging to my localized team and we had some success. However simple feature branching was still not able to answer all our questions such as:

  1. How do we develop code in parallel for this release and subsequent releases?
  2. What code is considered stable?
  3. What (in development) code is going into the next release?
  4. What (in development) code is going into a subsequent release?
  5. What version of code is our Test, Acceptance, or Production environments?
  6. How do we integrate concurrent development activities with a known stable release to reduce introducing bugs and incomplete work?
  7. How do we provide hot-fixes to released code?
  8. How do we know, from our source control, what development activity is currently ongoing?
  9. How do we experiment or R&D without disrupting the current code base while leveraging?

It seems that git-flow as defined here would go a long way to answer a lot of these questions. I experimented with this method in Mercurial and it seems like that it is possible to implement this method there as well. Sadly, migrating to a DVCS is off the table at this point.

However, my brief attempt to mimic this method in Subversion failed with many merge and tree conflicts. The merge options and edge cases are numerous and baffling.

Can Subversion be used to implement git-flow and if so what is the pain level?

like image 892
Ryan Taylor Avatar asked Nov 12 '12 14:11

Ryan Taylor


2 Answers

We use what is called the unstable trunk development method. This was the development methodology that the creators of Subversion had in mind when they created Subversion. It's simple and easy to implement.

  • You do all of your development on trunk. Thus called the unstable trunk.
  • When you get close to a release, you make a branch for that release. The idea is to make the branch late enough to keep parallel development as short as possible, but not so later that some developers can't do their jobs because they no longer need to work on the current release, but need to start working on the next release. In Agile, this is usually done right before the firming sprint. It's usually done when the release is feature complete, and now you're just fixing bugs.
  • The release takes place off of the branch. You tag off the branch. If there are patches that are needed, they're done off of the branch.

Here's an idea how it works:

  • Imagine you're working on Release 1.2. You are working on the trunk. Now, you're getting close to the time when Release 1.2 is about to be released, and there's not enough work on Release 1.2 to keep your developers busy. You create a 1.2 branch for your release.
  • Now, the people still working on Release 1.2 switch over to the Release 1.2 branch. Meanwhile, developers working on 1.3 stay on trunk.
  • You are now ready to Release 1.2. You tag Release 1.2 right on the branch. The branch is not merged back into trunk. The trunk is for Release 1.3.
  • Bugs are reported, and you want to fix them in Release 1.2.1. You continue working off the 1.2 branch. No new branch needed for 1.2.1. (You can lock branches between releases to keep them pure.
  • When you are about to do Release 1.3, you repeat the process -- branch 1.3 and work for 1.4 continues on the trunk.

There will be some merging. It's mainly merging defects fixed on the release branch back to trunk. There are three options of doing this:

  • Once you do a release, you merge enmass all changes on the branch back to trunk. There's very little tracking. You're just assuming that all the bug fixes on the branch also apply to the trunk.
  • You use a tracking systems that understands issues may live on more than one release. In this case, you simply mark a bug discovered on the branch to trunk too. You can cherry pick changes that apply to trunk thanks to your issue tracking system.
  • Some sites simply don't merge. They also track via the defect tracking system changes that need to be applied to the trunk that were applied on the branch, and simply re-implement them. They might copy changes from the branch to trunk, but they never do a formal merge. However, once you do this, you can't ever merge (unless you merge with the --record-only flag).

You, of course, realize that this method takes something called planning. You must prioritize your work, so the developers do the work for the upcoming release before work on the future release. You only branch once you no longer have enough work on the upcoming release to keep all of your developers busy.

You can implement the standard Git workflow which is using development separate development branches for each developer or issue, and then delivering those changes onto trunk. This would require a lot of branches, one for each developer/feature.

You first merge from the trunk to the branch to rebase your code. Once you've done the rebase, you merge from the branch back to the trunk using the --reintegrate switch. Pre-1.6, you were suppose to delete the branch and recreate it since --reintegrate sort of messed up merge tracking. However, this has been fixed in Release 1.6.x and up.

like image 116
David W. Avatar answered Sep 22 '22 03:09

David W.


That's a big question. I only have ideas how to solve some of the problems:

  1. I don't think this can easily be solved without using branches a lot. Not sure if this can be easily solved by using GIT either. Feature branches go a long way in solving this problem, but in general you should probably try to concentrate on features for the next release only.
  2. trunk - I consider it the master branch.
  3. I'd say the development branch is the code for the next release
  4. Seems difficult without using a lot of branches, no idea how to properly solve this.
  5. You could use branches or note the revision number being in TEST and ACC. PROD should be put into a tag I guess.
  6. I'd say using automated regression tests and continuous integration. Also using peer reviews can help here, at best you use some sort of tool to mark a file as reviewed. That way you can ensure that you only merge files that have been reviewed. It could also be interesting to tie your commit messages to your bugtracker, to automatically figure out which files have been touched in relation to which issues, and then make sure all issues are actually closed for the files you want to merge. This is a non trivial task, especially if you are thinking about merging only parts of branches. Thereby, sort of, doing a feature merge.
  7. Use a tag for the release. You can check it out just like a branch and add patches if necessary
  8. List all svn commits for the entire repository on one page (e.g. trac/redmine/jira overview)
  9. Use a local copy I'm afraid/or a branch again. Or make the R&D use git svn locally for research.

Some of these problems can, at least partly, be solved by using git svn. By using it you can for example to experiments locally using gits branch features, without storing those in the global repository. Of course this is not interesting if you are exploring a new feature with many members on a team, unless they are all comfortable with using git and pulling from each other over the network. By using git svn you can also use git cherrypick to hand pick single commits to apply from one branch to another (e.g. development onto released-x.x-tag).

That's all I could come up with for now, hope it helps.

like image 22
Nihathrael Avatar answered Sep 22 '22 03:09

Nihathrael