hook propagation document redone; should flow much easier now
This commit is contained in:
parent
f19a9cf480
commit
9b66643f3a
|
@ -3,131 +3,132 @@
|
||||||
Some users like to know how hooks propagate, and when, and why there appear to
|
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.
|
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
|
**Note**: You don't need to read all this just to add your own hooks or your
|
||||||
new custom hook; treat it as more "theory" than "lab". ([Here][customhooks] is the
|
own functionality to a hook that gitolite uses. See [here][customhooks] and
|
||||||
"lab" version!)
|
[here][hookchaining].
|
||||||
|
|
||||||
## hooks used by gitolite
|
## what hooks do repos get?
|
||||||
|
|
||||||
Gitolite uses only 2 hooks. **All** repos have an `update` hook, without
|
* `update`: all repos have this; it does the write-level access control
|
||||||
which there is no write-level access control (per-branch permissions). The
|
(per-branch permissions).
|
||||||
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
|
* `post-receive`: if you've enabled [mirroring][], all repos have this.
|
||||||
"gitolite-hooked". We'll see later what this does.
|
|
||||||
|
|
||||||
The final objective of all this is that each repo's `hooks/` directory should
|
* `post-update`: only the special "gitolite-admin" repo has this; it acts
|
||||||
get all the hooks that it is meant to get.
|
upon the changes you push to the admin repo.
|
||||||
|
|
||||||
## **where** do I (the admin) put the hooks?
|
* `gitolite-hooked`: not really a hook, but a special, zero-byte file; see
|
||||||
|
below.
|
||||||
|
|
||||||
In general, **all** hooks go into the `hooks/common` directory. Only the
|
* you can add any other hooks you want (see note at the top of this doc),
|
||||||
special `post-update` hook meant for the admin repo goes into
|
and gitolite will propagate them into all repos along with the others.
|
||||||
`hooks/gitolite-admin`.
|
|
||||||
|
|
||||||
Now we'll discuss the locations of these `hooks/common` and
|
## when do repos "get" hooks?
|
||||||
`hooks/gitolite-admin` directories. This depends on which install method you
|
|
||||||
used.
|
|
||||||
|
|
||||||
(Please refer to [doc/1-INSTALL.mkd][install] for what these "methods" are).
|
* When the "compile" script runs, any repo that is named explicitly in the
|
||||||
|
conf file, and the "gitolite-hooked" file is not present, gets hooks.
|
||||||
|
|
||||||
### the `GL_PACKAGE_HOOKS` directory
|
* When someone runs `gl-setup` on the server, then *all* repos physically
|
||||||
|
present inside `$REPO_BASE` get them.
|
||||||
|
|
||||||
You might recall that the "root", and "non-root" methods run a command called
|
A repo does not have to be defined in the config for this to happen.
|
||||||
`gl-system-install`, the third argument of which is some directory of your
|
Also, this includes the initial install; if you already had some repos in
|
||||||
choice (like maybe `/usr/share/gitolite/hooks`). Even though it is not
|
`REPO_BASE` they get the hooks.
|
||||||
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
|
* If `GL_WILDREPOS` is set, a repo gets hooks when a user creates a repo or
|
||||||
already decided what that location is, and the package creation/install
|
uses the "fork" command in "contrib/adc". <font color="gray">In the
|
||||||
process does the equivalent of `gl-system-install`.
|
latter case the hooks are explicitly copied from the source repo using the
|
||||||
|
"cp" command, not using the code internal to gitolite</font>.
|
||||||
|
|
||||||
So now we know there's a location called `$GL_PACKAGE_HOOKS` where you can
|
## what exactly does "get hooks" mean?
|
||||||
place your hooks.
|
|
||||||
|
|
||||||
### the `$HOME/.gitolite` directory
|
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.
|
||||||
|
|
||||||
You might also recall that, in these three methods, each **hosting user** has
|
Other files are left alone, so you *can* manually add a hook file to specific
|
||||||
to run `gl-setup`. This sets up, among other things, `$HOME/.gitolite`
|
repos, directly on the server, so long as there is no name clash.
|
||||||
directory, which also contains a `hooks/` directory.
|
|
||||||
|
|
||||||
So now there are two places you can put your hooks, apparently.
|
## where do the symlinks point?
|
||||||
|
|
||||||
### why two places?
|
There are two places the symlinks can point.
|
||||||
|
|
||||||
Just think of the "package" and "root" methods for now, even if you're using
|
* `$GL_PACKAGE_HOOKS/common` contains the "system" hooks.
|
||||||
the "non-root" method.
|
`GL_PACKAGE_HOOKS` is defined in the rc file.
|
||||||
|
|
||||||
In these two methods, it is reasonable to assume that the entire site (or
|
* `$HOME/.gitolite/hooks/common` has the "user" hooks.
|
||||||
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
|
<font color="gray">The special "post-update" hook for the equally special
|
||||||
clashes, which may necessitate hook chaining, etc., like we already do for the
|
"gitolite-admin" repo is not in either of those places. It's in
|
||||||
hooks that gitolite cares about). He adds these hooks to his
|
`../gitolite-admin` relative to them. Just don't worry about it, and don't
|
||||||
`$HOME/.gitolite/hooks` directory.
|
fiddle with it. **There is no spoon**.</font>
|
||||||
|
|
||||||
When hooks propagate, the ones in `$GL_PACKAGE_HOOKS` override/overwrite the
|
`GL_PACKAGE_HOOKS` is "/var/gitolite/hooks" or some such path for RPM/DEB or
|
||||||
ones in `$HOME/.gitolite/hooks`. Otherwise it wouldn't make sense; you
|
"root" method, and "$HOME/share/gitolite/hooks" for the non-root method.
|
||||||
wouldn't be able to enforce site-wide hooks.
|
(<font color="gray">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</font>).
|
||||||
|
|
||||||
[NOTE: due to a minor quirk, the site-wide hooks in `$GL_PACKAGE_HOOKS` also
|
## so where do I put my hooks?
|
||||||
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)]
|
|
||||||
|
|
||||||
### special case: the "non-root" method
|
Put them in the "user" location (`~/.gitolite/hooks/common`).
|
||||||
|
|
||||||
This method was created later, just piggy-backing on everything that already
|
The "system" location hooks override the ones in the "user" location, as you
|
||||||
existed to cater to the "package" and "root" methods. In this method, the
|
can see from the picture below. This can be useful to enforce site-wide hooks
|
||||||
`$GL_PACKAGE_HOOKS` is as accessible or under your control as
|
when using the RPM/DEB or root install methods. (For the non-root install
|
||||||
`$HOME/.gitolite`, so it doesn't matter where you put your hooks.
|
it's useless, since both locations are under the control of the user).
|
||||||
|
|
||||||
## **when** do hooks propagate?
|
.gv
|
||||||
|
|
||||||
First: realise that gitolite *wants to make sure* that all the hooks in your
|
edge [dir=forward color="blue"]
|
||||||
`hooks/common` directory get copied (symlinked, actually) to *every* repo that
|
splines = false
|
||||||
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:
|
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>
|
||||||
|
>]
|
||||||
|
|
||||||
1. anytime you do an install, gitolite trawls through *all* existing repos
|
gladh [ shape = none label = <
|
||||||
(using the unix `find` command) and force-links all the hooks in all the
|
<table>
|
||||||
repos so they all get the latest and greatest hooks.
|
<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>
|
||||||
|
>]
|
||||||
|
|
||||||
2. anytime you do a "compile" (meaning push changes to the admin repo),
|
rh [ shape = none label = <
|
||||||
gitolite looks through all the repos named in the config. It first checks
|
<table>
|
||||||
if the repo exists, creating it if needed. It then looks for a sentinel
|
<tr>
|
||||||
file called "gitolite-hooked" (an empty file in the hooks directory). If
|
<td colspan="4" bgcolor="green">individual repo hooks<br/>$REPO_BASE/reponame.git/hooks</td>
|
||||||
it doesn't find it, it will assume that hooks need to be propagated.
|
</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>
|
||||||
|
>]
|
||||||
|
|
||||||
This is because people often copy a repo from elsewhere, add it to the
|
rh:y3:n .. gladh:y3
|
||||||
config, and expect things to work. Without this step, those repos don't
|
rh:u:n .. glph:u:s
|
||||||
get the hooks, which is bad -- the access control would have failed
|
rh:y1:n .. glph:y1
|
||||||
silently!
|
rh:y2:n .. glph:y2
|
||||||
|
|
||||||
3. anytime a new repo is created, the same force-linking of hooks happens.
|
As you can see, when both locations have the same hook, the symlink points to
|
||||||
The 3 places a new repo is created are:
|
the "system" hook.
|
||||||
|
|
||||||
* 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.
|
|
||||||
|
|
||||||
|
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?
|
||||||
|
|
Loading…
Reference in a new issue