Automatically update a Subversion working copy on commit

Subversion updating

Subversion updating

Requirements:Subversiongcc

Platform:any Linux distro

Keeping code up-to-date in multiple environments can be a pain in the ass. You might develop on one server, stage on another, and then have all your production code run on yet another server. Thus, getting the most recent code moved to each server can involve a lot of updating from a code repository. If you're using Subversion, it's possible to issue an update automatically anytime a commit is made to a repository. This guide will detail setting up a post-commit hook to update a working copy residing on the same server of a repository. The most painless way to implement this is with a self-compiled executable that executes the "svn update" command. In this case we'll be compiling a C script so that the setuid bit can be set (*nix environments only allow the setuid bit to be set on executables). This will allow the script to execute as root to avoid any permissions problems when updating the Subversion working copy. Let's get rolling. We need to find where the svn command binary is located. Log on to the server where the repository and working copy are located and enter:
$ whereis svn
This should return something like:
svn: /usr/bin/svn /usr/share/man/man1/svn.1.gz
Make note of the first path (the above example is "/usr/bin/svn"). Create a new file called post-commit.c and enter the following code. Make sure to enter the path to svn and the path to the working copy of your code:
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
  execl("/usr/bin/svn", "svn", "--config-dir", "/root/.subversion", 
           "update", "/path/to/working/copy",
        (const char *) NULL);
  return(EXIT_FAILURE);
}
Now compile the script into an executable:
$ gcc -o post-commit post-commit.c
Set the setuid bit:
$ chmod 4755 post-commit
You now have an executable ready for some hot post-commit action. You just need to copy it into your repository's hooks directory. For example, if your repository is named "bar" and it's located in the "foo" directory, you would enter:
$ mv post-commit /foo/bar/hooks/
And you're good to go. Anytime a commit is performed to the repository, the changes will be immediately reflected in the working copy.

Troubleshooting

If your post-commit is failing, you may need to disable Subversion password caching on your repository server. Due to Subversion 1.6's Security Improvements, a plaintext password warning gets issued to the client on initial commands:
-----------------------------------------------------------------------
ATTENTION!  Your password for authentication realm:

   <https://www.mydomain.com> My Repository

can only be stored to disk unencrypted!  You are advised to configure
your system so that Subversion can store passwords encrypted, if
possible.  See the documentation for details.

You can avoid future appearances of this warning by setting the value
of the 'store-plaintext-passwords' option to either 'yes' or 'no' in
'/root/.subversion/servers'.
-----------------------------------------------------------------------
Store password unencrypted (yes/no)?
Since your post-commit hook has no way of responding to this warning, it will fail. To fix this, edit file /root/.subversion/servers and add the following line under the [global] section:
store-passwords = no

Comments

  1. Robert Jones

    Succint and worked like a charm! Thanks!

Leave a Comment