[PATCH 5 of 5] localrepo: check HG_PENDING strictly

Augie Fackler raf at durin42.com
Tue Feb 21 11:16:52 EST 2017


On Tue, Feb 21, 2017 at 01:28:04AM +0900, FUJIWARA Katsunori wrote:
> # HG changeset patch
> # User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
> # Date 1487607660 -32400
> #      Tue Feb 21 01:21:00 2017 +0900
> # Node ID 0eebac024d47de9c94968f49bc9a0dcb2c8d3d2b
> # Parent  f307ed0b262616d31c43eb1e3655a21b1d90865c
> localrepo: check HG_PENDING strictly

Queued these, very nice centralization of the pending logic into a single place.

Do you think we should consolidate other transaction-related bits into
txnutil? Might let us have a bit more tidy organization of things.

>
> Before this patch, checking HG_PENDING for changelog in localrepo.py
> might cause unintentional reading unrelated '00changelog.i.a' in,
> because HG_PENDING is checked by str.startswith().
>
> An external hook spawned by inner repository in nested ones satisfies
> this condition.
>
> This patch uses txnutil.mayhavepending() to check HG_PENDING strictly.
>
> BTW, this patch may cause failure of bisect in the repository of
> Mercurial itself, if examination at bisecting assumes that an external
> hook can see all pending changes while nested transactions across
> repositories.
>
> This invisibility issue will be fixed by subsequent patch, which
> allows HG_PENDING to refer multiple repositories.
>
> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -55,6 +55,7 @@ from . import (
>      subrepo,
>      tags as tagsmod,
>      transaction,
> +    txnutil,
>      util,
>  )
>
> @@ -512,10 +513,8 @@ class localrepository(object):
>      @storecache('00changelog.i')
>      def changelog(self):
>          c = changelog.changelog(self.svfs)
> -        if 'HG_PENDING' in encoding.environ:
> -            p = encoding.environ['HG_PENDING']
> -            if p.startswith(self.root):
> -                c.readpending('00changelog.i.a')
> +        if txnutil.mayhavepending(self.root):
> +            c.readpending('00changelog.i.a')
>          return c
>
>      def _constructmanifest(self):
> diff --git a/tests/test-hook.t b/tests/test-hook.t
> --- a/tests/test-hook.t
> +++ b/tests/test-hook.t
> @@ -832,6 +832,50 @@ pretxnclose hook failure should abort th
>    [1]
>    $ cd ..
>
> +check whether HG_PENDING makes pending changes only in related
> +repositories visible to an external hook.
> +
> +(emulate a transaction running concurrently by copied
> +.hg/store/00changelog.i.a in subsequent test)
> +
> +  $ cat > $TESTTMP/savepending.sh <<EOF
> +  > cp .hg/store/00changelog.i.a  .hg/store/00changelog.i.a.saved
> +  > exit 1 # to avoid adding new revision for subsequent tests
> +  > EOF
> +  $ cd a
> +  $ hg tip -q
> +  4:539e4b31b6dc
> +  $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" commit -m "invisible"
> +  transaction abort!
> +  rollback completed
> +  abort: pretxnclose hook exited with status 1
> +  [255]
> +  $ cp .hg/store/00changelog.i.a.saved .hg/store/00changelog.i.a
> +
> +(check (in)visibility of new changeset while transaction running in
> +repo)
> +
> +  $ cat > $TESTTMP/checkpending.sh <<EOF
> +  > echo '@a'
> +  > hg -R $TESTTMP/a tip -q
> +  > echo '@a/nested'
> +  > hg -R $TESTTMP/a/nested tip -q
> +  > exit 1 # to avoid adding new revision for subsequent tests
> +  > EOF
> +  $ hg init nested
> +  $ cd nested
> +  $ echo a > a
> +  $ hg add a
> +  $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" commit -m '#0'
> +  @a
> +  4:539e4b31b6dc
> +  @a/nested
> +  0:bf5e395ced2c
> +  transaction abort!
> +  rollback completed
> +  abort: pretxnclose hook exited with status 1
> +  [255]
> +
>  Hook from untrusted hgrc are reported as failure
>  ================================================
>
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


More information about the Mercurial-devel mailing list