gitano is not entirely unlike the
non-web, server side of github. It allows you to create and manage
users and their SSH keys, groups and repositories from the command
line. Repositories have ACLs associated with them. Those can be
complex (“allow user X to push to
master in the
doc/ subtree) or
trivial (“admin can do anything”). Gitano is written by Daniel
Silverstone, and I’d like to thank him both for writing it and for
holding my hand as I went stumbling through my initial gitano setup.
Getting started with Gitano can be a bit tricky, as it’s not yet packaged and fairly undocumented. Until it is packaged, it’s install from source time. You need luxio, lace, supple, clod, gall and gitano itself.
luxio needs a
make install LOCAL=1, the others will be installed
/usr/local with just
Once that is installed, create a user to hold the instance. I’ve
git, but you’re free to name it whatever you would like.
As that user, run gitano-setup and answer the prompts. I’ll use
git.example.com as the host name and
john as the user I’m setting this
To create users, run
ssh firstname.lastname@example.org user add john email@example.com
John Doe, then add their SSH key with
ssh firstname.lastname@example.org as john
sshkey add workstation < /tmp/john_id_rsa.pub.
To create a repository, run
ssh email@example.com repo create
myrepo. Out of the box, this only allows the owner (typically
“admin”, unless overridden) to do anything with it. To change ACLs,
you’ll want to grab the
refs/gitano/admin branch. This lives
outside of the space git usually use for branches, so you can’t just
check it out. The easiest way to check it out is to use
git-admin-clone. Run it as
firstname.lastname@example.org:myrepo ~/myrepo-admin and then edit in
~/myrepo-admin. Use git to add, commit and push as normal from
To change ACLs for a given repo, you’ll want to edit the
rules/main.lace file. A real-world example can be found in the
NetSurf repository and the lace syntax
might be useful. A lace file consists of four types of lines:
- Comments, start with – or #
- defines, look like
define name conditions
- allows, look like
allow "reason" definition [definition…]
- denials, look like
deny "reason" definition [definition…]
Rules are processed one by one, from the top and terminate whenever a matching allow or deny is found.
Conditions can either be matches to an update, such as
refs/heads/master to match updates to the master branch. To create
groupings, you can use the
allof verbs in a definition.
Allows and denials are checked against all the definitions listed and
if all of them match, the appropriate action is taken.
Pay some attention to what conditions you group together, since a
basic operation (
before git is even involved and you don’t have a tree at that point,
so rules like:
define is_master ref refs/heads/master allow "Devs can push" op_is_basic is_master
simply won’t work. You’ll want to use a group and check on that for basic operations and then have a separate rule to restrict refs.