Setting up a local GitHub mirror with cgit, gh-mirror, and git daemon
I just finished setting up a local GitHub mirror so that I can have a local
copy of my GitHub repositories on this server at all times. I figured since I
have them here, I might as well also make them available to the public on this
server. This post covers setting up the mirroring (using
gh-mirror), a web interface (using cgit through
nginx), and a clone interface (using git-daemon).
Setting up cgit
Replace “git.chrisdown.name” with the server you will be running git-daemon on.
If everything went well, executing /srv/http/cgit/cgit.cgi should output some
Setting up nginx
Replace “git.chrisdown.name” with your domain.
You should now get a cgit page at git.chrisdown.name that proudly displays “no
repositories found” (assuming you have no repositories in /srv/git already).
I wrote a script called gh-mirror that takes care of most of the
work for you.
This will mirror from GitHub every 5 minutes. Replace “cdown” with your
In the next 5 minutes, you should see your public repositories on cgit.
You can also optionally initialise the last modified time to the time of the
last commit for each repository so that they don’t all display the time at
which you first cloned for repos that you no longer commit to – here’s a
little script I wrote. The source shows that if it fails to find
info/web/last-modified, then head/refs/[default branch], then it looks at
packed-refs. As such, we update the mtime of packed-refs to match the time of
the last commit.
You’ll want to have an init script to run git-daemon. I wrote this one up, I
don’t know if it’s totally compliant with the Debian packaging guidelines, but
I tried to follow it as closely as I could.