Fixing permissions in Subversion post-commit hooks

Armijn Hemel, October 27, 2009, 18518 views.

Subversion is a great version control system and it allows for a lot of tweakability, but a mistake with permissions is easily made...and easily fixed.

Tags: ,

The code we develop for customers and ourselves are kept in several Subversion repositories. The reasons we chose for Subversion are historical, since we grew up with CVS.

One of the things we do for some Subversion repositories is to do an automatic checkout, or an automatic update of a checked out repository. For us it works very well, but there is one thing which took us a bit longer to solve (mostly because of other more urgent things to fix): permissions in checkouts done with a post-commit hook.

Subversion hooks

In every Subversion repository there is a directory hooks, in which you can put extra programs to control what happens when there is a commit. Usually you don't want to do anything, but it can come in handy. The directory hooks contains a few example scripts. One post-commit script we use for some repositories is to do a fresh checkout or update of a checkout every time there is an update.

Problems with post-commit hooks

If you use the svn protocol over SSH to access repositories what happens when you do a checkout or commit is that you log in with SSH to the server and launch a temporary local Subversion server, which runs as the user (and with attached permissions) you log in with. The hooks from the Subversion repository will also be run as that user.

In our case this is not OK. There are two users, both have a different user id and main group, but are in a shared group (svn). The checkout and all contents of the checked out versions of repositories on our system are typically owned by group svn. An update done as one user interferes with the checkout from another user and writes files and directories using the main group for that other user, sometimes resulting in a not fully completed checkout.

Linux and groups

On a Linux system every user belongs to one or more groups. Using the groups command you can see which groups you currently belong to, for example:

$ groups 
armijn

This is not necessarily the same list as the set of groups you are in on the system, which you can check with the id command (but you have to add the username as a parameter):

$ id armijn
uid=500(armijn) gid=500(armijn) groups=500(armijn),501(test)

Forcing the current group can be done using the newgrp command:

$ groups
armijn
$ newgrp test
$ groups
test armijn

The current group will have changed to test:

$ touch /tmp/foobar
$ ls -l /tmp/foobar
-rw-r--r-- 1 armijn test 0 2009-10-26 22:39 /tmp/foobar

Changing groups again will change the current group:

$ newgrp armijn
$ groups
armijn test
$ touch /tmp/foobaz; ls -l /tmp/foobaz
-rw-rw-r-- 1 armijn armijn 0 2009-10-26 22:40 /tmp/foobaz

newgrp and Subversion post-commit hooks

A typical Subversion post-commit hook could look like this:

#!/bin/sh
BASE=/tmp/foosvn
svn update $BASE

It updates the checkout in $BASE on the server (an initial checkout should be made by hand first in this case) every time there is a commit.

These checkouts are run as the user which logs in which might not be desirable, as explained above. The logical thing to do is to change the current user id, for example:

#!/bin/sh
newgrp
BASE=/tmp/foosvn
svn update $BASE
exit

Unfortunately this does not work and if you do a commit it will hang without the desired results. To work around this you can make use of so called 'here documents' available in bash:

BASE=/tmp/foosvn
newgrp svn <<FOO
/usr/bin/svn update $BASE
exit
FOO

With this little trick we got everything to work as expected: files and directories in the checked out version of the repository are owned by group svn.

Social networking: Tweet this article on Twitter Pass on this article on LinkedIn Bookmark this article on Google Bookmark this article on Yahoo! Bookmark this article on Technorati Bookmark this article on Delicious Share this article on Facebook Digg this article on Digg Submit this article to Reddit Thumb this article up at StumbleUpon Submit this article to Furl

Talkback

respond to this article