[PATCH 2 of 9 V2] localrepo: use changelog.rev instead of self.__contains__
Yuya Nishihara
yuya at tcha.org
Sun May 3 10:17:40 UTC 2015
On Sun, 03 May 2015 00:59:37 +0900, FUJIWARA Katsunori wrote:
> # HG changeset patch
> # User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
> # Date 1430582197 -32400
> # Sun May 03 00:56:37 2015 +0900
> # Node ID ea0832f5425148072ca048997fb322615e90e805
> # Parent fac0b879377d014c4081940040d092469635447a
> localrepo: use changelog.rev instead of self.__contains__
>
> Before this patch, releasing store lock implies actions below, when
> 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 sotre lock:
> resouces are acquired in "wlock => dirstateguard => store lock" order,
> and are released in reversed order.
>
> This may cause that "dirstate.p1()" still refers the changeset to be
> rollback-ed at (4) above: pushing multiple patches by "hg qpush" is
> typical case.
>
> At releasing store lock, such changesets are:
>
> - not contained in "repo.changelog", if it is reloaded from
> ".hg/00changelog.i" 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". It prevents tests from running stably.
>
> 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 "unknown working parent" warning irregularly, this
> patch uses "changelog.rev()" instead of "node in self" to examine
> existence of committed changeset.
>
> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -1521,9 +1521,12 @@
> def commithook(node=hex(ret), parent1=hookp1, parent2=hookp2):
> # hack for command that use a temporary commit (eg: histedit)
> # temporary commit got stripped before hook release
> - if node in self:
> + try:
> + self.changelog.rev(ret) # check existence
> self.hook("commit", node=node, parent1=parent1,
> parent2=parent2)
> + except error.LookupError:
> + pass # changeset is already rollback-ed
Nit pick: perhaps changelog.hasnode() can be used here.
More information about the Mercurial-devel
mailing list