Version Control – Creating a Version Control Strategy for SVN

svnversion control

Off the clock I'm going to try and come up with a strategy for version control for my company; we currently use SVN but there's no structure to it – we basically only have a trunk and only commit to that. Recently the development manager started a second repository that acts as our "tag", but it has to be manually merged with the "trunk" since it's not part of the same repository but a totally separate one. In effect there is just one folder, called "Dev" (there's actually different "Dev" folders at different dates but just "Dev" is the main one) and under that is everything else; all the other projects. It's not organized by project at all, it has no concept of branches/tag/trunk or anything. The person who set it up initially (long gone, of course) seemed to not know how to set SVN up at all, and since then nobody has bothered to learn how to do things properly for fear of breaking something. We don't use any kind of CI (or automated testing, unfortunately).

First, should we have it separated by project? For instance, we have: Two ASP.NET web sites (not Web Applications, Web Sites), a Web Service, a deployment folder for all the table scripts and stored procedures, two command-line clients for external projects that get called by the WebSites and a shared folder that has common business objects and the like. Should each of these be their own project with a branches/tag/trunk setup, or should it be like this:

dev/
  branches/
  tags/
  trunk/
      Site1/
      Site2/
      WebService/
      SharedCode/

and have all the branches and everything have a copy of the entire Dev folder? That approach might be easier to swallow since we often have situations where we need to make changes in the shared code library and at least one (usually both) of the web sites as well.

Second, we do regular releases ("pushes" in our parlance) to our dev server and live server. From what I've read the best way to handle this would be that all development goes into trunk/, branches are "temporary" and used for adding a new feature that might affect trunk, and tags are for releases? So, we push every month let's say, and I'm working on a brand new module. I would branch trunk, and use that branch for my code, writing and testing it and whatever. When the module is done, I'd merge it back into trunk (and maybe delete the branch), and when we are ready to deploy we would tag it ("May2011" let's say). If we have a bug fix after it goes live, it would be fixed in the May2011 tag and merged into trunk (so trunk gets the fix as well), and then May2011 would be pushed out again with the fix? Is this the intention of tagging?

Best Answer

If you want a unified build process, then be sure to put branches/tags/trunk at the root, like this:

branches/
tags/
trunk/
  dev/
    ...

If you don't need a unified build process, then you can put branches/tags/trunks within each project if you want. However, it might be difficult to migrate to a unified build after having put them within each project. A unified build has advantages, such as eliminating the need to publish shared components among projects -- they're all part of the build.

Personally, I like a unified build process. Furthermore, I don't think you should have a "dev" project. You should have projects directly under trunk, and then branch trunk into a dev branch. Use tags for releases. For example, I would do it like this:

branches/
  dev/
    Site1/
    Site2/
    WebService/
    SharedCode/
tags/
  release1/
    Site1/
    Site2/
    WebService/
    SharedCode/
trunk/
  Site1/
  Site2/
  WebService/
  SharedCode/