Sunday, January 30, 2011

Running Mercurial hg serve on Linux, allowing push

In a previous post I showed how to run "hg serve" on Windows.  I then tried the same approach on Linux, and things did not quite work the same.

After much tinkering, here is my recipe for running on Linux.

1) Create a directory called /var/hg


2) Create a file called /var/hg/hg.conf with the following content -- this peculiar directive states  all subdirectories of /var/hg/repos are treated as repositories and can be accessed directly using the subdirectory name (e.g. /var/hg/repos/myrepo is accessed as myrepo).


[collections]
/var/hg/repos = /var/hg/repos


3) Create a directory called /var/hg/repos -- this is where you will create the repositories


4)  Create a repository as follows (repeat for any repository you want to create).
cd /var/hg/repos
mkdir myrepo
cd myrepo
hg init


5) Edit /etc/mercurial/hgrc and add the following lines to allow pushing

[web]
push_ssl = false
allow_push = *

6) Create a file /etc/init.d/hg.init and make it executable (chmod a+x) with the following contents

#!/bin/sh
#
# Startup script for mercurial server.
#
# Change following ines
APP_BIN=/usr/bin/hg
SRC=/var/hg
SRCNAME=" package source"
# Path to PID file of running mercurial process.
PID_FILE=${SRC}/hg.pid


state=$1

case "$state" in
'start')
    echo "Mecurial Server service starting."
   (cd ${SRC} ;${APP_BIN} serve -d --webdir-conf ${SRC}/hg.conf -p 8000 --pid-file ${PID_FILE})
  ;;

'stop')
  if [ -f "${PID_FILE}" ]; then
    PID=`cat "${PID_FILE}"`
    if [ "${PID}" -gt 1 ]; then
      kill -TERM ${PID}
      echo "Stopping the Mercurial service PID=${PID}."
    else
      echo Bad PID for Mercurial -- \"${PID}\"
    fi
  else
    echo No PID file recorded for mercurial
  fi
  ;;

*)
  echo "$0 {start|stop}"
  exit 1
  ;;
esac



7) You can now start the server (the -p 8000 parameter in the script makes it listen on port 8000)
/etc/init.d/hg.init start

Wednesday, January 26, 2011

Running a simple Mercurial server (hg serve) and allowing push

I've been using mercurial (via Google Code Repository) as a simple solution for version control. The best feature is that Mercurial (hg for short) allows me to commit things to the repository that no-one else sees until I "push" them out (committing and pushing are two separate operations).

Lately I've had a need to quickly share code for an internal, non-FOSS project.  Running an internal hg server seems, at first glance, much harder than for SVN or CVS : while there is a simple "hg serve" command, the documentation is sparse, and in fact misleading.  The documentation would have you believe that hg serve is read-only, whereas it is not.  There are a few tricks required to run it as a cheap solution just for sharing between colleagues and avoiding the "oops, lost my laptop" issues.

First, run the program in daemon mode, and force it to read a config file:
hg serve -d --web-config E:\hg\config.txt


The following configuration file (config.txt in the command-line above) allows you a)  to have multiple repositories b) enables your colleagues to push changes and c) does not require an SSL connection.


[collections]
e:\hg = e:\hg


[web]
allow_push = *
push_ssl = false

Obviously, the setup is insecure, and is meant for private LANs or VPNs -- anything sensitive should use the more tedious solutions that rely on Apache and SSL.