changelog: handle writepending in the transaction
The 'delayupdate' method now takes a transaction object and registers its
'_writepending' method for execution in 'transaction.writepending()'. The hook can then
use 'transaction.writepending()' directly.
At some point this will allow the addition of other file creation
during writepending.
--- a/mercurial/changegroup.py Fri Oct 17 21:19:54 2014 -0700
+++ b/mercurial/changegroup.py Fri Oct 17 21:55:31 2014 -0700
@@ -661,12 +661,6 @@
changesets = files = revisions = 0
efiles = set()
- # write changelog data to temp files so concurrent readers will not see
- # inconsistent view
- cl = repo.changelog
- cl.delayupdate()
- oldheads = cl.heads()
-
tr = repo.transaction("\n".join([srctype, util.hidepassword(url)]))
# The transaction could have been created before and already carries source
# information. In this case we use the top level data. We overwrite the
@@ -674,6 +668,12 @@
# this function.
srctype = tr.hookargs.setdefault('source', srctype)
url = tr.hookargs.setdefault('url', url)
+
+ # write changelog data to temp files so concurrent readers will not see
+ # inconsistent view
+ cl = repo.changelog
+ cl.delayupdate(tr)
+ oldheads = cl.heads()
try:
repo.hook('prechangegroup', throw=True, **tr.hookargs)
@@ -756,7 +756,7 @@
repo.invalidatevolatilesets()
if changesets > 0:
- p = lambda: cl.writepending() and repo.root or ""
+ p = lambda: tr.writepending() and repo.root or ""
if 'node' not in tr.hookargs:
tr.hookargs['node'] = hex(cl.node(clstart))
hookargs = dict(tr.hookargs)
--- a/mercurial/changelog.py Fri Oct 17 21:19:54 2014 -0700
+++ b/mercurial/changelog.py Fri Oct 17 21:55:31 2014 -0700
@@ -224,7 +224,7 @@
raise error.FilteredIndexError(rev)
return super(changelog, self).flags(rev)
- def delayupdate(self):
+ def delayupdate(self, tr):
"delay visibility of index updates to other readers"
if not self._delayed:
@@ -238,6 +238,7 @@
self.opener = _delayopener(self._realopener, self.indexfile,
self._delaybuf)
self._delayed = True
+ tr.addpending('cl-%i' % id(self), self._writepending)
def finalize(self, tr):
"finalize index updates"
@@ -266,7 +267,7 @@
self._nodecache = r._nodecache
self._chunkcache = r._chunkcache
- def writepending(self):
+ def _writepending(self):
"create a file containing the unfinalized state for pretxnchangegroup"
if self._delaybuf:
# make a temporary copy of the index
--- a/mercurial/exchange.py Fri Oct 17 21:19:54 2014 -0700
+++ b/mercurial/exchange.py Fri Oct 17 21:55:31 2014 -0700
@@ -854,9 +854,7 @@
"""close transaction if created"""
if self._tr is not None:
repo = self.repo
- cl = repo.unfiltered().changelog
- p = cl.writepending() and repo.root or ""
- p = cl.writepending() and repo.root or ""
+ p = lambda: self._tr.writepending() and repo.root or ""
repo.hook('b2x-pretransactionclose', throw=True, pending=p,
**self._tr.hookargs)
self._tr.close()
@@ -1279,8 +1277,7 @@
tr.hookargs['url'] = url
tr.hookargs['bundle2-exp'] = '1'
r = bundle2.processbundle(repo, cg, lambda: tr).reply
- cl = repo.unfiltered().changelog
- p = cl.writepending() and repo.root or ""
+ p = lambda: tr.writepending() and repo.root or ""
repo.hook('b2x-pretransactionclose', throw=True, pending=p,
**tr.hookargs)
tr.close()
--- a/mercurial/localrepo.py Fri Oct 17 21:19:54 2014 -0700
+++ b/mercurial/localrepo.py Fri Oct 17 21:55:31 2014 -0700
@@ -1437,11 +1437,11 @@
files = []
# update changelog
- self.changelog.delayupdate()
+ self.changelog.delayupdate(tr)
n = self.changelog.add(mn, files, ctx.description(),
trp, p1.node(), p2.node(),
user, ctx.date(), ctx.extra().copy())
- p = lambda: self.changelog.writepending() and self.root or ""
+ p = lambda: tr.writepending() and self.root or ""
xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
parent2=xp2, pending=p)