Title: Mirroring my git repositories
Date: 2025-04-02 16:00

Since [everything is going downhill on the internet](https://en.wikipedia.org/wiki/Enshittification),
I spent some time mirroring some of my git repositories on a machine at home.
I chose [cgit](https://git.zx2c4.com/cgit/about/) 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:

```nginx
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](https://git.zx2c4.com/cgit/tree/cgitrc.5.txt) for `cgit` is
also super-simple:

```ini
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:

```sh
#!/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](https://en.wikipedia.org/wiki/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](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)
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](https://git.dustri.org/).
