bashmercurialmercurial-hook

How do I write a hook around mercurial's "push creates new remote head"?


I want to make a hook that when someone is pushing to the remote, if they get the abort: push creates new remote head error message, the hook will try to merge the remote and local head (if easy merge i.e. no conflicting files) and push again.

How can I do this? I tried adding a hook on pre-push, but I don't know how to get just the remote's head hash for the current branch.

Here is what I have been trying, though it is not polished.

currbranch=$(hg branch)
hg pull
numheads=$(hg heads --template "." $currbranch)
if test ${#numheads} -gt 1; then
    echo "Merge needed."
    head1=$(hg heads --template "{node}\n" $currbranch | head -n 1)
    head2=$(hg heads --template "{node}\n" $currbranch | tail -n 1)
    overlap=$((hg status --change $head1 --no-status ; hg status --change $head2 --no-status) | sort | uniq --repeated)
    if [ -z "$overlap" ]; then
        echo "Attempting automatic merge..."
        hg merge "$head1"  # Fails when merging the wrong head
        hg merge "$head2"  # But how do we know which one is wrong?
        hg commit -m "Merge"
        echo "Completed."
    else
        echo "Cannot automatically merge"
        exit 1
    fi
fi

To be clear, what doesn't work ahead is merging both heads. How can I know which head is local and which head is remote?

Also, is this the right hook to use?


Solution

    1. You can try to add and use remotenames extension (it's rather old and not actively maintained since 2018, but may work) in order to have all remote peers named in your repo (in this case you'll know names of remote head(s) after pull)
    2. You can (before pull) check presence of head in incoming set of changesets, smth. like

    hg in -r "head()" -T "{node|short}\n" (TBT!)