comparison mercurial/localrepo.py @ 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 42aa0e570eaa
children b64b6fdc5c9b
comparison
equal deleted inserted replaced
27290:525d9b3f0a31 27291:a18328aad48c
1469 match.bad = fail 1469 match.bad = fail
1470 1470
1471 wlock = lock = tr = None 1471 wlock = lock = tr = None
1472 try: 1472 try:
1473 wlock = self.wlock() 1473 wlock = self.wlock()
1474 lock = self.lock() # for recent changelog (see issue4368)
1475
1474 wctx = self[None] 1476 wctx = self[None]
1475 merge = len(wctx.parents()) > 1 1477 merge = len(wctx.parents()) > 1
1476 1478
1477 if not force and merge and match.ispartial(): 1479 if not force and merge and match.ispartial():
1478 raise error.Abort(_('cannot partially commit a merge ' 1480 raise error.Abort(_('cannot partially commit a merge '
1596 sr = sub.commit(cctx._text, user, date) 1598 sr = sub.commit(cctx._text, user, date)
1597 newstate[s] = (newstate[s][0], sr) 1599 newstate[s] = (newstate[s][0], sr)
1598 subrepo.writestate(self, newstate) 1600 subrepo.writestate(self, newstate)
1599 1601
1600 p1, p2 = self.dirstate.parents() 1602 p1, p2 = self.dirstate.parents()
1601 lock = self.lock()
1602 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '') 1603 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
1603 try: 1604 try:
1604 self.hook("precommit", throw=True, parent1=hookp1, 1605 self.hook("precommit", throw=True, parent1=hookp1,
1605 parent2=hookp2) 1606 parent2=hookp2)
1606 tr = self.transaction('commit') 1607 tr = self.transaction('commit')