Requesting an account

Before requesting an account, please check the list of existing accounts to see if there is already an account you can use.

To request an account you must be a member of University or college staff. Please send the following details to

  • Your institution and group, used for naming the account.
    (The group is omitted for institution-wide accounts.)
  • Your user name (CRSID).
  • Your ssh public key.

Duties of an account administrator

Access to your account is mainly by ssh to

Your account is managed by manipulating its gitolite-admin repository. (See "first steps" below.) When you push this repository to the server, your account is reconfigured; you should pay close attention to any errors.

You are responsible for determining who has access to the account, by managing the ssh keys in the gitolite-admin keydir, and you are responsible for determining who has access to which repositories by editing the conf/gitolite.conf file.

Who is an account admin is determined by who has write access to the gitolite-admin repository. You can change this.

You are also the first line of support for your account's users. If you need advice please contact You should also subscribe to the cs-git-users mailing list to receive announcements about the service.

For full details of what you can put in your gitolite.conf file, see the gitolite documentation. You can also read a copy of the git manual on this server.

The rest of this page describes some gitolite basics, and the peculiarities of our installation. Features which do not require access to gitolite.conf are described in the documentation for non-admin users.

First steps

Once your account has been created, you should clone its gitolite-admin repository and have a look inside. (In this example, spqr2 is a place-holder for your user name.)

   $ git clone
   Cloning into 'gitolite-admin'...
   $ cd gitolite-admin
   $ ls -l conf keydir
   total 2
   -rw-r--r--  1 spqr2  spqr2  77  Jul  1 12:34 gitolite.conf
   total 2
   -rw-r--r--  1 spqr2  spqr2  391 Jul  1 12:34
   $ cd conf
   $ cat gitolite.conf
   repo gitolite-admin
       RW+     =   spqr2

   repo testing
       RW+     =   @all

In addition to ssh key files and gitolite.conf there are a couple of extra files that you can add in the top level of your gitolite-admin repository:

  • account-name
    • This contains the full name of your account, as listed on the git server home page. If this file is missing, your account will not be listed, so you should create it straight away.
  • index.html
    • This file contains an HTML fragment which is included in your account's repository listing pages, and

After creating an account-name file, we suggest you make the following basic changes to gitolite.conf:

  • Enable deny-rules on all repositories to make it easier to exclude public access.
  • Allow your users to read your gitolite-admin repository, so that they can find out more about access permissions without bothering you.
  • Enable "wild" repositories so your users can create and delete personal repositories without bothering you.

Your gitolite.conf will then look like this:

   repo @all
        option deny-rules = 1

   repo gitolite-admin
        R       = @ssh
        RW+     = spqr2

   repo u/CREATOR/..*
        C       = @ssh
        RW+     = CREATOR
        RW+     = OWNERS
        -       = DENY
        R       = R
        RW      = RW
        RW+     = RW+

   repo testing
        RW+     = @all

User management

The gitolite-admin keydir contains ssh public key files, named like If a user has multiple keys it is normal to put each key in a separate file, using the naming schemes described in the Gitolite documentation.

Alternatively, you can put multiple keys into a file (OpenSSH authorized_keys style). When you push your gitolite-admin repo, multiline key files will be automatically split into one file per key, named like,, etc.

Special users

There are two user names that have special meaning to gitolite:

  • gitweb
    • Any repository readable by gitweb is publicly accessible via URLs starting for browsing with gitweb and for cloning with git.
  • daemon
    • Any repository readable by daemon is publicly accessible via URLs starting git:// for cloning with git.

Special groups

In gitolite, groups refer to collections of users or repositories. There are three built-in groups which are pre-populated by gitolite:

  • @all
    • All users or repositories.
    • Note: @all includes the special users daemon and gitweb which grant public anonymous access as described above.
    • Note: @all includes all Raven-authenticated users, allowing them to view repositories in their browsers via URLs starting
  • @public
    • Just the gitweb and daemon users.
    • This makes it easier to keep the two forms of public access in sync.
    • Note: @public does not include Raven-authenticated users, so granting R access to just @public means the repository will not appear under
    • You usually want to grant access to @all rather than @public. The @public group can be useful in deny rules.
  • @ssh
    • All users with ssh keys in your account.

