Painless Drupal revision control with CVS and Subversion on a shared host

December 19, 2007

So we at GateHouse Media are quickly pushing developers within the organization to learn and master Drupal for many of our smaller, one-off projects. While chatting with Brandon Belew a few minutes ago, it became apparent that manually downloading and installing Drupal and many contributed modules can be quite cumbersome. After reading the Pro Drupal Development book, and becoming a recent Subversion junkie, I've learned to do all of my Drupal and Contributed Module management through a combination of CVS and Subversion.

Through this post, I'm going to attempt to take you through all of the steps of managing your Drupal installation as well as any contributed modules you may need to utilize.

So the first steps are to have CVS and SVN running on either your server or production computer. In my case, I've got them running on both. If you've got a shared host, there are a few tutorials out there on how to setup SVN (many hosts already have CVS installed). Here's a rediculously quick tutorial on how to setup a base install of SVN on your shared server:

wget http://subversion.tigris.org/downloads/subversion-1.4.5.tar.gz
wget http://subversion.tigris.org/downloads/subversion-deps-1.4.5.tar.gz
tar -xzvf subversion-1.4.5.tar.gz
tar -xzvf subversion-deps-1.4.5.tar.gz
./configure --prefix=/path/to/installation
make
make install
PATH=~/path/to/installation/bin
export PATH

Okay, so now we're assuming CVS and SVN are correctly installed and working on your box. The first step is to checkout a base installation of Drupal. Create and navigate to a directory where you'd like your Drupal installation to live. Once you're there, create the following directories:

For an in-depth explanation of what these folders mean, see Wikipedia's decent overview.

Now, you'll checkout Drupal into the trunk folder. To do that, run the following command from the parent folder housing those three new directories:

cvs -d:pserver:anonymous:[email protected]:/cvs/drupal checkout -d ./trunk -r DRUPAL-5 drupal

The above code assumes you're looking for the latest stable Drupal 5 version, and that you want to check it out into './trunk'.

After that finishes, you've got a working copy of a Drupal installation straight from Drupal.org. Now we need to get your installation into your own Subversion repository for your personal safe-keeping. First you'll need to create a Subversion repository.

Think of your 'repository' as a bank. It's where you'll put your revision-controlled files, but not where you'll work on them. Once you've created the repository, you checkout versions of your projects and work on them in a remote location (remote as in another directory, or even another computer). The checked out version of your project from the repository is called a 'working copy'. You can then make changes incrementally to the version in the repository with the changes from your working copy.

Run the following command to create a repository named 'repos' in your current directory:

svnadmin create repos

If this doesn't work, be sure that the 'bin' folder from your SVN installation is correctly setup in your PATH. Run the command 'env' to check to see if that path is in there.

Then, go back to your Drupal checkout. At the top directory (where you see the folder that houses 'tags', 'trunk' and 'branches'), run the following command to put the entire codeset (including directories 'tags', 'trunk' and 'branches') into your repository you just created:

svn import name-of-folder file:///path/to/repos -m 'First Import'

There! You've just imported your base Drupal CVS checkout to your repository. At this point, if you wanted, you could delete the source files that you just used to import the code into the repository. I'd hold off until you do the next step.

Now that your project is in your Subversion repository, you need some way to manage and modify that code. The code that you used to import into the repository is in no way connected to the repository. What you need to do now, is do exactly what you did above with the Drupal installation, checkout your files into a working copy.

Navigate to the directory where you'll want your checkout to live, and run the following command:

svn checkout file:///path/to/repos/name-of-project/trunk name-of-destination-directory/

It's important to remember to checkout the '/trunk' of the project, because you don't really need the others, unless you have branched or tagged versions you're working on. Again, see that Wikipedia article for the usage of those folders.

Now you've got a working copy of your Drupal installation from your personal Subversion repository, which also maintains the integrity of your Drupal CVS checkout from Drupal.org. Let's say this checkout acts as the live codeset from which your site is running on. When Drupal.org announces an update, all you need to do is go back to your checked out version of Drupal, and run the following command to update your Drupal codebase with the latest version (assuming here that latest tagged release is '5.7'):

cvs update -r DRUPAL-5-7 -dP

It's as simple as that for upgrading your Drupal installation. Well, not really, if you have modules installed, you may need to perform some additional steps, but for the most part, it's as simple as that.

So now that you've got a nicely updated (from 3 minutes ago) installation of Drupal, you can start breaking stuff (or building, whatever you like). Let's say you find a nice little module on Drupal.org and you'd like to download and install that module into your Drupal installation. With this nice little setup we've got going on, there's no need to download the files manually, dump them into your Drupal installation and FTP to your server. Instead, you can do a CVS checkout of that specific module, then commit to your personal Subversion repository and check out a working copy on your server.

Navigate to:

your-drupal-installation/sites/all/modules/

You may need to create the 'modules' directory if this is a fresh Drupal install. Once you're there, run the following command to grab the 'Image' module from Drupal.org:

cvs -d:pserver:anonymous:[email protected]:/cvs/drupal-contrib checkout -d image -r DRUPAL-5--1-6 contributions/modules/image

Note that the revision tag (DRUPAL-5--1-6) may be different for each module. You'll want to make sure you grab the latest stable revision, rather than the HEAD, as many times the HEAD will contain development (and thus, unstable) code.

So once you run the command above, you'll have checked out the image module, and should now see it in your /sites/all/modules directory. The update process for modules is the same as your Drupal checkout. Navigate to the /sites/all/modules/image directory, and run the following command:

cvs update -dP

CVS will check your working copy against the revision you checked out of Drupal.org for changes. If there are changes, it'll bring your code up to date.

So now you have a Drupal installation and a module as working copies from Drupal.org. You'll want to commit your addition of the image module to your personal Subversion repository for safe-keeping. Run the following code at the root of your Drupal installation:

svn status

SVN will iterate through your installation and notify you of changes that you've made to your local working copy. You should see all of the additional files your Image module CVS checkout created. Run the following command to 'commit' (save) these changes to your repository:

svn commit -m 'adding cvs checkout of image module from drupal.org'

Then, you can run an 'svn status' again.

There should be no more pending actions. When you run 'svn status' and it returns a prompt with no actions, that means there is no difference between your LOCAL changes and the repository version. However, it does not necessarily mean there have not been changes to the repository. After all, if someone applies a patch to a piece of code in the repository, it does not automatically update your working copy for obvious reasons. You can see if there have been changes to the repository by the following command:

svn status --show-updates

So now, you've got a Drupal installation with your custom or contributed modules all under a personal Subversion repository, as well as copies of your Drupal installation and modules tied to a CVS checkout for upgrading (and downgrading) with ease.

Oh, here's a few links I was attached to when I first began this debacle:

At this point, I'm pretty much out of breath and I think we've covered a fair amount of ground.

So, yeah, well, I'm done.