diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -661,12 +661,6 @@ def addchangegroup(repo, source, srctype 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 @@ def addchangegroup(repo, source, srctype # 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 @@ def addchangegroup(repo, source, srctype 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) diff --git a/mercurial/changelog.py b/mercurial/changelog.py --- a/mercurial/changelog.py +++ b/mercurial/changelog.py @@ -224,7 +224,7 @@ class changelog(revlog.revlog): 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 @@ class changelog(revlog.revlog): 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 @@ class changelog(revlog.revlog): 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 diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -854,9 +854,7 @@ class pulloperation(object): """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 @@ def unbundle(repo, cg, heads, source, ur 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() diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1437,11 +1437,11 @@ class localrepository(object): 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)