# HG changeset patch # User FUJIWARA Katsunori # Date 2015-12-08 23:28:53 # Node ID a18328aad48c4512cb392fd72b65aa06eafb96da # Parent 525d9b3f0a317c059fa7d0fb185eb064cc336102 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'. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1471,6 +1471,8 @@ class localrepository(object): 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 @@ class localrepository(object): 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,