Monday, May 3, 2010

SVN: write post-commit hooks using PHP

Linux shell scripting might be difficult for a number of people. Hence, I am writing this to help those who are not familiar with shell scripting.

There are cases when you want to see the changes immediately after committing your work to svn server. There are 2 ways I can think of:
  1. Go to svn server and do a manual svn update. I do not recommend this repetitive task.
  2. Creating a post-commit hook that do the svn update automatically.  
This guide will help you create a post-commit hook using PHP script.

Requirements:
Assumptions:
  • You should have multiple repositories. Unless you have only one project. By having multiple repositories, you can have a different version control for each repository.
Go to your svn repository, in my case it's located under:
/home/svn/projectX
You should see a number of directories under projectX, let's look at hooks and forget the rest. You should see the following files:
  • post-commit.tmpl
  • post-lock.tmpl
  • post-revprop-change.tmpl
  • post-unlock.tmpl
  • pre-commit.tmpl
  • pre-lock.tmpl
  • pre-revprop-change.tmpl
  • pre-unlock.tmpl
  • start-commit.tmpl
For this guide we only interested in post-commit hook. This hook will execute after some body commit their work to svn server. You can easily do the same for all other hooks.

Now, create a new file call post-commit. This file will be executed after svn commit is executed.
#!/usr/bin/php5
<?php

/* Debugging - you never know if this file is being executed! Check the log */
//file_put_contents('/tmp/svn.log',  date("H:i:s"));

/* Location of your web directory */
chdir('/home/web/svn');

/* All projects check out should be here */
$repos = scandir('.'); 
/* Only do svn update if the repository committed is found in the /home/web/svn */
if ($repo = basename($_SERVER['argv'][1]) && in_array(
$repo, $repos)) {
    `/usr/bin/svn update $repo --username username --password password --quiet`;
}
Make sure this file have executable permission and its belong to correct user /group. If you can't make it works, try:
chmod 0777 post-commit
This would allowed everyone to execute post-commit script.

Note: there are 2 arguments passed to the post-commit script:
  1. $_SERVER['argv'][1]  (the path to this repository)
  2. $_SERVER['argv'][2]  (the number of the revision just committed)