39148282cc
* Correct the git remote set-url command syntax in admin.mkd
369 lines
15 KiB
Markdown
369 lines
15 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. 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.
|
|
|
|
<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">
|
|
|
|
> 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.
|
|
|
|
</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.
|
|
|
|
### "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]
|
|
|
|
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 :-)
|
|
|
|
* (workstation, old server) **pull** the latest changes to the
|
|
`gitolite-admin` repo to your workstation, if you don't have them
|
|
already. You'll need them later on.
|
|
|
|
* (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
|
|
|
|
Don't forget to chown repositories if git's UID changed. Gitolite expects
|
|
the hosting user to own all the files and directories it manages.
|
|
|
|
* (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!
|
|
|
|
### 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.
|