Mirroring my git repositories
Wed 02 April 2025 — download

Since everything is going downhill on the internet, I spent some time mirroring some of my git repositories on a machine at home. I chose cgit for the interface, as everything else is fucking terrible at best. The deployment is trivial: install cgit and fastcgi, create a git user with /src/git as home, slap the following into your nginx configuration and you're good to go:

server {
    server_name git.dustri.org;
    root /usr/share/webapps/cgit;
    try_files $uri @cgit;

    location ~* ^.+\.(css|png|ico)$ {
        root /usr/share/webapps/cgit;
        expires 30d;
    }

    location @cgit {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root/cgit.cgi;
        fastcgi_param PATH_INFO $uri;
        fastcgi_param QUERY_STRING $args;
        fastcgi_pass unix:/var/run/fcgiwrap/fcgiwrap.sock;
    }
}

The configuration for cgit is also super-simple:

virtual-root=/
scan-path=/srv/git
clone-prefix=https://git.dustri.org
footer=""
section-from-path=1
repository-sort=age

I git clone'd the repositories I wanted to mirror into /srv/git via git clone --mirror …, and wrote a shell script to kept them updated:

#!/bin/sh

for dir in /srv/git/*/; do
    echo "[+] Updating $dir"
    git --git-dir="$dir" remote update
    touch -d "$(git --git-dir="$dir" --no-pager log -1 --format='%as')" "$dir/packed-refs"
done

As cgit is using packed-refs to determine the last time a git repository was updated, I set its modification date to the latest's commit one. Using --format=%ai would be better (ISO 8601), but busybox' touch doesn't support it, so %as (YYYY-MM-DD) has to suffice. The script is called via the git's user crontab every day.

For private repositories on github, I generated a per-repo personal access token and cloned each of them via git clone --mirror https://jvoisin:github_pat_…@github.com/jvoisin/my_secret_repo. Preventing them from being listed on the web interface is done by putting a cgitrc file with hide=1 or ignore=1 at their root depending of what you prefer.

You can see the result on git.dustri.org.