There is one group which has a special meaning but whose members are set by you:

  • @users
    • All users who you allow to access your account.
    • Users in this list will be able to upload their ssh keys via the web self-service key enrolment interface, without bothering you.
    • Note: this feature is not yet available. It is mentioned here to reserve it for future use.

Lookup groups and institutions

You can also tell gitolite to fetch lists of users from Lookup. There are two syntactic sugar functions, corresponding to Lookup groups and to institutions. These functions are expanded into lists of users when you update your gitolite configuration: gitolite does not check Lookup on every access.

Warning: Lookup groups must allow read access to anonymous users for the git service to be able to see them.

  • @lookup_group(uis-members)
  • @lookup_group(101611)
  • @lookup_inst(UIS)

Note: The @lookup_ syntactic sugar does not directly make a real gitolite group, so it cannot be used in the perms command. Instead, you can define a gitolite group like this:

    @uis = @lookup_inst(UIS)

Listing groups

You can use the list-memberships command to check that a user is a member of the groups that you expect, like this:

 $ ssh list-memberships -u user

(Due to a bug, this command is not listed in the help output.)

Local users

You should name key files based on the user's CRSID, for example, This is so that Lookup groups and Raven authentication work correctly. Raven is used for gitweb browsing to private repositories via URLs starting

Robot users

You may want to allow read access so a repository can be checked out by a particular machine or cluster, using an ssh key generated for this purpose rather than a user key. To avoid name clashes, you can name the key files like, for example, The host name should contain at least one dot, to avoid confusing gitolite.

External users

You can provide access to external collaborators. You can name their key files like, for example,

Self-service key management

We provide the sskm command so that users can manage their own ssh keys without bothering you.

Self-service key management has a couple of important consequences:

  • It manipulates the gitolite-admin repository behind your back, so before pushing any changes you have made, you need to pull any changes from the server to ensure your copy of the repository is up to date.
  • It uses "old style" multi-key file names, where multiple keys for a user are named like Key tags have no dots, whereas email-address usernames do have dots.

Key format conversion

There are a number of different ssh public key file formats. For instance, PuTTYgen's "save public key" feature writes files in standard RFC 4716 multi-line public key format. However gitolite requires the single-line OpenSSH public key format.

If you need to convert a key before adding it to your gitolite-admin keydir, you can use the command

 $ ssh-keygen -i -f crsid.pem >

Wild repositories for groups

Our recommended basic setup includes per-user wild repository areas, so that your users can manage their personal repositories without bothering you.

It is often useful to set up a wild repository area for a group, so the group members can manage their part of your account without bothering you. The following example shows how to configure this.

    # either using a list of people
    @wombles = abc123 pqr456 xyz789
    # or using a Lookup group
    @wombles = @lookup_group(uis-wombles)

    repo wombles/..*
        C       = @wombles
        RW+     = CREATOR
        RW+     = OWNERS
        -       = DENY
        R       = R
        RW      = RW
        RW+     = RW+


Gitolite's macros can help to reduce repetition. There is some terse documentation in the macro implementation source code.

In the UIS we have lots of wild group directories, so we configure them using a macro. For example,

    macro wild repo %1/..*
        C       = %2
        RW+     = CREATOR
        RW+     = OWNERS
        -       = DENY
        R       = R
        RW      = RW
        RW+     = RW+

    wild wombles @wombles

Wild repository access control

Access to a wild repo can be configured by the repository's owner using the perms command. This command works in terms of roles, not directly in terms of permissions, but you can use role names that are the same as the corresponding permission strings, as in the example above.

When setting up wild repos in your gitolite.conf, you determine which roles correspond to which permissions, then your users specify these roles to the perms command.

There is a fixed set of role names that you can use, in addition to the roles that match permission strings. (Except that a bare "-" is not a valid role name; use "DENY" instead.) These role names are chosen to be suggestive but they do not have any particular built-in meaning.

  • DENY

