I am currently working with a team that uses subversion for day-to-day development but needs to use cvs due to a corporate policy. So I suggested that we create a build on our continuous integration server to automatically merge changes from a subversion working copy to a cvs checkout.

I had a quick look on the internet for something to do the merging and managed to find and play with a perl script to merge from svn to cvs, and with a java application that was supposed to do the same. The quality of code in each put me off a little, but what put me off more was that they just did not work properly in our environment.

A long time ago I wrote a ruby script to copy changed or new files from one directory to another, so I decided to dust it off and adapt it to merge from a svn tree to a cvs tree. The result can be downloaded from here. This script now performs the following:

  • Copies all files that have been changed in the svn tree to the cvs tree. It compares the modified time of each svn file against its cvs counterpart and only copies the svn file over to cvs if it is newer. Alternatively the script can use an MD5 hash of each file to see if the files are different.
  • Copies all files and directories that don't exist in the svn tree to the cvs tree, and executes the cvs add command on each new directory and file in the cvs tree.
  • Executes cvs remove on each file in the cvs tree that has no counterpart in the svn tree.
We use CruiseControl for continuous build and integration and apache ant as the build tool. Consequently everything else is taken care of by ant tasks that update the svn working copy, checkout (or update) a cvs working copy, and then commit the cvs working copy using the svn revision as the commit message.