changeset 27291:a18328aad48c

commit: make commit acquire store lock before processing for consistency If acquisition of wlock waits for another "hg commit" process to release it, dirstate will refer newly committed revision after acquisition of wlock. At that time, '00changelog.i' on the filesystem contains this new revision, but in-memory 'repo.changelog' doesn't, if it is cached without store lock (slock) before updating by another "hg commit". This makes validating parents at re-loading 'repo.dirstate' from '.hg/dirstate' replace such new revision with 'nullid'. Then, 'localrepository.commit()' creates "orphan" revision (see issue4368 for detail). a01d3d32b53a makes 'commands.commit()' acquire both wlock and slock before processing to avoid this issue at "hg commit". But similar issue can occur even after a01d3d32b53a, if 3rd party extension does: - refer 'repo.changelog' outside wlock scope, and - invoke 'repo.commit()' directly (instead of 'commands.commit()') This patch makes 'commit()' acquire slock before processing, to refer recent changelog at validating parents of 'repo.dirstate'.
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Wed, 09 Dec 2015 08:28:53 +0900
parents 525d9b3f0a31
children 14a83e8e1b88
files mercurial/localrepo.py
diffstat 1 files changed, 2 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/localrepo.py	Wed Dec 09 08:28:53 2015 +0900
+++ b/mercurial/localrepo.py	Wed Dec 09 08:28:53 2015 +0900
@@ -1471,6 +1471,8 @@
         wlock = lock = tr = None
         try:
             wlock = self.wlock()
+            lock = self.lock() # for recent changelog (see issue4368)
+
             wctx = self[None]
             merge = len(wctx.parents()) > 1
 
@@ -1598,7 +1600,6 @@
                 subrepo.writestate(self, newstate)
 
             p1, p2 = self.dirstate.parents()
-            lock = self.lock()
             hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
             try:
                 self.hook("precommit", throw=True, parent1=hookp1,