Using git over http with git-http-backend

This could be the third time I wrote a post like this. Editing apache configuration is ever so  tricky to me that something would definitely go wrong somehow. After I successfully smoothed thing out, I would write a post and then sometime later, my blog went down and here I am again.

So to make the long story short, my colleagues and I  have a project and a version control server. I don’t want to give my colleagues SSH key to the server since I store many other things on it, so I need another way to give them read and write access to the share git repo (with authentication of course).

To give access to git repo is easy. Git provide a CGI program called git-http-backend that will handle communication over the HTTP protocols, all we have to do is set some environments variable and alias apache to that CGI:

SetEnv GIT_PROJECT_ROOT /path/to/you/repo/parent/directory/
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/

The first variable is the system path to the parent directory of your git repo. I don’t know much about the second variable, I found an explanation here but I don’t understand that explanation either, so we just leave it there

If you leave out GIT_HTTP_EXPORT_ALL environment variable, then Git will only serve to unauthenticated clients the repositories with the git-daemon-export-ok file in them, just like the Git daemon did.

On some system, git-core is locate in  /usr/libexec instead of just /usr/lib so watchout for that, apache won’t tell you if the path was  wrong, make sure you get it right. The next part is authentication we can do it with this block:

<LocationMatch "^/git/.*/git-receive-pack$">
AuthType Basic
AuthName "Git Access"
AuthUserFile /path/to/your/.htpasswd
Require valid-user

Authentication will be handle by apache, git-http-backend won’t handle it. The regex in LocationMatch tell git to require authentication only if client is accessing object negotiation for the push, not the pull. If you require authentication for both push and fetch, change the first line to <LocationMatch "^/git/"> . You will be required to create a .htpasswd file contain all the username and password. that  file can using the program htpasswd:

htpasswd .htpasswd abc
New password:
Re-type new password:
Updating password for user abc

A guide I read suggest using htdigest but the .htpasswd for that file keep resulting in HTTP401 error so forget about it. When you are done with apache configuration, you can go create a bare repository on your server:

cd /path/to/you/repo/parent/directory/repo.git
git init --bare
git config http.receivepack true

The last command is require to enable write access to your repository. Since the authentication is done by apace, git don’t get the username and it treat all push as anonymous, thus disable by defaults. If you don’t config it otherwise it will throw you a Service not enabled: 'receive-pack' line in the error.log

Finally you can push to your newly setup upstream by running this at your local computer:

git push –set-upstream master

The red part in the command tell apache to handle it using git-http-backend and the blue part is your repository.