# How to setup Git server over http

2024-05-30

Note | This document is from 2006. A lot has happened since then, and this document is now relevant mainly if your web host is not CGI capable. Almost everyone else should instead look at git-http-backend(1).

Since Apache is one of those packages people like to compile themselves while others prefer the bureaucrat’s dream Debian, it is impossible to give guidelines which will work for everyone. Just send some feedback to the mailing list at git@vger.kernel.org to get this document tailored to your favorite distro.

What’s needed:

- Have an Apache web-server

      On Debian:
        $ apt-get install apache2
        To get apache2 by default started,
        edit /etc/default/apache2 and set NO_START=0

- can edit the configuration of it.

      This could be found under /etc/httpd, or refer to your Apache documentation.

      On Debian: this means being able to edit files under /etc/apache2

- can restart it.

      'apachectl --graceful' might do. If it doesn't, just stop and
      restart apache. Be warning that active connections to your server
      might be aborted by this.

      On Debian:
        $ /etc/init.d/apache2 restart
      or
        $ /etc/init.d/apache2 force-reload
        (which seems to do the same)
      This adds symlinks from the /etc/apache2/mods-enabled to
      /etc/apache2/mods-available.

- have permissions to chown a directory

- have Git installed on the client, and

- either have Git installed on the server or have a webdav client on the client.

In effect, this means you’re going to be root, or that you’re using a preconfigured WebDAV server.

## Step 1: setup a bare Git repository

At the time of writing, git-http-push cannot remotely create a Git repository. So we have to do that at the server side with Git. Another option is to generate an empty bare repository at the client and copy it to the server with a WebDAV client (which is the only option if Git is not installed on the server).

Create the directory under the DocumentRoot of the directories served by Apache. As an example we take /usr/local/apache2, but try "grep DocumentRoot /where/ever/httpd.conf" to find your root:

    $ cd /usr/local/apache/htdocs
    $ mkdir my-new-repo.git

    On Debian:

    $ cd /var/www
    $ mkdir my-new-repo.git

Initialize a bare repository

    $ cd my-new-repo.git
    $ git --bare init

Change the ownership to your web-server’s credentials. Use `"grep ^User httpd.conf"` and `"grep ^Group httpd.conf"` to find out:

    $ chown -R www.www .

    On Debian:

    $ chown -R www-data.www-data .

If you do not know which user Apache runs as, you can alternatively do a "chmod -R a+w .", inspect the files which are created later on, and set the permissions appropriately.

Restart apache2, and check whether http://server/my-new-repo.git gives a directory listing. If not, check whether apache started up successfully.

## Step 2: enable DAV on this repository

First make sure the dav_module is loaded. For this, insert in httpd.conf:

    LoadModule dav_module libexec/httpd/libdav.so
    AddModule mod_dav.c

Also make sure that this line exists which is the file used for locking DAV operations:

    DAVLockDB "/usr/local/apache2/temp/DAV.lock"

    On Debian these steps can be performed with:

    Enable the dav and dav_fs modules of apache:
    $ a2enmod dav_fs
    (just to be sure. dav_fs might be unneeded, I don't know)
    $ a2enmod dav
    The DAV lock is located in /etc/apache2/mods-available/dav_fs.conf:
      DAVLockDB /var/lock/apache2/DAVLock

Of course, it can point somewhere else, but the string is actually just a prefix in some Apache configurations, and therefore the directory has to be writable by the user Apache runs as.

Then, add something like this to your httpd.conf

    <Location /my-new-repo.git>
       DAV on
       AuthType Basic
       AuthName "Git"
       AuthUserFile /usr/local/apache2/conf/passwd.git
       Require valid-user
    </Location>

    On Debian:
      Create (or add to) /etc/apache2/conf.d/git.conf :

    <Location /my-new-repo.git>
       DAV on
       AuthType Basic
       AuthName "Git"
       AuthUserFile /etc/apache2/passwd.git
       Require valid-user
    </Location>

    Debian automatically reads all files under /etc/apache2/conf.d.

The password file can be somewhere else, but it has to be readable by Apache and preferably not readable by the world.

Create this file by $ htpasswd -c /usr/local/apache2/conf/passwd.git <user>

    On Debian:
      $ htpasswd -c /etc/apache2/passwd.git <user>

You will be asked a password, and the file is created. Subsequent calls to htpasswd should omit the -c option, since you want to append to the existing file.

You need to restart Apache.

Now go to http://<username>@<servername>/my-new-repo.git in your browser to check whether it asks for a password and accepts the right password.

On Debian:

    To test the WebDAV part, do:

    $ apt-get install litmus
    $ litmus http://<servername>/my-new-repo.git <username> <password>

    Most tests should pass.

A command-line tool to test WebDAV is cadaver. If you prefer GUIs, for example, konqueror can open WebDAV URLs as "webdav://…" or "webdavs://…".

If you’re into Windows, from XP onwards Internet Explorer supports WebDAV. For this, do Internet Explorer → Open Location → http://<servername>/my-new-repo.git [x] Open as webfolder → login .

## Step 3: setup the client

Make sure that you have HTTP support, i.e. your Git was built with libcurl (version more recent than 7.10). The command git http-push with no argument should display a usage message.

Then, add the following to your $HOME/.netrc (you can do without, but will be asked to input your password a lot of times):

    machine <servername>
    login <username>
    password <password>

…and set permissions: chmod 600 ~/.netrc

If you want to access the web-server by its IP, you have to type that in, instead of the server name.

To check whether all is OK, do:

    curl --netrc --location -v http://<username>@<servername>/my-new-repo.git/HEAD

…this should give something like ref: refs/heads/master, which is the content of the file HEAD on the server.

Now, add the remote in your existing repository which contains the project you want to export:

    $ git-config remote.upload.url \
        http://<username>@<servername>/my-new-repo.git/

It is important to put the last /; Without it, the server will send a redirect which git-http-push does not (yet) understand, and git-http-push will repeat the request infinitely.

## Step 4: make the initial push

From your client repository, do

    $ git push upload master

This pushes branch master (which is assumed to be the branch you want to export) to repository called upload, which we previously defined with git-config.

## Using a proxy:

If you have to access the WebDAV server from behind an HTTP(S) proxy, set the variable all_proxy to `http://proxy-host.com:port`, or `http://login-on-proxy:passwd-on-proxy@proxy-host.com:port`. See man curl for details.

## Troubleshooting:

If git-http-push says

    Error: no DAV locking support on remote repo http://...

then it means the web-server did not accept your authentication. Make sure that the user name and password matches in httpd.conf, .netrc and the URL you are uploading to.

If git-http-push shows you an error (22/502) when trying to MOVE a blob, it means that your web-server somehow does not recognize its name in the request; This can happen when you start Apache, but then disable the network interface. A simple restart of Apache helps.

Errors like (22/502) are of format (curl error code/http error code). So (22/404) means something like not found at the server.

Reading /usr/local/apache2/logs/error_log is often helpful.

    On Debian: Read /var/log/apache2/error.log instead.

If you access HTTPS locations, Git may fail verifying the SSL certificate (this is return code 60). Setting http.sslVerify=false can help diagnosing the problem, but removes security checks.

Debian References: http://www.debian-administration.org/articles/285

Authors Johannes Schindelin <Johannes.Schindelin@gmx.de> Rutger Nijlunsing <git@wingding.demon.nl> Matthieu Moy <Matthieu.Moy@imag.fr>