The Rub

AUTOMATICALLY SIMPLE SINCE 2002

Adding Custom Hooks to Gitolite

Gitolite is the best thing going at the moment for deploying Git in a controlled centralized environment. It features fine grained access control and many powerful features. The author, sitaramc, is very active and receptive of feedback and patches.

Gitolite’s author believes in a separation of privileges between gitolite admin access and system shell access. Due to this design philosophy, custom hooks require a little extra work. If you enable this type of feature, understand that anyone that can push a hook to the server essentially has shell access.

We are still in an early beta phase, so feedback is welcome.

In our gitolite-admin repository, we created a new directory for our hooks. Do not call it hooks! On push, this directory will be copied by gitolite setup to ~git/.gitolite/.

Once the custom hooks directory is getting populated on the server, there needs to be a way to enable or disable individual hooks on a per-repository basis, from the gitolite config file.

In our case, we have a pre-receive hook to do some issue tracking integration against ClearQuest.

In ~git/.gitolite.rc, enable the custom config key for the hook. In this case it’s called “cqintegration”.

    GIT_CONFIG_KEYS => 'gitweb\.description hooks\.cqintegration',

In gitolite.conf, enable the option for a specific repository:

    repo official/myrepo
        desc = My Repository
        RW+     =   @all
        config hooks.cqintegration = true

At this point, once gitolite.conf is pushed, the option should be verified by viewing ~git/repositories/official/myrepo.git/config. It should have a line that looks like this:

    [hooks]
     cqintegration = true

Now, setup the hook to respect the configuration option. There’s probably a more clean way to accomplish this.

#!/bin/sh

cqintegration=$(git config hooks.cqintegration)
cqintegration_ec=$?

if [ ${cqintegration_ec} -eq 0 ]; then
    if [ ${cqintegration} = "true" ]; then
        while read LINE; do
           hooks/my-custom-hook ${LINE}
        done
    fi
fi

To actually get the hook connected to your git repositories, there are a few options.

Gitolite provides a way to push the hooks at http://sitaramc.github.com/gitolite/special.html#pushhook.

Alternatively, for each new hook the administrator could go into ~git/.gitolite/hooks/common on the server and create a symlink to the new hook. After gitolite setup is run, it will detect the symlinks in the common directory and create symlinks in each of the repository hooks directories. It is a symlink to a symlink, but it works fine at least on *nix operating systems.

[email protected]:~/.gitolite/hooks/common$ ln -s ../../my_hooks/common/post-receive
[email protected]:~/.gitolite/hooks/common$ gitolite setup

Verify by looking at the hooks directory of a repository and seeing a post-receive symlink.

Please read the gitolite documentation, in particular http://sitaramc.github.com/gitolite/cust.html#hooks before implementing additional hooks.