External Publication
Visit Post

My Keep-It-Simple-Stupid Git Setup

angelwood.xyz [Unofficial] April 20, 2026
Source

Most of my projects are hosted on either sr.ht and/or codeberg. But due to some uptime issues on both providors, I have been searching for a self-hosted solution in the case that one or both of them are down.

After some searching I found stagit, a small fully static git hosting platform with minimal dependicies. Combined with a simple http proxy a fully stattic git hosting system is possible!

Getting started!

After installing stagit you should have both stagit and stagit-index in your path. You will also need to get stagit-post-receive from the official repo and install it into the path. Easiest way of doing that is putting it in /usr/local/bin/

Open the post-receive script in any text editor and change the variables at the top, Mainly reposdir and htmldir to match where you have decided to store your html and git repos on your system.

Here is an example:

# ... Start of the file ...

# config
# paths must be absolute.
reposdir="/var/git/"
dir="${reposdir}/${name}"
htmldir="/var/www/git.angelwood.xyz"
stagitdir="/"
destdir="${htmldir}${stagitdir}"
cachefile=".htmlcache"
# /config

# ... Rest of the file ...

Now that we have stagit setup, lets create a repo! To make our lives easier we can create a small script called stagit-init-repo that sets up the required hooks and symbolic links

#!/usr/bin/env sh
git init --bare $1
cd $1
echo https://git.angelwood.xyz/$1 >> url # generate URL automatically
ln -s /usr/local/bin/stagit-post-receive.sh hooks/post-receive # auto-updates stagit on each push
mv hooks/post-update.sample hooks/post-update # allows static git pull by adding git update-server-info
chmod ug+x hooks/ # sanity check on permissions for the hooks

#usage: stagit-init-repo repo-name

The last step is to point your HTTP(s) server of choice at whereever you set htmldir to be. If this server is not ment for the general public you can stop here, but you can continue on if you want anyone to beable to git clone it!

Git Cloning without a CGI

99% of git servers use a CGI to allow http transfers, but we can use the GIT HTTP Dumb Protocol to keep our server 100% static!

In your HTTP server's configuration you need to create a small redirection rule to change what directory to point to based on the useragent. When a browser access a repo it should direct itself to the htmldir, but when a git useragent is used it should be redirected to reposdir. Here is an example for Caddy:

git.angelwood.xyz {
        root /var/www/git.angelwood.xyz/
        file_server

        @git {
                header User-Agent git/*
        }

        handle @git {
                root * /var/git/
                file_server
        }
}

To ensure that this works you need to have the post-update script run the command git update-server-info to create some additional helper files for the Dumb HTTP protocol. You can do this after the fact if you have already created repos without this hook already established. My example stagit-init-repo script already sets this up for you so you should all ready to go!

Drawbacks

This system does have some drawbacks, having a static git repo means that every page needs to be pre-calculated. The Dumb HTTP protocol also has the drawback of being slightly more inefficient has git has to precalculate your request before hand. If you still want a lightweight git hosting solution that is usable on large repositories I can higly recommend cgit.

Special Thanks

  • Thank you to ليلى النحلة for innitially showing me stagit
  • This blogpost by a3nm for some helpful tips
  • The wonderful Caddy documentation

Discussion in the ATmosphere

Loading comments...