Mercurial > hg
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,