As a followup for Mercurial: enforce "hg pull -u" before "hg commit"
I have started to use a hook
[hooks]
pretxnchangegroup.forbid_2heads = /usr/local/bin/forbid_2head.sh
where forbid_2head.sh looks like this
#!/bin/bash
BRANCH=`hg branch`
COUNT=`hg heads --template '{branch}|{rev}\n' | grep ^${BRANCH} | wc -l`
if [ "$COUNT" -ne "1" ] ; then
echo "=========================================================="
echo "Trying to push more than one head, which is not allowed"
echo "You seem to try to add changes to an old changeset!"
echo "=========================================================="
exit 1
fi
exit 0
It is derivative of the script found at http://tutorials.davidherron.com/2008/10/forbidding-multiple-heads-in-shared.html
where I do allow multiple named branches.
The problem I have now is that
- it stops hg push -f which is what I wanted
- it also stops hg pull in case there are incoming changeset and I have commits outgoing. This is indeed bad
Can I in any way reuse the same script but change the hook setup and stop “hg push -f”?
Or can I in forbid_2head.sh know whether this is a push or pull command running?
First, the script isn’t completely correct: it just counts the number of heads in the branch currently checked out on the server (the one
hg branch) reports. You could improve it by usingto get the heads of the branch of
tip. But someone might push changesets on more than one branch at a time, so what you really want isto find branch heads for the branches touched by
$HG_NODE:tip(the changesets pushed in the not-yet-committed transaction). You can then compare that withwhich are the branches touched by the changegroup.
If you don’t want to allow existing multiple heads, then you can simplify the above to just
which just tests that the number of branch heads is equal to the number of branches — i.e., that there is exactly one branch head per named branch.
With that out of the way, let me mention
$HG_SOURCE. That environment variable is set by Mercurial when it runs the hook: it has the valuepushif the changegroup is being pushed into the repository using direct filesystem access, and the valueserveif the changegroup is coming in over SSH or HTTP. See the Mercurial book.So, to conclude, I believe this is a good “forbid multiple heads” script: