How to update Drupal while preserving all your changes
Let's face it: Updating a Drupal instance can be a pain, especially, if your Drupal installation is full of custom patched, like mine is. Wouldn't it be nice to have an installation that can be updated safe and easily? This article is about how I achieved this.
As you may know, Drupal uses CVS. In simple words, CVS allows several developers to work on the same file at the same time. Therefore developers can apply changes without overriding the changes of others - at least to some extend. Different changes to the same line of course need manual resolution.
So, let's dive in. Change into your home directory
cd ~
and download Drupal from CVS, like described here (Attention: This is one line!):
cvs -z6 -d:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal co -d staging -r DRUPAL-4-7 drupal
This downloads the current Drupal 4.7 (-r DRUPAL-4-7 drupal) into a directory called "staging" (-d staging). Note this directory is not accessible by the web server.
If you peek into the directory, you'll see a default Drupal installation, including all the READMEs, SQL files etc.
Now let's install some modules and themes. For example, let's install the pathauto module:
cvs -z6 -d:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal checkout -r DRUPAL-4-7 -d staging/modules/pathauto contributions/modules/pathauto
Or the the image module:
cvs -z6 -d:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal checkout -r DRUPAL-4-7 -d staging/modules/image contributions/modules/image
Do you see the pattern? Downloading a module is always the same, just append the module directory name to the path after -d and the path at the end:
cvs -z6 -d:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal checkout -r DRUPAL-4-7 -d staging/modules/[MODULEDIRNAME] contributions/modules/[MODULEDIRNAME]
If you don't know a module's directory name, try to find it here.
Themes can be downloaded the same way, just change the according directories. To fetch the Democratica theme, for example, issue:
cvs -z6 -d:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal checkout -r DRUPAL-4-7 -d staging/themes/democratica contributions/themes/democratica
Again the rule is simple:
cvs -z6 -d:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal checkout -r DRUPAL-4-7 -d staging/themes/[THEMEDIRNAME] contributions/themes/[THEMEDIRNAME]
A list of all themes is available here.
Alright, now download all modules and themes needed. Done? That was quite a bit of work, hmm?
Now comes the magic. First change into the "staging" directory:
cd ~/staging
And then do:
cd ~/staging cvs update
The CVS update command will check the server for new version of the Drupal core, and each module and theme you installed. But it also will keep every change you did locally, so updating patched files is no longer a pain. Additionally, if a file got deleted accidentally, CVS will download it again.
It is a good idea to run
cvs update
every week or so to not miss a security update. I prefer to do this by hand to see if there are conflicts when updating.
Well, we now have a Drupal installation that can be updated easily. But look: it's full of "readme" files, translation files, and this awful lot of directories named "CVS". Uh, and I don't want "xmlrpc.php" lying around on my web server, Dude.
Nema problema.
Now we have an installation bound to CVS, we will extract a subset to form the actual running installation that can be accessed by the webserver.
We use a tool called rsync. Rsync mainly keeps 2 directories synchronized, allowing to apply filters while copying. It can do this even remotely, so if your web space is limited, you may want to keep the CVS based installation locally and sync remotely.
Let's assume the web server's public directory is "htdocs" (this depends on your proivder, "www", or "html" are also common names), we sync our staging directory like this (one line!):
rsync -rl --exclude ".#*" --exclude "*txt" --exclude "*html" --exclude "*htm" --exclude "*sql" --exclude "CVS" --exclude "po" --exclude "README*" --exclude "INSTALL*" --exclude "CREDITS*" ~/staging/ ~/htdocs
I'm sure there is a more elegant way to express the filter. However, this one works. It's best to put it into a shell script file, so you do not have to type it again and again.
Note the "--exclude" switches. If you want to for example exclude modules or files, just add another switch.
--exclude "xmlrpc.php"
will exclude the file "xmlrpc.php".
--exclude "pathauto"
will exclude the pathauto module.
Now, each time the CVS based installation is updated, rsync must be called to forward the changes to the actual working directory. All changes should be made within the CVS installation, not in the working directory (in this case "htdocs")!
Summary: What do to:
- Download Drupal from CVS
- Download modules and themes from CVS
- Do "cvs update" and "rsync" regularly