Note: This tutorial is based on this very good site, thanks for the work:


This is a simple and step by step tutorial on how to install GIT server and Gitolite in Debian Squeeze.Since GIT has no authentication/authrization methods on its own Gitolite does fill in. Gitolite allows to control new creation of all new GIT repositories as well as who is allowed to work with which repository. All done via configuration files in a gitolite-admin repository which gets pulled from the master GIT server by the Gitolite admin user, modified and pushed back. Then the magic happens immediately at the server side.


========== In GIT server =========
Install git and gitolite
apt-get update
apt-get install git-core python-setuptools gitolite

Setup the gitolite temp password
passwd gitolite
Create the .ssh directory to contain the remote client’s public keys
su - gitolite
mkdir $HOME/.ssh/

========= in your desktop Linux as gitolite user ==================

Create the gitadmin user as git administrator
(press the {Enter} key as answer to every question)
useradd -m gitadmin
su - gitadmin
ssh-keygen -t rsa

Create the GIT repositories base directory
mkdir ~/gitrepos
Transfer the git administrator’s public key to gitolite ~/.ssh/ directory in server
cat ~/.ssh/ | ssh 'cat > ~/.ssh/'
================ Back in GIT server as gitolite user ===============
Setup gitolite with the gitadmin pub key
gl-setup $HOME/.ssh/
================ in your desktop linux as gitadmin user ===============
Clone the gitolite control repo into your local work space
cd ~/repositories
git clone ssh://

Some descriptitons of the configuration files:
~/gitrepos/gitolite-admin/conf/gitolite.conf: file and you will add users, privileges and projects/repos here
~/gitrepos/gitolite-admin/conf/keydir/: directory that contains the ssh public keys files of git users

IMPORTANT: Make sure the filename of ssh key matches the user in gitolite.conf without the ‘.pub’
eg. For user ‘martin’ you would have your ssh key file in keydir/ and in gitolite.conf you have the following:
repo gitolite-admin
RW+ = martin

Adding the first normal git user called ‘martin’

================ IN martins’s desktop ===============
Transfer martin’s ssh public key to the GIT server
cat ~/.ssh/ | ssh 'cat > ~/gitrepos/gitolite-admin/keydir/'

================ Back to the gitadmin user’s desktop ===============
Configuring gitolite to allow martin to be able to read/write/push in testrepo1 repo
vim ~/gitrepos/gitolite-admin/conf/gitolite.conf
repo gitolite-admin
RW+ = gitadmin
repo testrepo1
RW+ = martin
repo public-repo
RW+ = @all

This above configuration means:(RW+=Read Write Push)
gitadmin can RW+ on gitolite-admin repo
martin can RW+ on testrepo1 repo
everybody can RW+ on public-repo

