#require bash Test that, when an hg push is interrupted and the remote side receives SIGPIPE, the remote hg is able to successfully roll back the transaction. $ hg init -q remote $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" -q ssh://user@dummy/`pwd`/remote local $ pidfile=`pwd`/pidfile $ >$pidfile $ script() { > cat >"$1" > chmod +x "$1" > } On the remote end, run hg, piping stdout and stderr through processes that we know the PIDs of. We will later kill these to simulate an ssh client disconnecting. $ killable_pipe=`pwd`/killable_pipe.sh $ script $killable_pipe < #!/usr/bin/env bash > echo \$\$ >> $pidfile > exec cat > EOF $ remotecmd=`pwd`/remotecmd.sh $ script $remotecmd < #!/usr/bin/env bash > hg "\$@" 1> >($killable_pipe) 2> >($killable_pipe >&2) > EOF In the pretxnchangegroup hook, kill the PIDs recorded above to simulate ssh disconnecting. Then exit nonzero, to force a transaction rollback. $ hook_script=`pwd`/pretxnchangegroup.sh $ script $hook_script < #!/usr/bin/env bash > for pid in \$(cat $pidfile) ; do > kill \$pid > while kill -0 \$pid 2>/dev/null ; do > sleep 0.1 > done > done > exit 1 > EOF $ cat >remote/.hg/hgrc < [hooks] > pretxnchangegroup.00-break-things=$hook_script > pretxnchangegroup.01-output-things=echo "some remote output to be forward to the closed pipe" > EOF $ hg --cwd ./remote tip -T '{node|short}\n' 000000000000 $ cd local $ echo foo > foo ; hg commit -qAm "commit" $ hg push -q -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" --remotecmd $remotecmd 2>&1 | grep -v $killable_pipe abort: stream ended unexpectedly (got 0 bytes, expected 4) The remote should be left in a good state $ hg --cwd ../remote tip -T '{node|short}\n' 000000000000 $ hg --cwd ../remote recover no interrupted transaction available [1]