A simple, powerful self-hosted git setup
I had been using gogs for about a year. It worked reasonably well, as it focuses on being a lightweight self-hosted GitHub replacement. However, that wasn’t really what I wanted. I just wanted to host my own projects, I didn’t need things like issues, pull requests or wikis.
I recently switched to gitolite and cgit, as they were even lighter on resources, don’t require another login and work without an external database. Gitolite is unusual in its configuration: it creates a git repository with its configuration file. I will describe how I use them, rather than how to set them up, as they both have enough documentation on that.
My gitolite configuration file looks like this:
repo gitolite-admin
RW+ = alan
repo dotfiles
C = alan
RW+ = alan
R = READERS
option hook.post-update = github-mirror
repo [a-z].*
C = alan
RW+ = CREATOR
RW = WRITERS
R = READERS
The first block just allows me to work with the configuration repository, as the initial setup only enables one specific public SSH key, whereas I have three keys that I configure gitolite with.
The second configures my dotfiles specifically. Naturally, I should
be the only person with read/write access. The R = READERS
line
allows remote configuration of read permissions via ssh $DOMAIN perms
(explained further below). The last line runs a mirror script
(just git push --mirror…
) so that
my dotfiles repository on GitHub is updated when I
push to my private version.
Wild (or magic) repositories
The third block is where things get interesting. gitolite has a feature called wildrepos, which allows configuring a set of repositories at once, using a regular expression to match the repository name.
The really nice thing here is that the repository need not exist
before applying the configuration. Therefore, the line C = alan
means that I can create a remote repository automatically by cloning a
repository URL that doesn’t already exist.
I can clone and create a new repo simultaneously like so:
cd ~/projects
git clone alanpearce.eu:some-new-repository
But with ghq, which I blogged about before, I don’t have to concern myself with where to put the repository:
$ ghq get alanpearce.eu:some-new-repository
clone ssh://alanpearce.eu/some-new-repository -> /Volumes/Code/projects/alanpearce.eu/some-new-repository
git clone ssh://alanpearce.eu/some-new-repository /Volumes/Code/projects/alanpearce.eu/some-new-repository
Cloning into '/Volumes/Code/projects/alanpearce.eu/some-new-repository'...
Initialized empty Git repository in /var/lib/gitolite/repositories/some-new-repository.git/
warning: You appear to have cloned an empty repository.
The nice URLs come from this piece of my SSH configuration:
Host alanpearce.eu
HostName git.alanpearce.eu
User gitolite
Configuring wild repositories
This repository would be private by default, but I can change that by an SSH command. Here’s how I would do it:
ssh alanpearce.eu perms some-new-repository + READERS gitweb
ssh alanpearce.eu perms some-new-repository + READERS daemon
The first command makes it visible in cgit, whilst the second makes it
clonable via git://
url. I can make a repository
publically-clonable, but invisible on cgit by only allowing the daemon
user and not gitweb
, if I wanted.
I can also add or change the description of a repository shown on cgit like so:
ssh alanpearce.eu desc some-new-repository 'A new repository'
All the remote commands exposed by gitolite are described in the
help
command e.g. ssh alanpearce.eu help
hello alan, this is gitolite@oak running gitolite3 (unknown) on git 2.12.2
list of remote commands available:
D
desc
help
info
motd
perms
writable
Conclusion
I much prefer creating repositories in this way. It’s much simpler and allows me to get on with working on the repositories rather than going through a multi-step process in a web browser.
With cgit and gitolite, I have a minimal setup, that does exactly what I want, without consuming many system resources with daemons.