Sunday, 23 June 2013

How to Create a shared Git Repository in Debian (ssh, git-daemon, gitweb)

Git is a distributed revision control system.

We are going to create a remote shared git repository and add the following functionality to it:

- Read and write access using ssh protocol.
- Anonymous read only access via git-daemon.
- Browse every git repository via web.
- Send an email notification when user pushes a commit.

This article shows how to set a Git repository in a Debian distro (Sid).

Create the repository in the remote machine

First we are going to configure the remote machine where the git repository will be installed.

Create a directory where we will place every git repository:
$ mkdir /gitrepo

Install git
$ sudo aptitude install git

Every user able to read and write to the git repository must pertain to gitgroup group.
$ sudo groupadd gitgroup
$ sudo chgrp -R gitgroup /gitrepo
$ sudo chmod g+w /gitrepo

Generic home for users pertaining to gitgroup group:
$ sudo mkdir /home/gitgroup
$ sudo chgrp -R gitgroup /home/gitgroup

We add our current user to gitgroup group.
$ sudo adduser my_user gitgroup
Changes will become effective after login in again.
$ groups
my_user sudo gitgroup

We create now a bare git repository
$ cd /gitrepo
$ git init --bare --shared=0664 my_git_project
Initialized empty shared Git repository in /gitrepo/bar/

0664: other user has read only permissions.
0660: other user has no permissions.

$ chgrp -R gitgroup my_git_project

--shared option sets directories, new files etc to the right permissions.

Now we have a bare repository where we could upload our commits or another preexisting repository.

Read and write access

To allow read and write access we use ssh server.
Ssh server manages authentication, and if correct, allows the user access to repository content and execute git commands.

Install ssh server in remote machine:

$ sudo aptitude install openssh-server

Create some restricted users e.g: user_git who will execute git commands only:
$ sudo adduser --shell /usr/bin/git-shell --home /home/gitgroup --ingroup gitgroup --disabled-login user_git
$ sudo passwd user_git
$ sudo adduser user_git gitgroup

After correctly setting ssh server we can now clone the repository from outside:

This is the general ssh address format: ssh://[user@]host.xz[:port]/path/to/repo.git/

$ git clone ssh://user_git@my_computer/gitrepo/my_git_project
Cloning into 'my_git_project'...
user_git@myComputer's password:
warning: You appear to have cloned an empty repository.

If we have an already existing repository in our local box, we could upload it to the remote repository:
Local_box$ cd repo
$ git remote add remote_repo ssh://user_git/gitrepo/bar
$ git push remote_repo master:master

That means, we create a remote configuration named "remote_repo"
then we upload local contents from local master branch into remote master branch.

Read only access

We provide anonymous read only access to our repository using git-daemon

Install git-daemon
Git-daemon is installed along with git package. No need to install any more packages.
$ dpkg -S /usr/lib/git-core/git-daemon
git: /usr/lib/git-core/git-daemon

We will call git-daemon via xinetd daemon.
$ sudo aptitude install xinetd

Configure xinetd for git daemon
$ sudo nano /etc/xinetd.d/git

service git
        disable         = no 
        socket_type     = stream
        wait            = no
        user            = nobody
        group           = gitgroup
        server          = /usr/lib/git-core/git-daemon
        server_args     = --reuseaddr --syslog --inetd --verbose
        log_on_failure  += USERID

Restart xinetd service
$ sudo service xinetd restart

Grant access to anonymous users:
$ cd /gitrepo/my_git_project
$ touch git-daemon-export-ok

In the local machine we can now clone it:
$ git clone git://REMOTE_IP/gitrepo/my_git_project my_git_project

Browse the repository via web

Gitweb is the tool we are going to use to browse git repositories via web.

Install gitweb:
$ sudo aptitude install gitweb # it installs apache too as a dependency.
$ sudo aptitude install libapache2-mod-perl2 # apache perl mode to execuge cgi scripts.

Configuring apache:

You can add this to /etc/apache2.conf or wherever suits you.

#Configuration to execute perl cgi scripts:
   <Files ~ "\.(pl|cgi)$">
    SetHandler perl-script
    PerlResponseHandler ModPerl::PerlRun
    Options +ExecCGI
    PerlSendHeader On

# Configuraton to create a virtual host
<VirtualHost *:80>

  DocumentRoot /var/www

  Alias /gitrepo /usr/share/gitweb

  SetEnv  GITWEB_CONFIG  /etc/gitweb.conf


  <Directory /var/www/git>
    Allow from all
    AllowOverride all
    Order allow,deny
    Options +ExecCGI
    AddHandler cgi-script .cgi
    DirectoryIndex gitweb.cgi

Configuring gitweb:
$ sudo nano /etc/gitweb.conf

# path to git projects (.git)
$projectroot = "/gitrepo";   # where our git projects are located.
$home_link_str = "Gitrepo";  # Shows this as base of our projects in the browser.

# shows these addresses to clone the git projects.
our @git_base_url_list = qw(git://your_remote_IP/gitrepo
$site_name = "My Git Repository"; # Page name.
$export_ok = "git-daemon-export-ok";  # Same visible repos as with git-daemon.
$feature{'blame'}{'default'} = [1];

Configure Description of the git project.

Description cannot be set as git config variable or gitweb will not detect it.

$ cd /gitrepo/my_git_project
$ echo "My first git project in this repo" > description

Set the owner of the project:
$ git config gitweb.owner "User name <user@email.address>"

Configure web server user to grant permissions to gitrepo directory:
$ sudo adduser www-data gitgroup
NOTE: Since www-data has gitgroup write access, document root should not be set the same as /var/www/git
$ sudo service apache2 restart

Now we can open http://your_remote_IP/gitrepo in your web browser and watch a list of your projects.

Select one of them and enter in the summary. Then you can check commits, etc.


Receiving an email is an useful functionality in a shared project where serveral users commit changes.

We will need a hook which comes with git package:
$ dpkg -S /usr/share/git-core/contrib/hooks/post-receive-email
git: /usr/share/git-core/contrib/hooks/post-receive-email

Now we go to the git project and configure hooks there with the right post-receive-email hook.
$ cd /gitrepo/my_git_project/hooks
$ cp /usr/share/git-core/contrib/hooks/post-receive-email post-receive
$ chmod a+x post-receive

Add the users who will be notified via email:
$ git config hooks.mailinglist ","

Configure the email message content with git config hooks.showrev variable:

This shows less information than the next one:
$ git config hooks.showrev "git show -C %s; echo"

or this one: adapt it to your system. e.g: your_repository_IP and my_git_project
$ git config hooks.showrev "t=%s; printf 'http://your_repository_IP/gitrepo/?p=my_git_project;a=commitdiff;h=%%s' \$t; echo;echo; git show -C \$t; echo"

Email will be cropped after one hundred lines:
$ git config hooks.emailmaxlines 100

NOTE: sendmail or another mail daemon should be running and properly configured.
$ sudo aptitude install sendmail
$ sudo service sendmail start


$ man git-daemon

Share git repository between several users.

Send email when user pushes a commit:

Install and configure gitweb:

Configure perl cgi scripts in apache2:


Git Command Quick Reminder

0 comentarios: