Setting Up an Access Controlled Git Repository Server with Gitolite

March 5th, 2011 Permalink

For any given coding project that involves more than just one person, the odds are fairly good that some control over who can do what with the codebase is needed. That in turn implies that there is some central repository or repositories containing that codebase, and that a system of rights and permissions is used to manage access. Even in the more free-wheeling side of the open source development arena, a project and its participants will tend to coalesce around a reference repository.

Thus even if you are using git for version control, in which every participant has a local copy of the repository, the mechanics of organization still declare that you'll need some central server and management of rights to read and commit code. Such is the way the world works. From a practical standpoint, your options for a central point of control for a bunch of collaborating git users are either to use something like Github or set up a server running git and the access control layer of gitolite.

Gitolite is an access control layer on top of git, which allows access control down to the branch level, including specifying who can and cannot rewind a given branch. ... Gitolite lets you use a single user on a server to host many git repositories and provide access [via ssh] to many developers, without having to give them real userids on or shell access to the server.

I don't know about you, but it's important to me that I can set up a securely accessed repository on one of my servers and have multiple participating developers come and go without having to manage local accounts on the server. Thus the rest of this post is an overview of how to set up git and gitolite for a development project on a fresh Linux server: in this case a bare bones Fedora Core 14 server launched on Amazon Web Services with an Elastic Block Store boot volume from AMI ami-225aac4b.

(At the very end of this post are some notes on using an Ubuntu instance instead - you have to do a little more work, but it's basically the same).

On this AMI, you log in as "ec2-user" and then sudo su to root. Once there, you'll want to get started by installing git and gitolite. As of the time of writing the package versions are as shown below:

[root]# yum install git gitolite
[root]# yum list installed git*
git.i686		1.7.4-1.fc14
gitolite.noarch		1.5.3-2.fc14

This will create the gitolite user and folder for repositories /var/lib/gitolite - but the remainder of the setup process is manual. You need a second user with an RSA key pair, and for that public key to be available to the gitolite user.

[root]# useradd -d /home/gitolite-admin -m gitolite-admin
[root]# su - gitolite-admin
[gitolite-admin]# ssh-keygen
[gitolite-admin]# exit

Choose a good password for the RSA key pair. Generate it in the default location of /home/gitolite-admin/.ssh and with the default filenames of id_rsa and id_rsa.pub. Then, as root, copy this key to a place where it can be read by the gitolite user:

[root]# cp /home/gitolite-admin/.ssh/id_rsa.pub /var/lib/gitolite/id_rsa_gitolite_admin.pub
[root]# chown gitolite:gitolite /var/lib/gitolite/id_rsa_gitolite_admin.pub

If you examine the gitolite install documentation, this is a case where the "client" and the "server" role are filled by the same machine - this server. The gitolite-admin user plays the part of the client as it is described in the documentation, while the gitolite user is on the server side. To complete the setup, run the following commands:

[root]# su - gitolite
[gitolite]# gl-setup /var/lib/gitolite/id_rsa_gitolite_admin.pub
[gitolite]# exit
[root]# su - gitolite-admin
[gitolite-admin]# git clone gitolite@localhost:gitolite-admin

This back and forth of similarly named users and repositories might be a little opaque at first glance. What is happening here is that the gitolite-admin user is cloning the main gitolite-admin repository into its home directory. You will configure the operation of gitolite - adding and removing users and changing configuration directives - as follows:

  • Change the contents of the gitolite-admin repository.
  • Commit the revisions.
  • Push the revisions out.

Which is somewhat ingeniously recursive: using git to control the operation of the system that controls access to git. Hopefully by this point it becomes more clear that this could be set up as a client-server system, with the gitolite-admin repository cloned out onto a client machine - such as the lead developer's workstation. For my part, I prefer to keep it all on one server.

You will need to set the gitolite-admin user's basic git configuration before git will allow you to commit staged changes:

[gitolite-admin]# git config --global user.email "gitolite-admin@localhost"
[gitolite-admin]# git config --global user.name "gitolite-admin"

If you're not a big fan of vi, then you may also want to change the editor setting - perhaps to nano. This editor will automatically run when a commit is made:

[root]# yum install nano
[root]# su - gitolite-admin
[gitolite-admin]# git config --global core.editor "nano"

You can now add users and repositories as described in the gitolite administration guideby:

  • placing public keys into /home/gitolite-admin/gitolite-admin/keydir
  • altering the file /home/gitolite-admin/gitolite-admin/conf/gitolite.conf
  • and then committing those changes.

For example, you might add the new_username.pub public key file to /keydir, and then the following repository definition to gitolite.conf:

repo    my_new_repository
        RW+     =   new_username

Then commit and push those changes:

[gitolite-admin]# git add -A
[gitolite-admin]# git commit
[gitolite-admin]# git push

This will give anyone who connects over SSH using the private key counterpart to new_username.pub full read/write access to my_new_repository, and creates a bare repository in:

  • /var/lib/gitolite/my_new_repository.git

To connect this repository to work taking place on your local machine, you might clone out my_new_repository and then start working in the local copy:

git clone gitolite@mydomain.com:my_new_repository.git

Alternately, you may have a preexisting git repository that is already well advanced and full of the fruits of your labor. In this case you can link that local respository to the remote my_new_repository and push out your local repository contents to populate it:

git remote add mydomain.com gitolite@mydomain.com:my_new_repository.git
git push --all
git push --tags

Notice that in these examples you are connecting over SSH as the user "gitolite", but you will be using the private key for new_username. All gitolite connections from developers come in through the gitolite user, but every developer will have their own private key and corresponding entries in the /conf/gitolite.conf file.

Differences if Using Ubuntu

Setting up on Ubuntu requires just a little extra work. The installation of packages is as follows:

[root]# apt-get install git gitolite

You must create the gitolite user and the repository location yourself in this case:

[root]# useradd -d /var/lib/gitolite -m gitolite

After this the setup should all run in exactly the same way.