This page was originally published on blog.procrastination.nl, which is still on-line for archival purposes.
There are several posts describing how to get git pull using git-http-backend working on shared hosting, for example this post by mobiphil. However, following those steps, I was left with an unclear 'code 22' error when pushing.
In this post, I will describe shortly how I set-up git on my shared hosting account in a way that does allow pushing.
It should be possible to do this without shell access, but I have not tried this.
1. Getting git
Git was not available on the server by default, so I downloaded a reasonable RPM package:
~ $ mkdir git && cd git
~/git $ wget http://packages.sw.be/git/git-1.7.3-1.el5.rf.x86_64.rpm
~/git $ rpm2cpio git-1.7.3-1.el5.rf.x86_64.rpm | cpio -idmv
~/git $ usr/bin/git
usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]
[--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]
[-c name=value] [--help]
2. Create a CGI handler script
~ $ cat > public_html/cgi_bin/git.cgi
if [ -z "$REMOTE_USER" ]
Using absolute paths is probably not necessary, but hey, why not.
Important things to notice:
- The GIT_PROJECT_ROOT variable should be defined correctly
- If you want to export all git repositories by default, add
- REMOTE_USER needs to be defined for pushing to work. Due to redirects, sometimes only REDIRECT_REMOTE_USER is defined. Hence, REMOTE_USER will then be set to REDIRECT_REMOTE_USER.
- git-http-backend is not in usr/bin but in usr/libexec/git-core
This is enough to get public read access working onder an URL such as
http://host/cgi-bin/git.cgi/repos. If you want a nicer URL, read on.
Note: Pushing will fail with error code '22'.
3. htaccess URL rewriting and authentication
At the moment I only have a few repositories, so I chose the following approach. In public_html, create a directory structure
git/repos2, etc. In each of these directories, add an .htaccess file:
~/public_html/git/repos1 $ cat > .htaccess
AuthName "Git repository I"
RewriteRule ^(.*)$ /cgi-bin/git.cgi/repos1/$1
This will now allow access using the (authenticated) url
http://host/git/repos1, which will allow you to push /and/ pull!
4. Preventing direct access to git.cgi
To prevent people from accessing git.cgi directly, I used the following snippet on top of the git.cgi file:
if [[ $REQUEST_URI != /git/* ]]
echo Status: 403 Forbidden
echo Content-type: text/plain
echo Direct access to git.cgi is not allowed