[PATCH 2 of 9 V2] localrepo: use changelog.rev instead of self.__contains__

Yuya Nishihara yuya at tcha.org
Sun May 3 05:17:40 CDT 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