Subversion post-commit hooks

Hi, someone posted the same question a while back, but never got a response, so I’m just going to ask again. I have two directories, svn and labs. The svn directory holds my subversion project and I’d like labs to be a staging area for my site. When I commit to Subversion, I’d like the labs folder to be synchronized. Clearly, this calls for a post-commit hook which I wrote as:

/usr/bin/svn update /home/[account]/labs

Unfortunately, after I commit documents, svn update is never run. Does anyone have any suggestions on how to fix this? I’ve even tried moving the command to an external script as follows:

—post-commit (chmod’d +x)----

#!/usr/local/bin/php -q

<?php shell_exec('/usr/bin/svn update /home/[account]/labs'); ?>

Both of these methods will work properly if I execute it from the shell (even if I run them with $PATH cleared, env -i /home/[account]/svn/[project]/hooks/post-commit), but not when I commit through Subversion. This lead me to suspect it might be a permission problem (since commit will run as the dhapache user). The labs directory was chmod’d 755, but that still did not help. Any suggestions?

Sounds like permissions. Make the labs directory world writable (ie, 777) and test again.

If you want useful replies, ask smart questions.

Nope :confused:

Could it be anything else? I’m pretty sure the script gets run, because the demo post-commit script (the one that e-mails you what changes were made) works. I’ve tried logging the output as well to see if any errors were returned by doing:

/usr/bin/svn update /home/[account]/labs > /home/[account]/svn_output.txt

After a commit, the file remains empty.

How does Apache interact with the repository? Are all actions done as the Apache user? I don’t keep Subversion repositories at Dreamhost and the ones I do use I access via svn+ssh, so I’m afraid I don’t know much about the details of using it via HTTP. I’d guess that the problem lies here somewhere.

If you want useful replies, ask smart questions.

Yes, the post commit script is run as the dhapache user. You’re probably right, the problem lies there. I’ll just e-mail tech support and see if they can do something about it. I’ll post back here with their suggestions.

Sure, I can give this a stab. post-commits are kind of a pain for a couple reason. First, when they run, they run as the dhapache user. When you checked out the repo, you likely did it as your user, correct? This is the first problem, as the files are owned by your user then and another user running an svn up on that directory will not work, it doesn’t have permissions. One way to get around this, is to delete all the files that you checked out before, so for example remove all files in /home/[user]/labs. Then change the permissions of the labs directory with:

chmod 777 /home/[user]/labs

Then edit post-commit, and put in:

svn co /home/[user]/labs --username=user --password=pass --non-interactive

Then do a commit (just a blank file or something, anything) and it should checkout the repo to the labs directory.

Then go back, edit post-commit again, and change the file to use:

svn up /home/[user]/labs --non-interactive

And do another test commit. It should now be working and you can do commits normally. Please be aware though that because the files were checked out and updated by dhapache, they are all owned by dhapache now. The --non-interactive is a good idea when calling svn from a script, since if it decides to be stupid and ask for a user or pass anyways, it will sit there for a long while and cause your commit to hang.

If you mind not being able to edit the files, you can put a:

chmod -R 777 /home/[user]/labs

at the end of the post-commit.

In reality, that is a huge pain because of permissions and ownership. The easier thing to do is just forget about post-commit, and instead checkout the repo as your user, and then setup a crontab job to run every couple hours and do an svn up. :slight_smile: You can run it manually yourself if you really want to push the changes right away.

The only other alternatives to get the files owned by you is to make a C wrapper program, set it setgid and call that in post-commit, but it just gets more complex, requires compiling a C program everytime you want to change the command, etc.


Beautiful. Works perfectly, thanks a ton Justin!