# 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 ---- ### why 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) * the most requested feature (see "what's extra?") 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 * 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 extra? 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. 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). This includes not just who can push to what branch, but also whether they are allowed to rewind it or not (non-ff push). 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. Nothing prevents you from version-controlling that directory if you wish to, but it's not *required* * 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!) Advantages: all the complexity of parsing and error checking the parse is done away from the two places where the actual access control happens, 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 :-)