# F=admin administering and running gitolite ## please read this first Unless you know what you're doing, do not do **anything** manually on the server (except when the documentation says you should, for example to add custom hooks). In particular, adding new repositories or users or changing the access control rules should not be done directly on the server. Things will break. For example, if you manually create a repo on the server, it will not have the required "update" hook, without which there is no access control for pushes. Most normal (day-to-day) gitolite admin work is done by cloning the gitolite-admin repo from the server to your workstation, making changes to the clone, and pushing those changes back. The installation steps in the previous section include the steps to do this clone, so you should already have one on your workstation, in `~/gitolite-admin`. You can of course clone it anywhere else you want and use that clone. Either way, make sure you `cd` into this clone first. *Note*: some of the paths in this document use variable names. Just refer to `~/.gitolite.rc` for the correct values for *your* installation. Once you've cloned it, you're ready to add users and repos. ## F=add adding users and repos Do **NOT** add repos or users directly on the server! You MUST manage the server by cloning the special 'gitolite-admin' repo on your workstation (`git clone git@server:gitolite-admin`), making changes, and pushing them. This section tells you how to add users and repos. * ask each user who will get access to send you a public key. See other sources (for example [here][genpub]) for how to do this * rename each public key according to the user's name, with a `.pub` extension, like `sitaram.pub` or `john-smith.pub`. You can also use periods and underscores * copy all these `*.pub` files to `keydir` in your gitolite-admin repo clone. You can also organise them into various subdirectories of `keydir` if you wish, since the entire tree is searched. * edit the config file (`conf/gitolite.conf` in your admin repo clone). See the [gitolite.conf][conf] documentation for details on what goes in that file, syntax, etc. Just add new repos as needed, and add new users and give them permissions as required. The users names should be exactly the same as their keyfile names, but without the `.pub` extension * when done, commit your changes and push. Any new repos you specified will automatically be created (empty, but clonable) and users' access will be updated as needed. [genpub]: http://sitaramc.github.com/0-installing/2-access-gitolite.html#generating_a_public_key ## F=hooks using hooks ### #customhooks custom hooks You can supply your own, custom, hook scripts if you wish. Install gitolite as usual, then: * go to ~/.gitolite/hooks/common on the server and put your new hook there * now run "gl-setup" again You can use this procedure to install new hooks as well as to update hooks that you had previously installed. **IMPORTANT WARNINGS** * The `update` hook in `hooks/common` is what implements all the branch-level permissions in gitolite. If you fiddle with the hooks directory, please make sure you do not mess with this file accidentally, or all your fancy per-branch permissions will stop working. * Do not under any conditions put anything in `hooks/gitolite-admin` -- nothing in gitolite requires you to do anything here. Leave it alone! ### #hookchaining hook chaining Sometimes you need to use git hooks for your own purposes (site-local validations, CI integration, email notifications, or the ever popular "live website update"!). However, the hooks you want to use may already be in use by gitolite. This section will tell you what to do in such cases. First, let's list the hooks that gitolite uses: * The `update` hook is used in all repos and is critical to gitolite's access control! * The `post-receive` hook is used in all repos but only if mirroring has been enabled. Shipped as `post-receive.mirrorpush`, it is renamed to 'post-receive' and installed as part of the mirroring setup. * The `post-update` hook is used in the `gitolite-admin` repo only, to "compile" the configuration and so on. To run your own 'update' hook, just put it in a file called `update.secondary` and install it as a hook. Gitolite's update hook will automatically chain to it, taking care to pass it the same 3 arguments the original update hook received from git. > In addition, gitolite now contains the basic infrastructure to support > multiple 'update' hooks without having to remember to chain them yourself. > See `hooks/common/update.secondary.sample` for instructions. For `post-receive`, (if using mirroring) do the opposite. You're normally expected to rename the shipped 'post-receive.mirrorpush' to 'post-receive', but don't do this. Instead, simply run `hooks/post-receive.mirrorpush` at the end of *your* hook code. Do not worry about replicating STDIN (the documented way in which a post-receive hook receives its input) because the mirroring code does not use it. To run your own `post-update` hook on normal repos, just install a hook called 'post-update' the usual way. It'll be installed on all normal repos but not on the special gitolite-admin repo. If you need that for the gitolite-admin repo, you'll have to call it `post-update.secondary`. Finally, these names ('update.secondary' and 'post-update.secondary') are merely the defaults. You can change them to anything you want; look in conf/example.gitolite.rc for details. ### environment variables available to hooks The following environment variables are set, and may be useful for any custom processing you wish to do in your hook code: * `GL_USER` -- the user doing the push * `GL_REPO` -- the reponame * `GL_REPO_BASE_ABS` -- the absolute base path where all the repos are kept The following variables are also set, but are generally less useful: * `GL_BINDIR` -- where all the binaries live * `GL_ADMINDIR` -- common directory for many gitolite things ### "gl-post-init" hook Sometimes it is necessary to do something whenever a new repo is created. If you need this functionality, just supply a hook called "gl-post-init" with whatever code you want in it. ### #pre-git "gl-pre-git" hook Although git has lots of nice hooks you can tap into, they all run only on a push. There's nothing that runs on a fetch or a clone, and there's no way to run something *before* git-receive-pack or git-upload-pack, (as the case may be) are invoked. That's what the `gl-pre-git` hook is for. If an executable hook called `gl-pre-git` is present, it will be invoked with the current directory set to `repo.git`, and with a single argument which will be either `R` or `W` depending on what the client is trying to do. The environment variables `GL_USER` and `GL_REPO` are available. STDOUT will be forced to STDERR before it is called, to avoid confusing the client. If the code returns anything other than 0, gitolite will terminate the operation (i.e., not run git at all), just like many git hooks do, so make sure you end with `exit 0` or equivalent. ## other features ### F=moverepos moving pre-existing repos into gitolite It's best to split this into different use cases. **Case 1 -- few repos**: This is for moving one or two repos at a time, when you have a copy of the repo on your workstation. It is also the *only* way if you have push rights to the admin repo but no *shell* privileges on the server. * let gitolite create it as a brand new repo as described in the section on "adding users and repos" at the top * cd to the clone on your workstation. Make sure all the branches are correct and no extra stuff, "temp" branches, etc., are present * now run these two commands git push --all git@server:reponame git push --tags git@server:reponame * (You could also use "git push --mirror" instead of separately doing branches and tags, but that will carry across *your* remote refs also, and typically you may not want that. Anyway please do a `git ls-remote git@server:repo` to make sure all the stuff you want went through, and is named correctly). **Case 2 -- many repos**: This is when you have many existing repos to add, and they're all bare (as good little server repos should be) and you have shell access on the server. Here's how to do it; please note the order is important here: * make doubly sure they're *bare* repos ;-) * log on to the server and copy the repos to `$REPO_BASE` (which defaults to `~/repositories`), making sure that the directory names end in ".git". * back on your workstation, add each repo (without the `.git` suffix) to `conf/gitolite.conf` in your gitolite-admin repo clone. Give *some* user (even a non-existent one like "DUMMY" is fine) at least "R" access to these repos. Then add, commit, push. **Case 3 -- far too many repos** (or your initials are JH ;-): This is when you're like Case 2, except you have *so many* repos that step 3 becomes too cumbersome (even with a script doing it for you). Assuming you can group your repo names into various patterns, and can use similar access control lines within each such group, you can use gitolite's "wildcard repos" feature. First read the [wildcard repositories][wild] document, or at least skim through it, to understand the basic concept. Then do this: * do step 1 just like step 1 in Case 2 above * ditto for step 2 * for each repo, determine who the owner should be and create files called `gl-creater` (note spelling!) in each repo. The file should contain exactly one line with the owner name. * run `gl-setup` again (you don't need to supply a pub key filename) * finally add the repos to the conf, maybe something like this, (in this example, the owner name was the second component of the repo path), and add/commit/push: repo pub/CREATOR/..* C = @developers RW+ = CREATOR RW = WRITERS R = READERS **Details** * why is the order of steps different in case 1 and case 2? Because in case 2, the actual data is coming from an OS 'cp' (copy) command, not via a normal push like in case 1. Since that happens outside gitolite, it's easier to do it first, then tell gitolite about the repo so it can add hooks. (If you tell gitolite first, it will create an empty repo as soon as you push, then your 'cp' will have to overwrite those files, but you'll then lose gitolite's hooks, etc. A bit more messy). * what's with the `gl-creater` file in case 3? What the [wildcard repositories][wild] document does not explain is how ownership is *recorded* in gitolite: the `gl-creater` file contains the owner name. If you want to "pretend" these repos were created by some user, you need to add that in. That user then gets whatever access you gave to "CREATOR" in the access rules (in our example, that was `RW+`). * why does case 3 need the `gl-setup` command? An admin push only checks hooks on normal (non-wildcard) repos. It would be too timetaking otherwise. Running `gl-setup` forces it to do this more aggressively than an admin push, looking at wildcard repos as well as normal ones. In the end, it all boils down to (a) making sure the `update` hook is correct on all repos, wild or normal, and (b) making sure `gl-creater` contains the owner name for wild repos. The rest of the setup is in the conf file. ### F=moveserver moving the whole thing from one server to another [**NOTE**: I would appreciate help testing these instructions] Here's the simplest set of instructions, assuming the destination is a recent gitolite (has the 'gl-admin-push' command). Unless specified, all steps are on the *new* server. * **install** gitolite. Don't worry about the pubkey used in the gl-setup step -- for example this will do fine: ssh-keygen -q -N '' -f dummy gl-setup -q dummy.pub * **edit** the rc file to have similar settings to the old one. Do not copy the entire file outright -- some of the variables (notably `GL_PACKAGE_CONF` and `GL_PACKAGE_HOOKS`) are installation dependent and should not be touched! Do a diff or a vimdiff and copy across only what you know *you* changed on the old server. * **disable** the old server so your users will not push any changes to it. There are several ways to do this, but the simplest is to insert this line at the top of `~/.gitolite.rc` on the old server: exit 1; * **copy** the contents of `$REPO_BASE` in the old server to `$REPO_BASE` on the new server. By default, as you know, these are both `$HOME/repositories`. * **`chown -R`** the files to the correct user if you copied using root. * **fix up** the hooks gl-setup * **trigger** a push to the admin repo git clone repositories/gitolite-admin.git /tmp/gitolite-admin cd /tmp/gitolite-admin git commit --allow-empty -m 'trigger compile on new server' gl-admin-push -f Done. ### custom git config The custom hooks feature is a blunt instrument -- all repos get the hook you specified and will run it. You can of course install hooks manually on the server, but sometimes that's cumbersome. Instead, you could set your hooks to only work if a certain "gitconfig" variable was set. See [this][rsgc] for a way to specify "git config" settings on a per repository basis.