Categories
SysAdmin

Cloning Mercurial repos with a server-side hook

I use mercurial for my personal projects. I run mercurial-server. I wanted to have a hook on the server that would clone the repository so additional tasks could be performed against the contents of the repository without affecting the server’s repository.

I started by creating a hook script at /var/lib/mercurial-server/repos/somerepo/.hg/push-hook.sh:

#!/bin/bash

PUSH_COPY="/var/lib/mercurial-server/checkout-for-push/somerepo"
if ! [ -d $PUSH_COPY ] ; then
echo "CLONE: $PUSH_COPY"
/usr/bin/hg clone /var/lib/mercurial-server/repos/somerepo $PUSH_COPY
else
echo "UPDATE: $PUSH_COPY"
/usr/bin/hg pull -R $PUSH_COPY -v -u
fi

echo "do more work here..."

Then I added the following to /var/lib/mercurial-server/repos/somerepo/.hg/hgrc:

[hooks]
changegroup = /var/lib/mercurial-server/repos/somerepo/.hg/push-hook.sh

This got me to the point of being able to check out the server repository but updating it failed with the following message:

remote: UPDATE: /var/lib/mercurial-server/checkout-for-push/somerepo
remote: pulling from /var/lib/mercurial-server/repos/somerepo
remote: searching for changes
remote: 2 changesets found
remote: adding changesets
remote: calling hook outgoing.aaaaa_servelog: mercurialserver.servelog.hook
remote: transaction abort!
remote: rollback completed
remote: abort: outgoing.aaaaa_servelog hook is invalid (import of "mercurialserver.servelog" failed)

After a lot of digging and Google searches, I wasn’t coming up with any answers. One person mentioned that an environment variable may be set wrong, causing errors. Once I dumped the environment variables out, I unset each one at a time to see if any were causing problems. I ended up needing to add unset HGRCPATH to the top of the hook script before any hg commands run. So my push script now looks like:

#!/bin/bash
unset HGRCPATH

PUSH_COPY="/var/lib/mercurial-server/checkout-for-push/somerepo"
if ! [ -d $PUSH_COPY ] ; then
echo "CLONE: $PUSH_COPY"
/usr/bin/hg clone /var/lib/mercurial-server/repos/somerepo $PUSH_COPY
else
echo "UPDATE: $PUSH_COPY"
/usr/bin/hg pull -R $PUSH_COPY -v -u
fi

echo "do more work here..."

And the output of a push command now looks a lot better:

pushing to ssh://hg@hg.example.com/somerepo
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
remote: UPDATE: /var/lib/mercurial-server/checkout-for-push/somerepo
remote: pulling from /var/lib/mercurial-server/repos/somerepo
remote: searching for changes
remote: 3 changesets found
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 3 changesets with 3 changes to 2 files
remote: resolving manifests
...