Saturday, November 10, 2007

Subversion Vendor Branches Howto

This little posting is going to explain something that I have recently learned about that I would like to share. As someone who maintains complex software systems, it is important for me to be able to easily do upgrades of our third party applications. So, what is the best way to do this?

I use Subversion and a concept called 'vendor branches.' Sadly, their documentation is confusing and not as easy as what I'm going to describe. Let us use an example to demonstrate.

At work we rely on JiveSoftware's JiveForums software to host our forums. Each time they come out with an upgrade, what is the easiest way to deploy that upgrade across our development, preview and production environments? The answer is to check a copy of their code into subversion. This is an example script of how I do an upgrade from version 5.5.0 to 5.5.7. This assums that 5.5.0 has already been added using steps similar to below.
  1. wget http://domain/jive_software_5.5.7.zip
  2. unzip jive_software_5.5.7.zip
  3. svn co -N http://svn/vendor/jivesoftware jivesoftware
  4. mv jive_software_5.5.7 jivesoftware
  5. cd jivesoftware
  6. svn add jive_software_5.5.7
  7. svn ci -m 'adding a clean download of 5.5.7'
Now, the whole concept of the upgrade can be imagined with this simple statement: "I would like to take the difference between version 5.5.0 and 5.5.7 and apply that to what is in my development environment". In order to accomplish this, I check out my development tree locally and then execute a merge of the diff of the two versions.
  1. svn co http://svn/dev/jive jive-dev
  2. cd jive-dev
  3. svn merge --ignore-ancestry http://svn/vendor/jivesoftware/jive_software_5.5.0/ http://svn/vendor/jivesoftware/jive_software_5.5.7/ .
  4. svn ci -m 'upgraded development environment to 5.5.7'
Note: if there are any conflicting files, you will need to resolve those conflicts before checking in. However, as you can see, you can locally modify any of the jive software files and the diff process will take care of doing the merges for you.

For deployment of code to our preview and production environments, we have just checked out the preview/prod trees from svn onto the individual servers. Upgrading preview/prod is the same steps as above. Upgrading the machines themselves means that we just need to do an 'svn up' or 'svn switch' if we decide to deploy based on tags. At some point we might use .deb's to do these deployments, but for now, subversion is a great solution. It is especially handy to be able to quickly see a nice diff if a file changes because someone logged in over the weekend and needed to quickly modify a file by hand.

Running JBoss through this system works exceptionally well because not only does each revision move files around significantly, but it is increasingly difficult to even remember all the modifications we make to various configuration files for our preview and production servers. This process gives us the nice ability to use diff's to easily find those changes.

As for gotchas, one major one that I've discovered during upgrades of JBoss is that they will frequently take a packaged set of files (ie: a .sar/.jar file) and explode them into a directory. Unfortunately, subversion doesn't deal with this problem very well. It gives an error about 'type of resource object has changed.' When this happens, what you need to do is delete the file from your local repository first (including committing this change) and then doing the merge. The other gotcha is to make sure that all your text files go in with 'svn:eol-style = native' line feeds set from your .subversion/config file. If you get files with mixed linefeeds, the merge process doesn't always work so well and generates a lot of conflicts.

Well, that's it. I hope that little howto has been helpful.

7 comments:

Karl Fogel said...

I've added an item in the Subversion FAQ about this, pointing to your post:

http://subversion.tigris.org/faq.html#vendor-branch

lord said...

Bookmarked, coming back to this later. I just recently have the need to maintain a vendor branch, thanks!

Igor Blanco said...

What about file and directory deletes?

You're not managing the possibility of files or directories dissapearing in a new release of the 3rd party sofware, are you?

The official documentation does manage that with a perl script.

Jon Scott Stevens said...

Honestly, since I'm written this article, I've dumped subversion and moved to git. I highly suggest you do the same.

Ashley Nichols said...

We have been trying to find a consultant who can setup a Vendor branch for us! We use VisualSVN and have other issue that we need solved as well.

It would be nice to have an SVN consultant available ongoing!

You can contact us at 281-392-5050

Jon Stevens said...

Ashley, my advice now is to move to using git and drop subversion.

Ashley Nichols said...

Jon, my only problem with Git is that you don't seem to be able to prevent developers from having the entire codebase. With SVN you can give developers access to only the directories they need and prevent access to other directories.

Does this functionality exist in Git and I'm simply not aware of it?

Thanks for your advice!

Ashley