[PATCH 05 of 10] changelog: handle writepending in the transaction
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Tue Oct 28 10:41:19 CDT 2014
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1413608131 25200
# Fri Oct 17 21:55:31 2014 -0700
# Branch stable
# Node ID 8b1027bf74178ac96a8ba09a0a68d9a6c9a4f88d
# Parent 7bc27f8375dcb9682a78d2cccf46d7644dcef497
changelog: handle writepending in the transaction
The `delayupdate` method now take a transaction object and register its
`_writepending` method for run in `transaction.writepending()`. The hook can then
use `transaction.writepending()` directly.
At some point this will allow the addition of other file creation during write
pending. But this is outside of stable scope.
diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py
--- a/mercurial/changegroup.py
+++ b/mercurial/changegroup.py
@@ -593,23 +593,23 @@ def addchangegroup(repo, source, srctype
return 0
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
# argument because we need to use the top level value (if they exist) in
# 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)
trp = weakref.proxy(tr)
# pull off the changeset group
@@ -688,11 +688,11 @@ def addchangegroup(repo, source, srctype
" with %d changes to %d files%s\n")
% (changesets, revisions, files, htext))
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)
else:
hookargs = dict(tr.hookargs)
diff --git a/mercurial/changelog.py b/mercurial/changelog.py
--- a/mercurial/changelog.py
+++ b/mercurial/changelog.py
@@ -222,11 +222,11 @@ class changelog(revlog.revlog):
"""filtered version of revlog.flags"""
if rev in self.filteredrevs:
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:
if len(self) == 0:
self._divert = True
@@ -236,10 +236,11 @@ class changelog(revlog.revlog):
else:
self._delaybuf = []
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"
self._delayed = False
self.opener = self._realopener
@@ -264,11 +265,11 @@ class changelog(revlog.revlog):
self.index = r.index
self.nodemap = r.nodemap
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
fp1 = self._realopener(self.indexfile)
fp2 = self._realopener(self.indexfile + ".a", "w")
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -837,13 +837,11 @@ class pulloperation(object):
def closetransaction(self):
"""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()
hookargs = dict(self._tr.hookargs)
def runhooks():
@@ -1247,12 +1245,11 @@ def unbundle(repo, cg, heads, source, ur
tr = repo.transaction('unbundle')
tr.hookargs['source'] = source
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()
hookargs = dict(tr.hookargs)
def runhooks():
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1431,15 +1431,15 @@ class localrepository(object):
else:
mn = p1.manifestnode()
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)
self.changelog.finalize(trp)
# set the new commit is proper phase
More information about the Mercurial-devel
mailing list