Forbidding multiple heads in a shared mercurial repository

Date: Wed Sep 20 2017 Mercurial

One of the issues with correctly configuring a shared mercurial repository is to prevent there being multiple heads in the shared repository. Multiple heads? Does that sound like Zaphod Beeblebrox? Maybe, maybe not. In Mercurial history can be a convoluted thing, just like in real life. The series of changes a team has in hand may end up at a place where there are multiple lines of history. A head revision is one which does not have any children, that is a head revision is one from which no further revisions have been made. There is always at least one head revision, that's the tip. But there may be multiple heads.

For many reasons it is bad practice for a shared repository to have multiple heads. Doing a push from a repository that contains multiple heads also makes the repository into which the push lands also have multiple heads.

The merge command gets rid of multiple heads. And you can prune dead branches by pretending to be a virtual arborist. But for the shared repository it's better to avoid them in the first place.

One method is the following hgrc configuration

[hooks]
pretxnchangegroup.forbid_2heads = /path/to/forbid_2head.sh

The hook calls this shell script

% cat /path/to/forbid_2head.sh
#!/bin/bash
COUNT=`hg heads | grep "^changeset:" | wc -l`
if [ "$COUNT" -ne "1" ] ; then
echo "=========================================================="
echo "Trying to push more than one head, try run "hg merge" before it"
echo "=========================================================="
exit 1
fi
exit 0