From ArchWiki
Revision as of 14:34, 22 July 2010 by Eregon (Talk | contribs) (Add a note about the fact the permissions must exactly match, else it will not work)

Jump to: navigation, search

Tango-edit-clear.pngThis article or section needs language, wiki syntax or style improvements.Tango-edit-clear.png

Reason: please use the first argument of the template to provide a brief explanation. (Discuss in Talk:Gitosis#)
Template:I18n links start

Template:I18n entry Template:I18n entry Template:I18n links end

gitosis is simply an access control list for git, the (famous) stupid content tracker. Once you have a git repository, there are many ways to setup how people will access it. You might prefer publishing your repository with read-only access via the git:// protocol. But when it comes to pushing to the repository, it's essential to decide by whom and how the repository will be accessed. Generally, you wouldn't prefer letting everyone pushing changes and hopefully ruin your repository. Therefore you need some kinds of authorization methods such as:

  • SSH Authentication
  • HTTP Authentication (webdav)
  • gitosis (using SSH)

The rest of this document is about the third method. (Afterall, the title says it all.)

What does gitosis do?

With gitosis, you have the ability to pull from and push to the repository with just one system account. You don't need to create SSH accounts for each user who will have write access to the repository. Once you install the package (see below), there will be system user created on your system called gitosis with a home directory in /srv. Users that will access to the repositories will be using gitosis user for every transaction.


Install gitosis-git from the AUR.

Once installed, you'll be able to find some example config files in /usr/share/doc/gitosis.

Initiating gitosis-admin repository

You will need a public SSH key to continue. If you don't have one, you may generate one on your local computer:

$ ssh-keygen -t rsa

In order to make gitosis work, you should first create a SSH key pair (or use the existing one) and use the public key to create the gitosis-admin repository installed within gitosis home directory (/srv/gitosis).

$ sudo -H -u git gitosis-init < /path/to/
Initialized empty Git repository in /srv/gitosis/repositories/gitosis-admin.git/
Reinitialized existing Git repository in /srv/gitosis/repositories/gitosis-admin.git/

You should also place the public key you used above as .ssh/authorized_keys inside gitosis' home directory. The above command will create two directories:

  • gitosis
  • repositories

The directory gitosis includes a single file (projects.list) in which some information about the repositories are defined. The repositories directory contains all repositories including the gitosis-admin repository.

gitosis-admin repository

gitosis-admin is simply a git repository, that stores the permissions per repository and the keys of users who have access to them. To change the settings of gitosis, add/remote repositories or users, you'll need to clone the repository to some local directory and do the changes like you would do to a normal git repository. After you're done with the files, you'll have to commit the changes and push them to the remote repository you initially cloned from.

$ git clone git@host:gitosis-admin.git

For this command to work,

  • the home directory (/srv/gitosis/) => 700
  • the .ssh directory (/srv/gitosis/.ssh/) => 700
  • the authorized_keys file (/srv/gitosis/.ssh/authorized_keys) => 600

should have the correct permissions. (These permissions must exactly match, greater permissions will not work !)

Once you clone the repository, you'll be able to edit the following:

  • gitosis.conf
  • keydir

configuration of the repositories


gitweb = yes

[repo foobar]
description = git repository for foobar
owner = user

[group devs]
members = user1 user2

[group admins]
members = user1

[group gitosis-admin]
writable = gitosis-admin
members = @admins

[group foobar]
writable = foobar
members = @devs

[group myteam]
writable = free_monkey
members = jdoe

This defines a new group called "free_monkey", which is an arbitrary string. "jdoe" is a member of myteam and will have write access to the "gitosis" repo.

Save this addition to gitosis.conf, commit and push it:

$ git commit -a -m "Allow jdoe write access to free_monkey"
$ git push

Now the user "jdoe" has access to write to the repo named "free_monkey", but we still haven't created a repo yet. What we will do is create a new repo locally, and then push it:

$ mkdir free_monkey
$ cd free_monkey
$ git init
$ git remote add origin git@YOUR_SERVER_HOSTNAME:free_monkey.git

Do some work, git add and commit files

$ git push origin master:refs/heads/master

With the final push, you're off to the races. The repository "free_monkey" has been created on the server (in /srv/gitosis/repositories) and you're ready to start using it like any ol' git repo.

gitosis repositories can also be used with gitweb; just point the directory that contains the repository inside the gitweb configuration.

Adding users

The next natural thing to do is to grant some lucky few commit access to the FreeMonkey project. This is a simple two step process.

First, gather their public SSH keys, which I'll call "" and "", and drop them into keydir/ of your local gitosis-admin repository. Second, edit gitosis.conf and add them to the "members" list.

$ cd gitosis-admin
$ cp ~/ keydir/
$ cp ~/ keydir/
$ git add keydir/ keydir/

Note that the key filename must have a ".pub" extension.

gitosis.conf changes:

[group myteam]
members = jdoe alice bob
writable = free_monkey

Commit and push:

$ git commit -a -m "Granted Alice and Bob commit rights to FreeMonkey"
$ git push

That's it. Alice and Bob can now clone the free_monkey repository like so:

$ git clone git@YOUR_SERVER_HOSTNAME:free_monkey.git

Alice and Bob will also have commit rights.

Public access

If you are running a public project, you will have your users with commit rights, and then you'll have everyone else. How do we give everyone else read-only access without fiddling w/ SSH keys?

We just use git-daemon. This is independent of gitosis and it comes with git itself.

$ sudo -u git git-daemon --base-path=/srv/gitosis/repositories/ --export-all

This will make all the repositories you manage with gitosis read-only for the public. Someone can then clone FreeMonkey like so:

$ git clone git://YOUR_SERVER_HOSTNAME/free_monkey.git

To export only some repositories and not others, you need to touch git-daemon-export-ok inside the root directory (e.g. /srv/gitosis/repositories/free_monkey.git) of each repo that you want public. Then remove "--export-all" from the git-daemon command above.

More tricks

gitosis.conf can be set to do some other neat tricks. Open example.conf in the gitosis source directory (where you originally cloned gitosis way at the top) to see a summary of all options. You can specify some repos to be read-only (opposite of writable), but yet not public. A group members list can include another group. And a few other tricks that I'll leave it to the reader to discover. Caveats

If /srv/gitosis/.gitosis.conf on your server never seems to get updated to match your local copy (they should match), even though you are making changes and pushing, it could be that your post-update hook isn't executable. Older versions of setuptools can cause this. Be sure to fix that:

$ sudo chmod 755 /srv/gitosis/repositories/gitosis-admin.git/hooks/post-update

If your Python goodies are in a non-standard location, you must additionally edit post-update and put an "export PYTHONPATH=..." line at the top. Failure to do so will give you a Python stack trace the first time you try to push changes within gitosis-admin.

If you want to install gitosis in a non-standard location, I don't recommend it. It's an edge case that the author hasn't run up against until I bugged him to help me get it working.

For the brave, you need to edit whatever file on your system controls the default PATH for a non-login, non-interactive shell. On Ubuntu this is /etc/environment. Add the path to gitosis-serve to the PATH line. Also insert a line for PYTHONPATH and set it to your non-standard Python site-packages directory. As an example, this is my /etc/environment:

$ PATH="/home/$(whoami)/sys/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games"
$ PYTHONPATH=/home/$(whoami)/sys/lib/python2.4/site-packages

Be sure to logout and log back in after you make these changes.

Don't use the gitosis-init line I have above for the standard install, instead use this slightly modified one:

$ sudo -H -u git env PATH=$PATH gitosis-init < /tmp/

Be sure to also set PYTHONPATH in your post-update hook as described above.

The *should* do it. I am purposefully terse with this non-standard setup as I think not many people will use it. HIt me up in #git on FreeNode if you need more info (my nick is up_the_irons).

Non-standard SSH port

If you run SSH on a non-standard port on your server, don't use the syntax "", it won't work. Putting the port in the URL doesn't seem to make gitosis, or git, (not sure which) happy. Instead, put this in your ~/.ssh/config file:

$ Host
$ Port 1234
  • [repo] blocks are used to define some necessary areas being used with gitweb.
  • [group] blocks are used for both:
    • defining user groups
    • defining repository permissions
  • @ is used to define user groups.

You should commit and push any changes you do in this file.


keydir is simply a directory that contains public keys of the users. Some of the keys can be in the form of user@machine and those keys must be defined with that form inside gitosis.conf. It's better to create user groups and use them as members of the repositories. Once you add new keys to enable some new users, you should add the files to the git repository and commit & push them. The new users will use the above form of git commands like you've used to clone the gitosis-admin repository.