changeset 23203:3872d563e01a

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.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Fri, 17 Oct 2014 21:55:31 -0700
parents ea5af863fbff
children 10beda5bd2b7
files mercurial/changegroup.py mercurial/changelog.py mercurial/exchange.py mercurial/localrepo.py
diffstat 4 files changed, 14 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- 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)