# HG changeset patch
# User FUJIWARA Katsunori <fo...@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

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@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Reply via email to