F=hook_prop hook propagation in gitolite

Some users like to know how hooks propagate, and when, and why there appear to be two places to put them, and so on. I'll try and set out the logic here.

Note: You don't need to read all this just to add your own hooks or your own functionality to a hook that gitolite uses. See [here][customhooks] and [here][hookchaining].

what hooks do repos get?

when do repos "get" hooks?

what exactly does "get hooks" mean?

The "hooks/" directory of the bare repo on the server will forcibly have symlinks created for each of the hooks mentioned in the "what hooks..." section.

Other files are left alone, so you can manually add a hook file to specific repos, directly on the server, so long as there is no name clash.

where do the symlinks point?

There are two places the symlinks can point.

The special "post-update" hook for the equally special "gitolite-admin" repo is not in either of those places. It's in ../gitolite-admin relative to them. Just don't worry about it, and don't fiddle with it. There is no spoon.

GL_PACKAGE_HOOKS is "/var/gitolite/hooks" or some such path for RPM/DEB or "root" method, and "$HOME/share/gitolite/hooks" for the non-root method. (Basically, it's whatever you gave as the 3rd argument to 'gl-system-install' when you used the root or non-root methods, or whatever the packager decided if you used the RPM/DEB method).

so where do I put my hooks?

Put them in the "user" location (~/.gitolite/hooks/common).

The "system" location hooks override the ones in the "user" location, as you can see from the picture below. This can be useful to enforce site-wide hooks when using the RPM/DEB or root install methods. (For the non-root install it's useless, since both locations are under the control of the user).

.gv

edge [dir=forward color="blue"]
splines = false

glph [ shape = none label = <
    <table>
        <tr>
            <td colspan="3" bgcolor="red">package/system hooks<br/>$GL_PACKAGE_HOOKS/common</td>
        </tr><tr>
            <td port="u" bgcolor="lightblue">update</td>
            <td port="y1">yourhook1</td>
            <td port="y2">yourhook2</td>
        </tr>
    </table>
>]

gladh [ shape = none label = <
    <table>
        <tr>
            <td colspan="3" bgcolor="green">user hooks<br/>~/.gitolite/hooks/common</td>
        </tr><tr>
            <td port="u" bgcolor="lightblue">update</td>
            <td port="y1">yourhook1</td>
            <td port="y3">yourhook3</td>
        </tr>
    </table>
>]

rh [ shape = none label = <
    <table>
        <tr>
            <td colspan="4" bgcolor="green">individual repo hooks<br/>$REPO_BASE/reponame.git/hooks</td>
        </tr><tr>
            <td port="u" bgcolor="lightblue">update</td>
            <td port="y1">yourhook1</td>
            <td port="y2">yourhook2</td>
            <td port="y3">yourhook3</td>
        </tr>
    </table>
>]

rh:y3:n .. gladh:y3
rh:u:n .. glph:u:s
rh:y1:n .. glph:y1
rh:y2:n .. glph:y2

As you can see, when both locations have the same hook, the symlink points to the "system" hook.

By default, the only reason you need to touch the "system" location is if you want to modify the 'update' hook, but why would you fiddle with the most important part of gitolite, huh? You're a good admin, and will use [hook chaining][hookchaining] properly, right?

why not just push a hook?

A question I often get is, why can't we simply push the hooks using the admin repo, just like we push config changes.

To understand why, realise that in many sites, the "right to push the gitolite-admin repo" is not the same as "right to get a command line on the server and run arbitrary commands".

This means, gitolite tries its best to keep these two rights separated, and to prevent someone who has the former right from trivially acquiring the latter.

And so we don't allow adding hooks by admin push.

That doesn't mean you can't do it yourself. Here's one possible way.

Using the simple instructions [here][customhooks], add a post-update.secondary hook containing this code:

#!/bin/bash
cp $GL_ADMINDIR/local-hooks/* $GL_ADMINDIR/hooks/common
gl-setup

Now create a directory in your gitolite-admin clone called "local-hooks", put all your hooks there, and add/commit/push.

That should do it. Test it and send me a patch for this document when you do :-)