Update the new config to the master git server
cd ~/gitrepos/gitolite-admin/
git add keydir/*
git commit -am "added martin access to testrepo1 repo"
git push

NOTE: with the ‘push’ gitolite on the git server will create the missing repositories automatically in the git server and assign their proper access rights. Never any need to go on the git server to create new repos.

Working on the testrepo1 repo from martin’s desktop

================ In martin’s desktop as martin user ===============
mkdir gitrepos
cd gitrepos/
git clone ssh://

Response should be:
Cloning into testrepo1...
warning: You appear to have cloned an empty repository.

Now make changes in the repo
cd testrepo1
echo "content1" >testfile1.txt

Commit the changes to the server
git add testfile1.txt
git commit -am 'First commit to repo'

NOTE: No need to worry about the lots of warning messages
Simply note the Committer line message:
Committer: martin <martin@laptop.local>

To illiminate those messages do the following commands:
git config --global martin
git config --global martin@laptop.local

The first time you make a push to an empty repository it should be done this way
git push origin master
You should get the follwoing similar result:
Counting objects: 3, done.
Writing objects: 100% (3/3), 229 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://
* [new branch] master -> master

From now on the repository committing and push commands will done as normal. Example:
echo "second file" > testfile2.txt
git add testfile2.txt
git commit -am 'Second commit to repo'
git push

Result should be:
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 290 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://
3aa8b8f..5472dfc master -> master


This part of the tutorial is an identical extract of the following article. Thanks for the good work:


Do NOT add new repos or users manually on the server. Gitolite users, repos, and access rules are maintained by making changes to a special repo called ‘gitolite-admin’ and pushing those changes to the server.

To administer your gitolite installation, start by doing this on your workstation (if you have not already done so):
git clone ssh://

**NOTE**: if you are asked for a password, something has gone wrong with the initalization of gitolite with the admin’s public key.

Now if you ‘cd gitolite-admin’, you will see two subdirectories in it: conf and keydir.

To add new users alice, bob, and carol, obtain their public keys and add them to keydir directory as,, and respectively. Make sue the name of the user used in the configuration file is the same as the key filename (without the .pub)

To add a new repo ‘foo’ and give different levels of access to these users, edit the file ‘conf/gitolite.conf’ and add lines like this:
repo foo
RW+ = alice
RW = bob
R = carol

See the ‘ACCESS RULES’ section later for more details. Once you have made these changes, do something like this:
cd ~/gitrepos/gitolite-admin/
git add keydir/*
git commit -m 'added foo, gave access to alice, bob, carol'
git push

When the push completes, gitolite will add the new users to ~/.ssh/authorized_keys on the server, as well as create a new, empty, repo called ‘foo’.


Once a user has sent you their public key and you have added them as specified above and given them access, you have to tell them what URL to access their repos at. This is usually ‘git clone git@host:reponame’; see man git-clone for other forms.

**NOTE**: again, if they are asked for a password, something is wrong.

If they need to know what repos they have access to, they just have to run ‘ssh git@host info’; see ‘COMMANDS’ section later for more on this.


The basic syntax of the conf file is very simple.

* Everything is space separated; there are no commas, semicolons, etc., in the syntax.
* Comments are in the usual perl/shell style.(the ‘#’)
* User and repo names are as simple as possible; they must start with an alphanumeric, but after that they can also contain ‘.‘, ‘_‘, or ‘‘.

Usernames can optionally be followed by an ‘@’ and a domainname containing at least one .; this allows you to use an email address as someone’s username.

Reponames can contain / characters; this allows you to put your repos in a tree-structure for convenience.

* There are no continuation lines.


This section is mostly ‘by example’.

Gitolite’s access rules are very powerful. The simplest use was already shown above. Here is a slightly more detailed example:
repo foo
RW+ = alice
- master = bob
- refs/tags/v[0-9] = bob
RW = bob
RW refs/tags/v[0-9] = carol
R = dave

For clones and fetches, as long as the user is listed with an R, RW or RW+ in at least one rule, he is allowed to read the repo.
For pushes, rules are processed in sequence until a rule is found where the user, the permission (see note 1), and the refex (note 2) *all* match. At that point, if the permission on the matched rule was ‘‘, the push is denied, otherwise it is allowed. If no rule matches, the push is denied.

Note 1: permission matching:

* a permission of RW matches only a fast-forward push or create
* a permission of RW+ matches any type of push
* a permission of ‘-‘ matches any type of push

Note 2: refex matching:
(refex = optional regex to match the ref being pushed)

* an empty refex is treated as ‘refs/.*
* a refex that does not start with ‘refs/’ is prefixed with ‘refs/heads/’
* finally, a ‘^’ is prefixed
* the ref being pushed is matched against this resulting refex

With all that background, here’s what the example rules say:

* alice can do anything to any branch or tag — create, push, delete, rewind/overwrite etc.
* bob can create or fast-forward push any branch whose name does not start with ‘master’ and create any tag whose name does not start with ‘v‘+digit.
* carol can create tags whose names start with ‘v‘+digit.
* dave can clone/fetch.


Gitolite allows you to group users or repos for convenience. Here’s an example that creates two groups of users:
@staff = alice bob carol
@interns = ashok
repo secret
RW = @staff
repo foss
RW+ = @staff
RW = @interns

Group lists accumulate. The following two lines have the same effect as the earlier definition of @staff above:
@staff = alice bob
@staff = carol

You can also use group names in other group names:
@all-devs = @staff @interns

Finally, @all is a special group name that is often convenient to use if you really mean ‘all repos‘ or ‘all users‘.


Users can run certain commands remotely, using ssh. For example:
ssh git@host help
prints a list of available commands.

The most commonly used command is ‘info’. All commands respond to a single argument of ‘-h’ with suitable information. If you have shell on the server, you have a lot more commands available to you; try running ‘gitolite help’.


Some of the instructions below may require you to edit the rc file (~/.gitolite.rc on the server).

The rc file is perl code, but you do NOT need to know perl to edit it. Just mind the commas, use single quotes unless you know what you’re doing, and make sure the brackets and braces stay matched up.


Gitolite lets you set git-config values for individual repos without having to log on to the server and run ‘git config’ commands:
repo foo
config hooks.mailinglist = foo-commits@example.tld
config hooks.emailprefix = '[foo] '
config = ''
config foo.baz =

The last two syntaxes shown above are the *only* way to *delete* a config variable once you have added it. Merely removing it from the conf file will *not* delete it from the repo.git/config file.

Some git-config keys allow arbitrary code to be run on the server.

If all of your gitolite admins already have shell access to the server account hosting it, you can edit the rc file (~/.gitolite.rc) on the server, and change the GIT_CONFIG_KEYS line to look like this:
Otherwise, give it a space-separated list of regular expressions that define what git-config keys are allowed. For example, this one allows only variables whose names start with ‘gitweb’ or with ‘gc’ to be defined:
GIT_CONFIG_KEYS => 'gitweb\..* gc\..*',


Gitolite creates the ‘git-daemon-export-ok’ file for any repo that is readable by a special user called ‘daemon’, like so:
repo foo
R = daemon


Any repo that is readable by a special user called ‘gitweb’ will be added to the projects.list file.
repo foo
R = gitweb

Or you can set one or more of the following config variables instead:
repo foo
config gitweb.owner = some person's name
config gitweb.description = some description
config gitweb.category = some category

You will probably need to change the UMASK in the rc file from the default (0077) to 0027 and add whatever user your gitweb is running as to the ‘git’ group. After that, you need to run a one-time ‘chmod -R’ on the already created files and directories.

Installing Gitweb

Gitweb allows to view the repositories in a web interface. It only has the read access.
Example of Gitweb URL:

Install gitweb

apt-get install gitweb

Symlink the git repository to where gitweb CGI expects it

rmdir /var/cache/git
ln -s /var/lib/gitolite/repositories /var/cache/git

Configure Apache to access gitweb.

After installing gitwen Apache2 is already configured for gitweb.
To make sure the portal is not accessible from everybody on the Net make sure it is protected by Authentication for gitolite user as follows:

Set the Apache user to be allowed to read the repositories which has only access by gitolite user
vim /etc/apache2/envvars
export APACHE_RUN_USER=www-data
export APACHE_RUN_USER=gitolite

Configure the authentication
vim /etc/apache2/conf.d/gitweb
<Directory /usr/share/gitweb>
Options FollowSymLinks +ExecCGI
AddHandler cgi-script .cgi

<Directory /usr/share/gitweb>
AuthType Basic
AuthName "Private area"
AuthUserFile /etc/apache2/web.auth
Require user gitolite
Options FollowSymLinks +ExecCGI
AddHandler cgi-script .cgi

Set the gitolite user poassword for gitweb acccess

htpasswd -c /etc/apache2/web.auth gitolite
(type 2 times the password)

Enable the SSL module for Apache

a2enmod ssl
a2ensite default-ssl

Set the certificate to a proper one

vim /etc/apache2/sites-enabled/default-ssl
Set the certificates files path of the flowing 2 lines appropriately
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

Restart Apache

service apache2 restart

Happy Gitting šŸ™‚