20 August 2009

Share a git repository with unix groups

If you have a shared Linux/Unix box that all your developers use to share code with git, there are various ways of setting up the shared repository. If you just use git over ssh, you don't need to maintain any more servers.

The simplest possible solutions assume that there is a single user account and different developers are authenticated on the server with their ssh public keys. I needed to restrict which developers get access to different repositories, and to be able to switch these permissions on and off. Unix has already solved this problem of course, with users and groups. Here is how to use real users and groups on your unix server to control git access.

  1. Set up unix accounts for your users. "adduser jim"
  2. Set up groups for each project, "addgroup wonderproject-developers"
  3. Add the appropriate developers to the group "adduser jim wonderproject-developers"
  4. In a private directory on your server, logged in as yourself, make a directory for the git repository "mkdir wonderproject.git"
  5. Make the new group the group owner of the git repository "chgrp wonderproject-developers wonderproject.git/"
  6. Fix the perms so only the group and the owner can read and write the repository "chmod 770 wonderproject.git/"
  7. Make the repository setgid, so that any new files created inside it have group ownership the same as the directory "chmod g+s wonderproject.git"
  8. cd wonderproject.git
  9. create the git repository "git --bare init --shared=group" the --shared option ensures that git keeps the correct permissions when the various developers push commits into the repository.
  10. Now, if your project is empty, clone this new repository onto your desktop and start committing "git clone ssh://jim@git.example.com:port/path/to/repos/wonderproject.git
  11. If you have an existing repository on your desktop and you want to push it into the empty shared repository, edit your .git/config remote url to point at the new server url and then do a "git push --all"