Coding in a Vacuum: Subversion Hooks
A month ago I wrote about setting up an in-house subversion server on the cheap. After a month of using my setup it’s been pretty successful, and I’ve learned even more about subversion.
One of the things I had to do was set up a post-commit hook to publish changes to a webserver. The site I did this for is still in development, and every commit needed to be pushed to the webserver for testing. I did this using rsync, (or, since the SVN server is in Windows, cwRsync), and it’s a pretty basic rsync/openSSH setup, but that’s for another day.
What I am talking about today is actually creating the hook script. What a pain in the ass. It’s not actually hard to create the script and run it. On Windows you just write a batch file, debug it, call it post_commit.bat, and drop it in the hooks folder of the repository you want to use. Sounds simple, doesn’t it? Why then, when you commit a revision, does Subversion hang, and the script not execute? Because subversion runs hooks in a near-null environment. This means that nothing is set. In Windows, not PATH variable. In everything, pretty much no environment variables of any kind. So, when you tested your script yourself it ran great because it had lots of support, but now Subversion is running it entirely alone. Poor, lonely script.
It gets even more frustrating. Since Subversion is running the script, there’s nothing being printed to the screen to tell you what’s going on, so debugging is like shooting bugs in the dark.
There are a couple of things you can do, however, to make your script work. First, use an absolute, full, path for everything. For Windows this means start with the drive letter. For *nix this means start with a slash. If that doesn’t work, there’s a trick that allows you to see what’s going on. You can log the hook’s output to a file. This way you can find out what’s going on, read the errors, and fix them. Thanks to Dan Switzer for posting about it. His blog showed up in a Google search and ended my frustration. In my case, it was some more environment that had to be set up for cwrsync to work properly.