# administering and running gitolite
In this document:
* please read this first
* adding users and repos
* using hooks
* custom hooks
* "gl-post-init" hook
* "gl-pre-git" hook
* hook chaining
* environment variables available to hooks
* other features
* moving pre-existing repos into gitolite
* moving the whole thing from one server to another
* specifying gitweb and daemon access
* custom git config
----
### 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.
### 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
[doc/gitolite.conf.mkd][confmkd] in the gitolite source 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.
### using hooks
#### 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!
#### "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.
#### "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.
#### 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
### other features
#### 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.
[wild]: http://sitaramc.github.com/gitolite/doc/wildcard-repositories.html
First read [doc/wildcard-repositories.mkd][wild], 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 [doc/wildcard-repositories.mkd][wild] 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.
#### moving the whole thing from one server to another
[**NOTE**: I would appreciate help testing these instructions]
Just copying everything won't work unless everything on the new server is
exactly the same. I suggest you don't try it unless you know what you're
doing.
**Assumptions**
* you have not changed `$REPO_BASE` on either of the servers; if you did,
substitute accordingly
* the admin's name is "YourName" -- again, substitute accordingly!
* the "hosting user" on both servers is "git". Substitute whatever you're
actually using (for example, if you're installing using RPM/DEB, this
would be "gitolite")
There are many ways of doing this, but the most *generic* set of steps are
given below. Please follow all the steps; do not skip or improvise! Ask me
if things are not clear -- you can help me fine tune this document :-)
* (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;
* (new server) **copy** the repos to the new server, **except** the
`gitolite-admin` repo and files called `gitolite-hooked` in the `hooks`
directory of each repo.
That sounds complicated but it's not. It's just:
cd $HOME
rsync -a olduser@oldhost:repositories .
mv repositories/gitolite-admin.git $HOME/old-gitolite-admin.git
find repositories -name gitolite-hooked | xargs rm
* (workstation, new server) **install** gitolite normally on your new
server. Use whatever install method suits you, but you must use the
**same** name for the admin ("YourName" in the install instructions). You
may use a different keypair if you need to, or use the same one that
currently gets access to the old server.
* (new server) **edit** the `~/.gitolite.rc` file to match the settings on
the old server, if needed. 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.
* (workstation) **push** the config to the new server. To do this, go to
your admin clone, and:
* if you used a different keypair when installing to the new server,
copy that pubkey to this clone into `keydir/Yourname.pub`, then add
and commit the change to the pubkey
cd gitolite-admin
cp path/to/new/YourName.pub keydir/YourName.pub
git add keydir
git commit -m "new server, new key"
* if you did *not* use a different keypair, just make a dummy commit
git commit -m "new server" --allow-empty
* set the URL for the new server
git remote --set-url origin git@newserver:gitolite-admin
* push the config, including past history
git push -f
And that should be that!
#### specifying gitweb and daemon access
This is a feature that I personally do not use (corporate environments don't
like unauthenticated access of any kind to any repo!), but someone wanted it,
so here goes.
Gitolite has two pre-defined, "special", usernames: `daemon` and `gitweb`.
To make a repo or repo group accessible via "git daemon", just give read
permission to the special user "daemon". Similarly, give read permission to
`gitweb` to allow the gitweb CGI to show the repo. Something like this:
repo foo bar baz
R = gitweb daemon
This gives you a quick way to offer multiple repos up for gitweb and/or daemon
access.
However, setting a description for the project also enables gitweb permissions
so you can do it that way if you want. Of course in this case you have to
deal with each repo separately. Add lines like this to gitolite.conf:
foo = "some description"
bar = "some other description"
baz = "yet another description"
You can also specify an owner for gitweb to show, if you like; for example I
might use:
gitolite "Sitaram Chamarty" = "fast, secure, fine-grained, access control for git"
Note that gitolite does **not** install or configure gitweb/git-daemon -- that
is a one-time setup you must do separately. All gitolite does is:
* for daemon, create the file `git-daemon-export-ok` in the repository
* for gitweb, add the repo (plus owner name, if given) to the list of
projects to be served by gitweb (see the config file variable
`$PROJECTS_LIST`, which should have the same value you specified for
`$projects_list` when setting up gitweb)
* put the description, if given, in `$repo/description`
The "compile" script will keep these files consistent with the config settings
-- this includes removing such settings/files if you remove "read" permissions
for the special usernames or remove the description line.
Please **note** that giving permissions to these special users via `@all`
(that is, using either `repo @all` or `R = @all`), will not work unless you
set the rc-file variable `$GL_ALL_INCLUDES_SPECIAL` to `1`. Also, **NOTE**
that giving them read access to `repo @all` means the `gitolite-admin` repo is
also accessible. **It is upto you to decide if that is OK in your
environment**.
#### custom git config
The custom hooks feature is a blunt instrument -- all repos get the hook you
specified and will run it. In order to make it a little more fine-grained,
you could set your hooks to only work if a certain "gitconfig" variable was
set. Which means we now need a way to specify "git config" settings on a per
repository basis.
Thanks to Teemu (teemu dot matilainen at iki dot fi), gitolite now does this
very easily. For security reasons, this can only be done from the master
config file (i.e., if you're using delegation, the delegated admins cannot
specify git config settings).
Please see `doc/gitolite.conf.mkd` for syntax and limitations. Also note that
this feature is disabled by default. Read the comments on a variable called
`GL_GITCONFIG_KEYS` in the rc file documentation, then set it to some
appropriate value, to enable this feature.
[genpub]: http://sitaramc.github.com/0-installing/2-access-gitolite.html#generating_a_public_key
[confmkd]: http://sitaramc.github.com/gitolite/doc/gitolite.conf.html