comparison tests/test-mq-qpush-fail.t @ 24992:7df090c9c9fe

localrepo: use changelog.hasnode instead of self.__contains__ Before this patch, releasing the store lock implies the actions below, when the transaction is aborted: 1. "commithook()" scheduled in "localrepository.commit()" is invoked 2. "changectx.__init__()" is invoked via "self.__contains__()" 3. specified ID is examined against "repo.dirstate.p1()" 4. validation function is invoked in "dirstate.p1()" In subsequent patches, "dirstate.invalidate()" invocations for discarding changes are replaced with "dirstateguard", but discarding changes by "dirstateguard" is executed after releasing the store lock: resources are acquired in "wlock => dirstateguard => store lock" order, and are released in reverse order. This may cause that "dirstate.p1()" still refers to the changeset to be rolled-back at (4) above: pushing multiple patches by "hg qpush" is a typical case. When releasing the store lock, such changesets are: - not contained in "repo.changelog", if it is reloaded from ".hg/00changelog.i", as that file was already truncated by "transaction.abort()" - still contained in it, otherwise (this "dirty read" problem is discussed in "Transaction Plan" http://mercurial.selenic.com/wiki/TransactionPlan) Validation function shows "unknown working parent" warning in the former case, but reloading "repo.changelog" depends on the timestamp of ".hg/00changelog.i". This causes occasional test failures. In the case of scheduled "commithook()", it just wants to examine whether "node ID" of committed changeset is still valid or not. Other examinations implied in "changectx.__init__()" are meaningless. To avoid showing the "unknown working parent" warning irregularly, this patch uses "changelog.hasnode()" instead of "node in self" to examine existence of committed changeset.
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Thu, 07 May 2015 12:07:10 +0900
parents 9b02b678888e
children 30657909b2ba
comparison
equal deleted inserted replaced
24991:4169a4f83548 24992:7df090c9c9fe
32 popping patch1 32 popping patch1
33 patch queue now empty 33 patch queue now empty
34 $ $PYTHON -c 'print "\xe9"' > message 34 $ $PYTHON -c 'print "\xe9"' > message
35 $ cat .hg/patches/bad-patch >> message 35 $ cat .hg/patches/bad-patch >> message
36 $ mv message .hg/patches/bad-patch 36 $ mv message .hg/patches/bad-patch
37 $ hg qpush -a && echo 'qpush succeeded?!' 37 $ cat > $TESTTMP/wrapplayback.py <<EOF
38 > import os
39 > from mercurial import extensions, transaction
40 > def wrapplayback(orig,
41 > journal, report, opener, vfsmap, entries, backupentries,
42 > unlink=True):
43 > orig(journal, report, opener, vfsmap, entries, backupentries, unlink)
44 > # Touching files truncated at "transaction.abort" causes
45 > # forcible re-loading invalidated filecache properties
46 > # (including repo.changelog)
47 > for f, o, _ignore in entries:
48 > if o or not unlink:
49 > os.utime(opener.join(f), (0.0, 0.0))
50 > def extsetup(ui):
51 > extensions.wrapfunction(transaction, '_playback', wrapplayback)
52 > EOF
53 $ hg qpush -a --config extensions.wrapplayback=$TESTTMP/wrapplayback.py && echo 'qpush succeeded?!'
38 applying patch1 54 applying patch1
39 applying patch2 55 applying patch2
40 applying bad-patch 56 applying bad-patch
41 transaction abort! 57 transaction abort!
42 rollback completed 58 rollback completed