The first two roles are special. The CREATOR is fixed when a repository is created. The CREATOR can use the D command to delete repositories. The CREATOR can nominate other users as OWNERS, who are also able to change access permissions with the perms command.

Access control debugging

On a wild repository, you can find out which users and groups are in which access roles with the perms command:

    $ ssh perms repo -l

For non-wild repos and other more tricky cases, you can use the access command to find out how your gitolite.conf translates into an allow/deny decision:

    $ ssh access -s repo user

config settings

The user documentation lists the git config variables that you can set, to configure gitweb and git push hooks. Your users can set config variables on wild repos with the config command, and for managed repos you can set the variables in your gitolite.conf.

Gitweb has git config variables to set the owner, category, and description fields on the repository listing and summary web pages. The syntax is (for example):

   repo git/git
	config gitweb.description = Local mirror of git

And you can set up README files for gitweb using the readme hook config variables. For example,

   repo wombat
	config hooks.readme-file =

To configure push notification email with multimail, you can add settings like:

   config multimailhook.mailinglist =
   config multimailhook.commitlist = none
   config multimailhook.refchangeshowlog = true
   config multimailhook.logopts = --decorate --patch

The following sections describe the more advanced config variable settings.

Remote post-receive hooks

Although there is no way for you to run arbitrary programs on the git server, it is possible to trigger an action on another machine under your control when someone pushes an update to a repository on the git server. There are two options:

post-receive HTTP GET hook

The most simple option is to trigger an HTTP GET request.

Set the config hooks.remote-http-get variable to an http: or https: URL. When the repository is updated, the git server will GET the URL. The web server's response is sent to the client that ran git push.

The git server does not send any details of the push to the web server.

post-receive ssh hook

For similar functionality to a local post-receive hook, you can set up a hook to be run via ssh.

Set the config hooks.remoteuser variable to a string of the form username@hostname. When the repository is updated, the git server will use ssh to log in to the account you specified and run the command:

git-post-receive-remote acct repo

Your git-post-receive-remote command gets the same standard input as a normal git post-receive hook.

You must add the following ssh public key to the target account's authorized_keys file. We recommend you use the "command" option to fix what command is run, to prevent the git server from running arbitrary commands on your server. For details, see the "AUTHORIZED_KEYS FILE FORMAT" section of the sshd manual. (This key is also used for fetching from upstream repositories over ssh.)

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwxKVt7g3SJ2csMUs+b60vOLQ0D56r/CHhXmTZsJggMdQuT949wzpw/J6WhUGxuE4p4SeBgj8excOo5BYeQpDIWVM3Ky1gj0S5PlXz+Vv4u2yZeBf/1w2VmHgfo4cYXpM3pJVhV9yW6wyu5bLYavsNLxGWZzSDi8JStYFkm+gI2nQ7HfQOMP9MnvVIU1Bla9nVkL/ad6sIW7QTeCedvoVoDHcJhzGensmHrzrQftZVv9W93JqDDyIg+3D7AVeQ+kVSuRdCHJY2L7KhYZV8r8jX1nJtiadmBNF8eMpmjA6ksPM4CJkIs3PrHv4hDv2JD4KLAnEAggWvFj1m1AGhIJr7 gitmaster@git

Partial copies for limited read access

Gitolite allows quite flexible control over who can modify which branches and tags in managed repositories. However, because of the way git works, gitolite can only grant or deny read access to an entire repository.

If you want to grant read access to a subset of the branches in a repository, the solution is to make a second repository containing copies of only these branches. This is tiresome to do manually; fortunately it can be automated. There are two git config variables which control the partial-copy feature:

  • hooks.partial-copy-to
    • the name of the target repo that will be a partial copy of this repo
  • hooks.partial-copy-reader
    • the name of a representative user who should have limited read access
    • (defaults to gitweb)

For example, say you have a repository configured as follows:

    repo pc-private
	-      private/              = @public
	RW+                          = @ssh
	R                            = @all

