2011-01-29 10:58:57 +01:00
|
|
|
## hook propagation in gitolite
|
2010-06-19 08:03:18 +02:00
|
|
|
|
2011-08-01 12:49:24 +02:00
|
|
|
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**: This is **not** the document to read if you just want to install a
|
|
|
|
new custom hook; treat it as more "theory" than "lab". ([Here][ch] is the
|
|
|
|
"lab" version!)
|
|
|
|
|
|
|
|
[ch]: http://sitaramc.github.com/gitolite/doc/2-admin.html#_custom_hooks
|
2010-06-20 04:36:54 +02:00
|
|
|
|
|
|
|
In this document:
|
|
|
|
|
2010-09-02 15:45:32 +02:00
|
|
|
* <a href="#_hooks_used_by_gitolite">hooks used by gitolite</a>
|
|
|
|
* <a href="#_where_do_I_the_admin_put_the_hooks_">**where** do I (the admin) put the hooks?</a>
|
|
|
|
* <a href="#_the_from_client_method">the "from-client" method</a>
|
|
|
|
* <a href="#_the_other_3_methods">the other 3 methods</a>
|
|
|
|
* <a href="#_the_GL_PACKAGE_HOOKS_directory">the `GL_PACKAGE_HOOKS` directory</a>
|
|
|
|
* <a href="#_the_HOME_gitolite_directory">the `$HOME/.gitolite` directory</a>
|
|
|
|
* <a href="#_why_two_places_">why two places?</a>
|
|
|
|
* <a href="#_special_case_the_non_root_method">special case: the "non-root" method</a>
|
|
|
|
* <a href="#_when_do_hooks_propagate_">**when** do hooks propagate?</a>
|
|
|
|
|
|
|
|
<a name="_hooks_used_by_gitolite"></a>
|
2010-06-20 04:36:54 +02:00
|
|
|
|
|
|
|
### hooks used by gitolite
|
|
|
|
|
|
|
|
Gitolite uses only 2 hooks. **All** repos have an `update` hook, without
|
|
|
|
which there is no write-level access control (per-branch permissions). The
|
|
|
|
special **gitolite-admin** repo has a special `post-update` hook, which is
|
|
|
|
required to do its, umm, special things, like running the "compile" script,
|
|
|
|
etc.
|
|
|
|
|
|
|
|
In addition there is a "sentinel file" -- an empty file called
|
|
|
|
"gitolite-hooked". We'll see later what this does.
|
|
|
|
|
|
|
|
The final objective of all this is that each repo's `hooks/` directory should
|
|
|
|
get all the hooks that it is meant to get.
|
|
|
|
|
2010-09-02 15:45:32 +02:00
|
|
|
<a name="_where_do_I_the_admin_put_the_hooks_"></a>
|
2010-06-20 04:36:54 +02:00
|
|
|
|
|
|
|
### **where** do I (the admin) put the hooks?
|
|
|
|
|
|
|
|
In general, **all** hooks go into the `hooks/common` directory. Only the
|
|
|
|
special `post-update` hook meant for the admin repo goes into
|
|
|
|
`hooks/gitolite-admin`.
|
|
|
|
|
|
|
|
Now we'll discuss the locations of these `hooks/common` and
|
|
|
|
`hooks/gitolite-admin` directories. This depends on which install method you
|
|
|
|
used.
|
|
|
|
|
2010-09-02 15:45:32 +02:00
|
|
|
(Please refer to [doc/1-INSTALL.mkd][0inst] for what these "methods" are).
|
2010-06-20 04:36:54 +02:00
|
|
|
|
2010-09-02 15:45:32 +02:00
|
|
|
<a name="_the_from_client_method"></a>
|
2010-06-20 04:36:54 +02:00
|
|
|
|
|
|
|
#### the "from-client" method
|
|
|
|
|
|
|
|
Let's get this out of the way first, because it is simple: if you're using the
|
|
|
|
"from-client" method, there's only one place: the `hooks` directory in your
|
|
|
|
gitolite clone on the client side. This is where you run
|
|
|
|
`src/gl-easy-install` from. Nothing else in this section is relevant to this
|
|
|
|
method; skip to the next section ("when do hooks propagate") if you installed
|
|
|
|
using the "from-client" method.
|
|
|
|
|
2010-09-02 15:45:32 +02:00
|
|
|
<a name="_the_other_3_methods"></a>
|
2010-06-20 04:36:54 +02:00
|
|
|
|
|
|
|
#### the other 3 methods
|
|
|
|
|
2010-09-02 15:45:32 +02:00
|
|
|
<a name="_the_GL_PACKAGE_HOOKS_directory"></a>
|
2010-06-20 04:36:54 +02:00
|
|
|
|
|
|
|
##### the `GL_PACKAGE_HOOKS` directory
|
|
|
|
|
|
|
|
You might recall that the "root", and "non-root" methods run a command called
|
|
|
|
`gl-system-install`, the third argument of which is some directory of your
|
|
|
|
choice (like maybe `/usr/share/gitolite/hooks`). Even though it is not
|
|
|
|
necessary to know this, internally this becomes the value of the
|
|
|
|
`$GL_PACKAGE_HOOKS` variable, so in this document we will refer to that
|
|
|
|
variable instead of the location (because you might choose any location you
|
|
|
|
like for it).
|
|
|
|
|
|
|
|
The "package" method also has the same property, except that the packager has
|
|
|
|
already decided what that location is, and the package creation/install
|
|
|
|
process does the equivalent of `gl-system-install`.
|
|
|
|
|
|
|
|
So now we know there's a location called `$GL_PACKAGE_HOOKS` where you can
|
|
|
|
place your hooks.
|
|
|
|
|
2010-09-02 15:45:32 +02:00
|
|
|
<a name="_the_HOME_gitolite_directory"></a>
|
2010-06-20 04:36:54 +02:00
|
|
|
|
|
|
|
##### the `$HOME/.gitolite` directory
|
|
|
|
|
|
|
|
You might also recall that, in these three methods, each **hosting user** has
|
|
|
|
to run `gl-setup`. This sets up, among other things, `$HOME/.gitolite`
|
|
|
|
directory, which also contains a `hooks/` directory.
|
|
|
|
|
|
|
|
So now there are two places you can put your hooks, apparently.
|
|
|
|
|
2010-09-02 15:45:32 +02:00
|
|
|
<a name="_why_two_places_"></a>
|
2010-06-20 04:36:54 +02:00
|
|
|
|
|
|
|
#### why two places?
|
|
|
|
|
|
|
|
Just think of the "package" and "root" methods for now, even if you're using
|
|
|
|
the "non-root" method.
|
|
|
|
|
|
|
|
In these two methods, it is reasonable to assume that the entire site (or
|
|
|
|
server) has certain policies that they want to implement using hooks. They
|
|
|
|
want to enforce these hooks on *each hosting user*. These hooks go into
|
|
|
|
`$GL_PACKAGE_HOOKS`.
|
|
|
|
|
|
|
|
Each hosting user then has the discretion to add his own hooks (modulo name
|
|
|
|
clashes, which may necessitate hook chaining, etc., like we already do for the
|
|
|
|
hooks that gitolite cares about). He adds these hooks to his
|
|
|
|
`$HOME/.gitolite/hooks` directory.
|
|
|
|
|
|
|
|
When hooks propagate, the ones in `$GL_PACKAGE_HOOKS` override/overwrite the
|
|
|
|
ones in `$HOME/.gitolite/hooks`. Otherwise it wouldn't make sense; you
|
|
|
|
wouldn't be able to enforce site-wide hooks.
|
|
|
|
|
|
|
|
[NOTE: due to a minor quirk, the site-wide hooks in `$GL_PACKAGE_HOOKS` also
|
|
|
|
get copied to `$HOME/.gitolite/hooks` when you "install". I need to fix and
|
|
|
|
thoroughly test this later; for now, just ignore the extra files you see in
|
|
|
|
there; they're harmless/redundant (TODO)]
|
|
|
|
|
2010-09-02 15:45:32 +02:00
|
|
|
<a name="_special_case_the_non_root_method"></a>
|
2010-06-20 04:36:54 +02:00
|
|
|
|
|
|
|
#### special case: the "non-root" method
|
|
|
|
|
|
|
|
This method was created later, just piggy-backing on everything that already
|
|
|
|
existed to cater to the "package" and "root" methods. In this method, the
|
|
|
|
`$GL_PACKAGE_HOOKS` is as accessible or under your control as
|
2011-07-08 04:25:57 +02:00
|
|
|
`$HOME/.gitolite`, so it doesn't matter where you put your hooks.
|
2010-06-20 04:36:54 +02:00
|
|
|
|
2010-09-02 15:45:32 +02:00
|
|
|
<a name="_when_do_hooks_propagate_"></a>
|
2010-06-20 04:36:54 +02:00
|
|
|
|
|
|
|
### **when** do hooks propagate?
|
2010-06-19 08:03:18 +02:00
|
|
|
|
|
|
|
First: realise that gitolite *wants to make sure* that all the hooks in your
|
|
|
|
`hooks/common` directory get copied (symlinked, actually) to *every* repo that
|
|
|
|
gets created. **Not doing so is generally a security risk; because the
|
|
|
|
primary purpose of gitolite is access control, people generally *want* hooks
|
|
|
|
to run.**
|
|
|
|
|
|
|
|
Here's how/when hooks are created/propagated:
|
|
|
|
|
|
|
|
1. anytime you do an install, gitolite trawls through *all* existing repos
|
|
|
|
(using the unix `find` command) and force-links all the hooks in all the
|
|
|
|
repos so they all get the latest and greatest hooks.
|
|
|
|
|
|
|
|
2. anytime you do a "compile" (meaning push changes to the admin repo),
|
|
|
|
gitolite looks through all the repos named in the config. It first checks
|
|
|
|
if the repo exists, creating it if needed. It then looks for a sentinel
|
|
|
|
file called "gitolite-hooked" (an empty file in the hooks directory). If
|
|
|
|
it doesn't find it, it will assume that hooks need to be propagated.
|
|
|
|
|
|
|
|
This is because people often copy a repo from elsewhere, add it to the
|
|
|
|
config, and expect things to work. Without this step, those repos don't
|
|
|
|
get the hooks, which is bad -- the access control would have failed
|
|
|
|
silently!
|
|
|
|
|
|
|
|
3. anytime a new repo is created, the same force-linking of hooks happens.
|
|
|
|
The 3 places a new repo is created are:
|
|
|
|
|
|
|
|
* the "compile" case mentioned above, where the admin added a normal
|
|
|
|
repo to the config and pushed
|
|
|
|
|
|
|
|
* the wildrepos case, where you have "C" permissions and the repo does
|
|
|
|
not already exist
|
|
|
|
|
|
|
|
* the `fork` command in `contrib/adc`. In this case the hooks are
|
|
|
|
explicitly copied from the source repo using the `cp` command, not
|
|
|
|
using the code internal to gitolite.
|
|
|
|
|
|
|
|
For people who do not want certain hooks to run for certain repos, one simple
|
|
|
|
solution that will work right now is to check the value of `$GL_REPO` at the
|
|
|
|
start of the hook, and `exit 0` based on what it contains/matches.
|
2010-06-20 04:36:54 +02:00
|
|
|
|
2011-01-26 03:09:12 +01:00
|
|
|
[0inst]: http://sitaramc.github.com/gitolite/doc/1-INSTALL.html
|
2010-06-20 04:36:54 +02:00
|
|
|
|