Tagging and merging in SVN
I have spoke about SVN before, specifically how to set up and use it on MacOS X. Now I am going to cover one of the more useful, and frustrating features of SVN; breaking up your development into trunk (active development) and tags (feature frozen releases).
First of all, why tag?
There are two models that you can follow when developing a large, enterprise scale application. You can check your code into SVN, and effectively have nothing but trunk, that is you will have one version of the code for said project, and you will make checkouts from it when you have reached a certain level of maturity and featurefullness. In the case of a web application, the most popular practice when using this scenario is to have your website running out of a checkout.
What this means is that you make your changes to your canonical source, i.e. trunk, and then svn update your checkout as needed. As you can imagine, this practice has some very cool pros and some disastrous cons. The biggest pro is that you can quickly deploy new and updated code to your live site; the biggest con is that if your not careful you can deploy code that hasn't been tested properly... if at all.
The second model that is employed when using SVN to manage the source code of your app is tagging. Tagging can be a confusing concept if not explained correctly, I know that I wasn't convinced of the usefullness of tagging for a very long time, because it just didn't click. I am still not thrilled with the complexity involved but you can't have everything apparently.
So what is the tagging model?
For you to get the most out of tagging, I would really suggest creating a detailed roadmap. In developing our Educational CMS Scrivener, we found it was most helpful to create a roadmap that began with 1.0 and ended at 2.0 with major release milestones on the points (1.1, 1.2, etc). After the roadmap was created we had our tagging scheme.
Once all the features for a milestone are reached we go into a feature freeze on trunk, tag the current codebase and release (in our case update the site, we haven't gotten to a place yet that we can release Scrivener in the wild.. soon though). We then update the roadmap with the revision number that corresponds to our tag and go back to developing in trunk for our next major release.
Okay so far we have trunk, where all our active development is happening, and various tags that are no longer actively developed that correspond to a waypoint on our roadmap. Sounds good right? Maybe. What happens when we close a security whole in trunk that is still open in our tag? Or how about we need to fix a typo in our HTML? We have to merge those changes into our latest tag from trunk. And this is where the frustration begins.
The mechanism for merging code between trunk and tags is cumbersome, and makes you do the work twice before it ever sees the light of day. You have to commit your changes from trunk, and then merge them into your tag; you then commit from the tag, and then in the case of a site running on code from a tag checkout, you have to update the checkout on the server to get the new code. Two commits, a merge and an update to fix a typo in a DIV name.
But even with this frustration, it is essential for a large scale project to use tagging to manage releases. Websites in particular will benefit from this system since it tends to minimize accidental code updates. In part two of this little missive we will get into the commands needed to set up this type of environment, and go through some examples of merging and updating. See you then.
Enjoyed this article? Follow me on Twitter.