This says that anonymous users (@public) should be denied access to branches whose names start private/. Users with ssh access should have unrestricted read/write access. And everyone should have read access to the everything unless they have been denied.

So we're trying to prevent anonymous users from accessing private branches, but this does not work. With deny-rules=1, anonymous users can't read anything, and with deny-rules=0 they can read everything. (Read access is controlled by gitolite's access check #1.)

To set up an automatically-maintained partial copy, create a second repo which will allow read access to the relevant users, and add a config setting on the private repo. The result will look like the following (assuming you have set deny-rules=1 on all repos as we recommend):

    repo pc-private
	-      private/              = @public
	RW+                          = @ssh
	R                            = @all
        config hooks.partial-copy-to = pc-public

    repo pc-public
	R                            = @all

When you push to a branch in the main repo pc-private, to which gitweb has read access (according to gitolite's access check #2) the commits will be copied to pc-public and you will see a message like:

remote: To /home/acct/repositories/pc-public.git
remote:    9607381..6b24c57  master -> master
   9607381..6b24c57  master -> master

It is unwise to allow pushes to a partial-copy target, since they will be overwritten when the main (private) repo is changed.

Local copies of upstream repositories

If you are maintaining patches against some third party codebase, it can be useful to have an automatically-maintained local copy of the upstream repository. For example, we keep a local copy of git with the following configuration:

   repo git/git
	desc                   = Local mirror of git
	RW+     u/             = @ssh
	R                      = @all
	option  upstream.url   = git://
	option  upstream.nice  = 60

(Note, these are gitolite options not git config variables.)

When I fetch from the local repository, gitolite automatically fetches any changes from upstream.url into its copy of the repository, before sending the updates to me. To avoid wasteful re-fetching, gitolite will not fetch more than once every upstream.nice minutes.

Any local refs that match upstream refs are overwritten whenever gitolite fetches from upstream. So to avoid lossage, I have configured the repository access controls to be "R", read only, except for branch heads in a local u/ namespace.

You can also fetch from an upstream repository over ssh, which is useful for private repositories on GitHub, for example. You need to grant access to the following SSH public key. (This is the same key that is used for the post-receive ssh hook.)

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwxKVt7g3SJ2csMUs+b60vOLQ0D56r/CHhXmTZsJggMdQuT949wzpw/J6WhUGxuE4p4SeBgj8excOo5BYeQpDIWVM3Ky1gj0S5PlXz+Vv4u2yZeBf/1w2VmHgfo4cYXpM3pJVhV9yW6wyu5bLYavsNLxGWZzSDi8JStYFkm+gI2nQ7HfQOMP9MnvVIU1Bla9nVkL/ad6sIW7QTeCedvoVoDHcJhzGensmHrzrQftZVv9W93JqDDyIg+3D7AVeQ+kVSuRdCHJY2L7KhYZV8r8jX1nJtiadmBNF8eMpmjA6ksPM4CJkIs3PrHv4hDv2JD4KLAnEAggWvFj1m1AGhIJr7 gitmaster@git

Keeping things tidy

The list-dangling-repos command is useful for finding repositories that exist on disk but do not have access permissions specified in the gitolite.conf file. You can restore access to a dangling repo by putting an entry for it in your gitolite.conf.

The rename command is special because account admins can use it to rename any repository, not just wild repos. You need to rename a repository before you change gitolite.conf to match.

If it is necessary to delete a non-wild repository, you can turn it into a wild repo with the rename -c command, after which you can use the D command to delete it.


The gitolite documentation generally assumes that the account admin has shell access to the server, but that is not the case for this service. Because of this restriction:

  • You cannot edit any gitolite.rc configuration.
  • You cannot install any custom hooks or triggers.

If you would like us to install a hook, or change gitolite.rc, please ask To keep complexity under control, all accounts share the same gitolite.rc, so any changes neeed to be appropriate for everyone. Similarly, hook scripts are installed in every repository, so they need to be enabled and configured using git config settings.