cgit & gitolite
I've just finished to configure gitolite and cgit to manage some git repos of mine (and friends), so I'm posting here the setup before forgetting the details.
The final result is a git server with both a web view, HTTP clone and ssh for you and your users.
It requires more work than, say, gitea or gitlab, and has a few moving parts. Nevertheless, it's a modular solution (you can replace cgit with gitweb for instance) and it does not have obnoxious web guis to manage things. The whole gitolite config is itself a git repository, so you can use the tools you're familiar with (a bit of ssh, git and your preferred $EDITOR
) to build and maintain your own git server.
gitolite
Install gitolite, it's easy. Follow the installation guide. I've done that on a new user called "git". This will create two repos in ~git/repositories
: gitolite-admin
and testing
. With the default configuration testing will be read-write for all users (in the gitolite sense).
You should import your own ssh public key. Try to clone the gitolite-admin
repo with git clone git@your.own.host:gitolite-admin
to test the setup and, eventually, add more users and repos.
cgit
I'm using nginx plus fcgiwrap on a FreeBSD system, but other options are available. (For instance, if you're using OpenBSD than you have httpd and slowcgi already in base.)
For reference, my configuration file is /usr/local/etc/cgit-op.conf
and contains:
css=/mine.css
logo=/logo.png
head-include=/usr/local/lib/cgit/theme/head.html
enable-http-clone=1
enable-index-links=1
remove-suffix=1
enable-commit-graph=1
enable-log-filecount=1
enable-git-config=1
source-filter=/usr/local/lib/cgit/filters/syntax-high.py
about-filter=/usr/local/lib/cgit/filters/about-formatting.sh
virtual-root=/
enable-index-links=1
enable-index-owner=0
snapshots=tar.gz tar.bz2
root-title=Stuff
root-desc=some git repos of mine
local-time=1
# path to the root about file
#root-readme=/usr/local/lib/cgit/theme/about.html
# search for these files in the root fo the default branch
readme=:README.md
readme=:readme.md
readme=:README.mkd
readme=:readme.mkd
readme=:README.rst
readme=:readme.rst
readme=:README.html
readme=:readme.html
readme=:README.htm
readme=:readme.htm
readme=:README.txt
readme=:readme.txt
readme=:README
readme=:readme
readme=:INSTALL.md
readme=:install.md
readme=:INSTALL.mkd
readme=:install.mkd
readme=:INSTALL.rst
readme=:install.rst
readme=:INSTALL.html
readme=:install.html
readme=:INSTALL.htm
readme=:install.htm
readme=:INSTALL.txt
readme=:install.txt
readme=:INSTALL
readme=:install
scan-path=/home/git/repositories
The important bits of all of these are only:
enable-git-config=1
and
scan-path=/home/git/repositories
The first let us configure per-repo cgit options via the standard git config file, while the second lets cgit discovers the repos by searching in that path.
If you're curious, I used head-include
to add some <meta>
tags and modified the default CSS to render the pages decently on mobile screens. More work is needed.
Note about permissions
You are probably running cgit with the www
user and gitolite with the git
user so you have a permission problem. While you can do fancy stuff with mount_nullfs
/mount --bind
and whatnot or by changing the default path for the repositories, I didn't want to.
I'm still not sure if this is the best way to handle things, but I made fcgiwrap use the git
user with
fcgiwrap_user="git"
in /etc/rc.conf
plus a manual chown(8)
on the socket. Now cgit and gitolite are run by the same user. Problem solved.
hide some repositories!
This was the basic setup to have cgit display the repositories managed by gitolite, as well as having both public HTTP and authenticated ssh clone. Pretty neat.
But, you have no way (still) to hide some repositories. For instance, the gitolite-admin
repositorie is public readable (not writable). It may be fine for you, but I wanted a way to have private repositories, while still having the repos managed by gitolite.
If you set enable-git-config
in cgit configuration file, now you can control some cgit per-repo options via ~git/repositories/$REPO/config
. You can create a section that looks like this:
[cgit]
ignore = 1
to make cgit ignore that repo. Check the documentation of cgit for the list of parameters you can set.
But it's tedious and needs manual work per-repo. That's something that needs to be automatized.
Fortunately, gitolite lets us set git configurations via the gitolite.conf
file. You first need to set GIT_CONFIG_KEYS
to '.*'
in ~git/.gitolite.rc
. (.*
is the broader, probably cgit.*
is enough, haven't tested tho).
Now, in your gitolite.conf
you can
repo gitolite-admin
config cgit.ignore=1
and BOOM, it's hidden and unreachable via cgit (both via web and http clone).
But (there are too many 'but' in this section, hu?) we can do even better:
@hiddenrepos = gitolite-admin
@hiddenrepos = private-stuff
@hiddenrepos = next-gen-revolutionary-stuff
repo @hiddenrepos
config cgit.ignore=1
to bulk-hide repositories.
Neat.