331 lines
13 KiB
Markdown
331 lines
13 KiB
Markdown
# 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. (Generating a
|
|
keypair is described somewhere in [this][gl_ssh] page).
|
|
|
|
* 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.
|
|
|
|
<font color="red">**IMPORTANT WARNINGS**</font>
|
|
|
|
* 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.
|
|
|
|
<font color="gray">
|
|
|
|
> Also see the document on [virtual refs][vref] for a way to add additional
|
|
> checks that you might need.
|
|
|
|
</font>
|
|
|
|
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**
|
|
|
|
<font color="gray">
|
|
|
|
* 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.
|
|
|
|
</font>
|
|
|
|
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.
|