How to set up simple, out of the box git user management for multiple teams?

One of my latest projects was setting up the Git source code management system on a customer's server, so that different developers can have different access rights to repositories. How to do that?

For the really simple case of one set of repositories with r/w access to every developer in your organization, you can use a git server, with or without a dedicated user, with or without SSH keys [source]. For the complex case with even intra-repository rights management, there is Gitolite; or Gitosis, but that is no longer maintained [source]. But what is the simplest solution for the middle ground: multiple users, and giving each one access to a potentially different set of repositories?

Here's a solution for that – I haven't seen it documented anywhere, but I guess it's quite obvious. I simply extend the outta-the-box git server scenario by running multiple git servers in parallel, each for one (non-intersecting) set of repositories with one (potentially intersecting) set of developers who get r/w access. So for example, you can have a setup like this:

  • team 1
    • repositories: project 1, project 2
    • developers with access: Alice, Bob, Andrew
  • team 2
    • repositories: project 3
    • developers with access: Alice, Juan
  • team 3
    • repositories: project 4, project 5
    • developers with access: Juan

Setting up a team

For every team, you set up one dedicated user and git server on your host. You can have as many servers as you want, and adding one always follows this procedure. Let's assume we want to set up a team devteam1.

  1. Create a new user and set a password for it. Say you want to name the user devteam1, then execute: adduser devteam1.
  2. In /etc/passwd, change devteam1's shell to be /usr/bin/git-shell (or wherever it is on your host – see which git-shell). This prohibits SSH access with this user, but allows git commands.

Adding a developer to a team

Say you want add developer Alice to your team devteam1, which means giving her r/w access to all repositories of devteam1. The simplest solution is to hand out the password for system user devteam1 to the new developer. This requires however to enter it on every commit. (If you want to avoid this, the usual and widely documented method if to use SSH keys with git.)

Note that using one shared user account for writing to your remote repository does not mean that commits from all the developers will use the same author information. Instead, the password needed for git push just is for transferring your commits. Your commits have been made earlier, in your local git repository, using the author information configured in git.

You can determine git's author information by looking at user.name and user.email in git config --list (potentially overwritten in environment variables GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL [source]). You can configure this author information for your user in ~/.gitconfig on your local computer, and if needed override it in .git/config per repository, by adding a section like this there:

[user]
        name = Alice Example
        email = alice@example.com

Adding a repository to a team

Say you want to add repository project1 to team devteam1. On your server, do this:

  1. cd /home/devteam1
  2. mkdir project1.git
  3. cd project1.git
  4. git init --bare
  5. chmod -R u=rwX,g=rX,o= .
  6. chown -R devteam1:devteam1 .

Explanations:

  • git init --bare creates a "bare" repository, which means one that stores all the code in objects, but without having a working directory (the set of source files a developer will work with on her local computer). On your local computer, the git repository resides in a .git subdirectory, while a "bare" repository is created in the current directory, not within a .git one.
  • The chmod and chown commands make sure the devteam user is the one with write access to the repository; else, git push commands involving this repository (using devteam1@example.com:/home/devteam1/project1.git) would result in this error message: "error: insufficient permission for adding an object to repository database ./objects" [source]. They also make sure no other user has access, not even nread access.
  • Note that read and read/write access to git repositories on the server is controlled by the file permissions of this repository's files. So rights management is effectively just Unix system file rights management: Every Unix system user with read access to these files can be used in a git command to read (clone and pull) the repository. Every Unix system user with write access can be used in a git push command. So if you want to create a world-readable repository, make its files world-readable. If you don't want the simple "team -> repositories" hierarchy we use here, you can instead create a group with r/w access for every repository on the server, a system user per developer, and add that user to all groups of repositories that you want him / her to access r/w.

Working with your repositories

Say you want to access a repository project1 that belongs to devteam1, and your server is example.com:

  • Cloning the git repository to your local computer: git clone devteam1@example.com:/home/devteam1/project1.git. This creates a local directory project1. Go there and do your changes to your code.
  • Getting and merging changes from the repository: git pull.
  • Committing your changes to the repository: git add .; git commit -m "Commit message."; git push; You will be asked for the password of user devteam1 on the server.

Posted

in

,

by

Tags:

Comments

3 responses to “How to set up simple, out of the box git user management for multiple teams?”

  1. Sadish

    Dear Mr. Matt,
    Good day to you!!!
    I am Sadish working in a reputed software company in SG.
    I have a working ghost script printing A4 ps file correctly. But when I add duplex option, it is not getting printed double side.
    Kindly please assist sir.

    Working gs script.

    #!/usr/bin/sh
    PATH=$PATH:/usr/local/bin
    export PATH
    filename=`/usr/bin/basename $5`
    gs -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pswrite “-sOutputFile=/tmp/$filename.ps” -c save pop -c
    “<> setpagedevice” -f “$5” 2> /dev/null
    lp -o ps3 $1 $2 $3 $4 /tmp/$filename.ps
    sleep 3
    \rm /tmp/$filename.ps

    I want to add duplex option but not working..please assist.
    sadish.p@gmail.com
    65-91185449
    I have tried adding /duplex true before setPageDevice but still printing single sided only. Kindly assist.

  2. I have never tried duplex printing with Ghostscript. But I’d proceed like this: first print to duplex from a regular application’s print dialog; then capture the gs and lp commands used in that, and it will show you why your script is not working. I can imagine it will be a problem with the lp command (needing printer specific options), since gs only creates a PostScript file, which (I assume) cannot instruct the printer to indeed print front and back at once since.

  3. Jean Frederic Nalt

    For my part, I think I did the opposite, I create groups and new users on the servers and I add users to the groups.

    lets say each repo have a specific group named git-repos1, git-repos2

    if a want bob access to both:

    usermod -a -G git-repos1 bob
    usermod -a -G git-repos2 bob

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.