I like Mercurial, aka hg - it is lightweight and stays mostly out of my way. I plan to install GitLab, but first I will set up a Mercurial server, which is quick. See Mercurial Publishing Repositories. I tested this on Ubuntu 16.04.

I chose \var\www\mercurial as the server directory, repos as repository directory and set up an empty test repository:

mkdir -p mercurial\repos
hg init mercurial\repos
sudo chown -R www-data:www-data mercurial 

Edited /etc/mercurial/hgrc to trust Apache user, allow pushing and archives. Perhaps I will enable push_ssl later.

# system-wide mercurial configuration file
# See hgrc(5) for more information
allow_push = *
push_ssl = false
allow_archive = gz, zip, bz2
users = www-data

I am going to use CGI for now, even though performance should be much better with WSGI. Copied an example hgweb.cgi sudo cp /usr/share/doc/mercurial/examples/hgweb.cgi /var/www/mercurial, made it executable and edited the config file reference config = "/var/www/mercurial/hgweb.config"


style = gitweb
encoding = "UTF-8"
# ** allows descending into sub-repos
repos = /var/www/mercurial/repos/**
# Can add more repositories here

Now I want to add ScriptAlias /hg to site config. Instead of editing sites-available it is better to follow the DRY principle and have a common config conf-available/hg.conf, and enabled globally with sudo a2enconf hg. This should work for all my sites, in my case HTTP and HTTPS. Needless to say, my *.conf files are versioned with hg.


# Config file for Mercurial server
ScriptAlias /hg "/var/www/mercurial/hgweb.cgi"
<Directory "/var/www/mercurial">
   AuthType Digest
   AuthName "Mercurial"
   AuthDigestProvider file
   AuthUserFile /var/www/mercurial/.hgusers
   Require valid-user

Then I created .hgusers with htdigest -c .hgusers Mercurial <user>.

I had to enable auth_digest module (Apache was coughing on AuthType Digest) and cgi (Apache was serving script as text instead of executing it). Checked with systemctl status apache2.service and journalctl -u apache2.service,

# a2enmod auth_digest cgi
# service apache2 restart

After testing both http://<my-server>/hg and https://<my-server>/hg I redirected the HTTP site to HTTPS. It is not clear to me if I need [R,L] rewrite flags (redirect and last), it seems to work well without them.

# Redirect to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{SERVER_NAME}%{REQUEST_URI}  
# [R,L] - redirect and last flags. Needed?

The corresponding hgrc in the client repo is as follows (xy - some prefix):

xy.prefix = https://<my-server>/hg/repo/xyz
xy.username = <user>
xy.password = <pass>

Update: As my repo grew bigger (several MBs now), I switched to WSGI to improve performance - everything is much, much faster.

# cp /usr/share/doc/mercurial/examples/hgweb.wsgi /var/www/mercurial
# chmod a+x hgweb.wsgi
# apt install libapache2-mod-wsgi

Edit the config line in hgweb.wsgi. The corresponding ScriptAlias is now:

#ScriptAlias /hg "/var/www/mercurial/hgweb.cgi"
WSGIScriptAlias /hg "/var/www/mercurial/hgweb.wsgi"

Update 2: I have also installed gitweb and git-http-backend. I created a test repo in /var/www/git/repos/test first

$ sudo apt install gitweb
$ sudo su -s /bin/bash www-data
$ mkdir -p /var/www/git/repos/test
$ git init /var/www/git/repos/test

I wanted to include some git repos explicitly and from all over my server, so I added some links under /var/www/git/repos. They need to be writeable by www-data. I also enabled blame, pickaxe and snapshot features in /etc/gitweb.conf:

$projectroot = "/var/www/git/repos";
$projects_list = $projectroot;
$site_name = "My git";
$feature{'blame'}{'default'} = [1];
$feature{'blame'}{'override'} = 1;
$feature{'pickaxe'}{'default'} = [1];
$feature{'pickaxe'}{'override'} = 1;
$feature{'snapshot'}{'default'} = ['zip', 'tgz'];
$feature{'snapshot'}{'override'} = 1;

At first I protected gitweb with AuthType Digest, but it does not work for git (see below) and obviously I wanted to have the same users for both, so I went for AuthType Basic in /etc/apache2/conf-available/gitweb.conf:

<Directory /usr/share/gitweb>
    Options +FollowSymLinks +ExecCGI
    AddHandler cgi-script .cgi
    AuthType Basic
    AuthName "Git"
    AuthUserFile /var/www/git/.htpasswd
    Require valid-user

For pull/push access I created and enabled git-http-backend with /etc/apache2/conf-available/git.conf. It seems git curl does not play well with digest auth. I got errors AH01788: realm mismatch - got '' but expected 'Git' and found no way to specify empty realm with AuthName. According to github msysgit discussion I could have specified realm\username as username, but I went for basic auth instead and created users with htpasswd -c <user>. I think it is good enough with SSL. Here my git.conf:

SetEnv GIT_PROJECT_ROOT /var/www/git/repos

ScriptAlias /git/ /usr/lib/git-core/git-http-backend/

<Directory "/usr/lib/git-core/">
        AuthType Basic
        AuthName "Git"
        AuthUserFile /var/www/git/.htpasswd
        Require valid-user

Add a comment

Next Post Previous Post