namespace support in gitolite

This feature is only available in the 'namespaces' branch until enough people test it and tell me it works fine.

AVOID NASTY SURPRISES! Please read the entire page before attempting to use or install this. Most non-core features of gitolite do not work with namespaces, and, worse, many of them will fail silently. There are also security issues you need to be aware of.


In many projects, developers need to push their work to some central place for others to fetch. Namespaces allow you to give each developer what looks like her own repo or set of repos, while combining all these logical repos into one physical repo on the server. This saves a lot of disk space if they all share a lot of common history.

The logical repos look like normal repos to a git client; all the magic is on the server side. (But see the "WARNINGS" section).


There is one repo that is special, and several others that depend upon it or use it. Depending on context, we use one of the following names:

In addition, in the gitolite context you could say that the blessed repo is a normal (not "wild") repo and the logical repos are wild repos, since that is the most convenient way to set this up. However, it is not mandatory -- you can have a wild repo as a backing repo, and/or a normal repo as a logical repo if you wish.


First, add the following lines to the rc file, as indicated:

# add this line as the *last* item in the PRE_GIT trigger list.  In
# particular, it should be *after* the Mirroring::pre_git line if you're
# using mirroring.

# add this line as the *first* item in the POST_GIT trigger list.  In
# particular, it should be *before* the Mirroring::post_git line if you're
# using mirroring.

Then use the following example conf below as a guide and roll your own. This example is from a mail to the gitolite list by Javier Domingo ("Mirroring forks", 13-11-2012), modified slightly.

# backing repos, normal (non-wild), serving as blessed repos
repo    linux git gitolite [...other projects...]
    RW+     =   integration-manager
    R       =   @all

# logical repos, wild, created by devs as needed
repo    CREATOR/[a-zA-Z0-9].*
    C       =   @all
    RW+     =   CREATOR
    R       =   READERS @all
    option namespace.pattern = %/* is @1 in @2


A developer doesn't have to do anything differently. She will still run, e.g., git clone git@host:alice/linux to auto-create and clone a wild repo for herself, then add a remote to the "backing" repo, fetch it, start working, and eventually push her work to alice/linux.

However, she might notice some differences. To begin with, her first push of an enormous code base, to what she thought was an empty repo on the server, might go surprisingly fast :)

Secondly, a lot of gitolite commands (and other features) won't work. See the "WARNINGS" section below for more.


The option line above has 3 parts separated by the words "is" and "in":

<pattern> is <namespace> in <backing repo>

When a user attempts to access a logical repo (say "alice/linux"), the namespace pattern for that repo is applied to the repo name as follows:

Once the matching is done, each "at-digit" combination is replaced by the corresponding matched segment to derive the namespace and the backing repo name.

Some examples may help:



First and most important, please read 'man gitnamespaces' for important security information about namespaces.

Secondly, please note that gitolite's access control decisions are made based on the repo name that the user supplies, even if that is only a logical repo. E.g., in a sequence like this:

git clone git@server:alice/linux                        # 1
cd alice
git remote add backing git@server:linux
git fetch backing                                       # 2
git checkout master
git push origin master                                  # 3

Lines 1 and 3 use the access list for the logical repo ("alice/linux") to allow or reject a push, while line 2, which is directly contacting the "backing" repo, use that repo's access rules.

In particular, Alice does not need write access to the backing repo for the push to succeed!

gitolite functionality

Most things you're used to in gitolite won't work with logical repos. From the client point of view, the only features guaranteed to work on logical repos are:

From a server/admin point of view, the following will not work for logical repos, and may even fail silently!:

gitolite functionality -- mirroring

Mirroring works, but all the logical repos and the backing repo should have the same mirroring setup. I.e., which server is the master, who are the slaves, are redirects allowed, if so from where, etc., etc., etc., should all have the same values for all of them. I cannot over-emphasise the importance of this for proper mirroring.

other notes

The "backing repo" needs to exist. If it is itself a wild repo, it must be auto-created before a logical repo that hangs off of it is accessed.

The logical repo must also be mentioned in the gitolite.conf file in some way, as you saw in the example. Access control decisions are made based on this one, not the backing repo.

One quirk is that, if the logical repo is a wild repo, then an actual repo with that name is created on disk. Gitolite needs a place to keep its repo-specific permissions so it has to do that. You will find, however, that the objects directory is pretty much empty, even after a lot of activity.