How to serve a private git repository with gitolite
Introduction
Git repositories can easily be published by putting them into a place from which they can be served via http. Except for a standard web server like apache, no additional server is necessary in order to give public read access to your git repository. Of course one can run gitweb, but it's not necessary. One simply can put a bare git repository into a place that is served via http, runs "git update-server-info" on the repository and gives enough read permissions.
The above, however, makes your repository world readable.
The following steps show how you can share one or several repositories with other people. Giving them only read or read/write access. Those people must only provide a public ssh key, but they don't need an account on the server machine.
Some background information: Sharing is done by making your repository available on a dedicated computer, the server. This server machine should, of course be always connected to the internet. People (including yourself) will talk to your repository through gitolite. Gitolite takes care of controlling permissions, but no server daemon must be running in the background.
Preparation
In the following there are two machines involved and, of course, two accounts on these machines. Let's name them by variables. In all places thatall they appear below, replace them by their actual value!!!
GLSERVER=dolphin.risc.jku.at GLCLIENT=dog.risc.jku.at SERVERACCOUNT=hemmecke CLIENTACCOUNT=hemmecke
Of course, the account names can be the same or different.
Make sure you have all necessary software installed on the server, see http://sitaramc.github.com/gitolite/install.html#req. If you are unsure the following command should bring you there.
sudo apt-get install gitk perl
Make sure you have Git in version 1.6.6 or greater. Check with
git --version
Make sure that for all of the following you should be using a posix compatible shell. csh and tcsh aren't. Use bash or sh.
Some ssh setup
In this setup we have one key (id_rsa) for passwordless shell access from the client to the server and another key (gitolite) for managing git repositories via gitolite.
You issue the following command on the client machine and generate and copy the first key.
If you have already a file $HOME/.ssh/id_rsa
, then you don't need to generate a key pair!!!
If you don't yet have a private/public key pair in $HOME/.ssh
, then issue the following command and accept the default location of the key (which is $HOME/.ssh/id_rsa
).
ssh-keygen -t rsa
You should enter a passphrase, because otherwise people who capture your private key (for example, when your computer is unattended for some reason), can do a lot of mischief with it. And everyone will claim that it was you, because it was done with your key. Therefore, protect your private key with a (long and hard to guess) passphrase.
This will generate two files inside $HOME/.ssh
, namely id_rsa
(private key) and id_rsa.pub
(public key).
Make sure you can ssh to your server without password. In short: you have to append your public key from your local machine to the authorized_keys
file on the server machine. It's done like this.
#GLCLIENT ssh-copy-id -i ~/.ssh/id_rsa.pub $SERVERACCOUNT@$GLSERVER
If you now type
ssh $SERVERACCOUNT@$GLSERVER
you should be asked for the passphrase of your ssh key, but not for the password on the server machine.
Make sure you can login to the server without a password! Don't go on until this works.
Now we can generate the second key. On the client machine generate a new key and copy it to the server.
ssh-keygen -t rsa -f $HOME/.ssh/gitolite
scp $HOME/.ssh/gitolite.pub $SERVERACCOUNT@$GLSERVER:.ssh/$CLIENTACCOUNT.pub
Enter the following host alias to the file $HOME/.ssh/config
on the client.
host gitolite User $SERVERACCOUNT HostName $GLSERVER port 22 IdentityFile ~/.ssh/gitolite HostbasedAuthentication no
Note: You should, of course, not put the variables there but rather replace the $ variables by their actual value.
Make yourself known to git
Issue the following commands (of course with your respective data!) on the server
git config --global user.name "Firstname Lastname" # <--- Change appropriately git config --global user.email "$SERVERACCOUNT@risc.jku.at"
and the client.
git config --global user.name "Firstname Lastname" # <--- Change appropriately git config --global user.email "$CLIENTACCOUNT@risc.jku.at"
Installation of Gitolite on the server
The installation guide at http://sitaramc.github.com/gitolite/qi.html explains how to setup gitolite in such a way that you have to provide your password in case you want to ssh from the client machine (laptop or desktop) to the server (a machine that has to be on the internet all the time). In chapter "Get public key ssh access from client to server" we basically setup a passwordless access method. We therefore need a second ssh key that will be used to manage gitolite.
Go to the server and install gitolite.
cd $HOME # This could be actually any directory.
git clone git://github.com/sitaramc/gitolite
gitolite/install
$HOME/gitolite/src/gitolite setup -pk $HOME/.ssh/$CLIENTACCOUNT.pub
Clone the admin repository from the server to the client
#GLCLIENT
git clone gitolite:gitolite-admin
Note that using "gitolite" as the server name uses the host entry "gitolite" in the file $HOME/.ssh/config
.
How to create a new repository that you want to share
Make sure you are logged in to the client!
Assume you want to create a new repository with name myrepo
.
- Edit the file
$HOME/gitolite-admin/conf/gitolite.conf
to contain the following (additional) lines:
repo myrepo RW+ = $CLIENTACCOUNT
where (of course) you replace$CLIENTACCOUNT
by the appropriate value. - You must tell the server by pushing to it.
cd $HOME/gitolite-admin git add conf/gitolite.conf git commit -m 'create new repository myrepo'
git push - Executing the following commands will give you an empty repo
myrepo
,
git clone gitolite:myrepo
which you can fill with data afterwards.
How to give someone (including yourself) access to your repo
The infrastructure is already there. You basically have to add a public key from the person that should get access and an entry in the config file. Suppose somebody has sent you his public key (usually his $HOME/.ssh/id_rsa.pub
file). Invent some userid, for example, user1
or simply take the user's account name. To be on the safe site, the userid should only contain small letters and numbers.
Store the public key as $HOME/gitolite-admin/keydir/user1.pub
then add a line to your myrepo
section of your $HOME/gitolite-admin/conf/gitolite.conf
.
repo myrepo RW+ = $CLIENTACCOUNT R = user1 # <--- add this line
As in section How to create a new repository that you want to share, you commit and push your changes so that the server can take appropriate actions.
cd $HOME/gitolite-admim git add conf/gitolite.conf git add keydir/user1.pub git commit -m 'give read access for repository myrepo to user1' git push
If you want to use your laptop to access the repository, you should generate an ssh keypair on the laptop (if you do not already have one) via
ssh-keygen -t rsa
and treat the file $HOME/.ssh/id_rsa.pub
from the laptop like a public key above. Note that you should probably not use any userid that is already on the list. It's probably safe to use admin
as a userid and to add a line (read/write access) as follows to the myrepo
section.
repo myrepo ... RW = admin
Note that the userid is like a virtual account name and solely needed to name the public key in the $HOME/gitolite-admin/conf/gitolite.conf
file, but is not connected to any real account name.
As you see from above, you have to add a key to your $HOME/gitolite-admin/conf/gitolite.conf
file for every different keypair of a user.
Now, user1 can access your repository
git clone $SERVERACCOUNT@$GLSERVER:myrepo
Note: You should, of course, not put the variables there but rather replace the $ variables by their actual value. In particular, the part in front of the @ should be the account name of where the repository is located. In other words, if the repository is in ~foo/repositories/myrepo.git
on the server blah.example.org
, then user1 would have to call
git clone foo@blah.example.org:myrepo
in order to access this repository. Another option is that user1 puts something like this
host myreposerv User user1 HostName foo@blah.example.com port 22 IdentityFile ~/.ssh/id_rsa HostbasedAuthentication no
into his $HOME/.ssh/config
(under the assumption that the corresponding public key for user1 on foo@blah.example.com
is a copy of user1's local ~/.ssh/id_rsa.pub
) and then calls
git clone myreposerv:myrepo
If anything is wrong, user1 will usually get problems like being asked for a password of some (other) user instead of the passphrase for his respective key.
How to get data from the official upstream repository
The maintainer of the upstream repository must have given you read access to his repository, so you should have sent him your public key (most probably your file $HOME/.ssh/id_rsa.pub
).
Assume you have already done the above steps How to create a new repository that you want to share and you have access to the official repository. Now, you have to connect your local repository to the official one. Locally, we call this official repository upstream
. Assume the official repository is accessible via theorema@risc.jku.at
.
cd myrepo git remote add upstream theorema@risc.jku.at git fetch upstream
Everyone (except $CLIENTACCOUNT
at $GLCLIENT
) clones your repository via
git clone $SERVERACCOUNT@$GLSERVER:myrepo
You (on the machine $GLCLIENT
, but not on your laptop) clone via the following command
git clone gitolite:myrepo
How to make your life easier
Every connection to a remote repository requires you to enter the passphrase of your ssh key. By using ssh-add
, you only need to enter your password once per session. Simply execute the following command.
ssh-add $HOME/.ssh/id_rsa
If you see an error message like "Could not open a connection to your authentication agent.", then your ssh-agent
is not running. Start it as follows.
exec ssh-agent /bin/bash
Resolving Trouble
Most trouble is with ssh, Since Sitaram Chamarty, the author of gitolite has already put together quite a few common mistakes, I will not repeat it here.