Skip to content
Hosting git repositories -- Gitolite allows you to setup git hosting on a central server, with very fine-grained access control and many (many!) more powerful features.
Perl Shell
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



[IMPORTANT: There is now an "upgrade" document in the "doc" directory; please read if upgrading gitolite]

Gitolite is the bare essentials of gitosis, with a completely different config file that allows (at last!) access control down to the branch level, including specifying who can and cannot rewind a given branch. It is released under GPL v2. See COPYING for details.

In this document:

  • why
  • what's gone
  • what's new
  • the workflow


I have been using gitosis for a while, and have learnt a lot from it. But in a typical $DAYJOB setting, there are some issues:

  • it's not always Linux; you can't just "urpmi gitosis" (or yum or apt-get) and be done
  • often, "python-setuptools" isn't installed (and on a Solaris9 I was trying to help remotely, we never did manage to install it eventually)
  • or you don't have root access, or the ability to add users
  • the most requested feature (see "what's new?") had to be written anyway

what's gone

While I was pondering the need to finally learn python[1] , I also realised that:

  • no one in $DAYJOB type environments will use or approve access methods that work without any authentication, so I didn't need gitweb/daemon support in the tool or in the config file.

    Update 2009-09-24: I don't use this feature but someone wanted it, so I added it... see the "faq, tips, etc" document for more

  • the idea that you admin it by pushing to a special repo is nice, but not really necessary because of how rarely these changes are made, especially considering how much code is involved in that piece

All of this pointed to a rewrite. In perl, naturally :-)

what's new

Per-branch permissions. You will not believe how often I am asked this at $DAYJOB. This is almost the single reason I started thinking about rolling my own gitosis in the first place.

It's not just "read-only" versus "read-write". Rewinding a branch (aka "non fast forward push") is potentially dangerous, but sometimes needed. So is deleting a branch (which is really just an extreme form of rewind). I needed something in between allowing anyone to do it (the default) and disabling it completely (receive.denyNonFastForwards or receive.denyDeletes).

Take a look at the example config file in the repo to see how I do this. I copied the basic idea from update-hook-example.txt (it's one of the "howto"s that come with the git source tree). However, please note the difference in the size and complexity of the operational code between the update hook in that example, and in mine :-) The reason is in the next section.

the workflow

In order to get per-branch access, you must use an update hook. However, that only gets invoked on a push; "read" access still has to be controlled right at the beginning, before git even enters the scene (just the way gitosis currently works).

So: either split the access control into two config files, or have two completely different programs both parse the same one and pick what they want. Crap... I definitely don't want the hook doing any parsing, (and it would be nice if the auth-control program didn't have to either).

So I changed the workflow completely:

  • all admin changes happen on the server, in a special directory that contains the config and the users' pubkeys. But there's no commit and push afterward
  • instead, after making changes, you "compile" the configuration. This refreshes ~/.ssh/authorized_keys, as well as puts a parsed form of the access list in a file for the other two pieces to use.

The pre-parsed form is basically a huge perl variable. It's human readable too (never mind what the python guys say!)

So the admin knows immediately if the config file had any problems, which is good. Also, the relatively complex parse code is not part of the actual access control points, which are:

  • the program that is run via ~/.ssh/authorized_keys (I call it gl-auth-command, equivalent to gitosis-serve); this decides whether git should even be allowed to run (basic R/W/no access)
  • the update-hook on each repo, which decides the per-branch permissions


[1] I hate whitespace to mean anything significant except for text; this is a personal opinion only, so pythonistas please back off :-)


Something went wrong with that request. Please try again.