[PATCH RFC] revlog/changegroup: use callbacks for populating efiles

Gregory Szorc gregory.szorc at gmail.com
Fri Jul 10 18:46:42 CDT 2015

# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1436571961 25200
#      Fri Jul 10 16:46:01 2015 -0700
# Node ID bca84aa6ea80b386a01c245e7f4e4ebdb720cd8c
# Parent  648323f41a89619d9eeeb7287213378c340866c8
revlog/changegroup: use callbacks for populating efiles

This fails with:

$ HGRCPATH=/dev/null time -p ~/src/hg/hg unbundle ../f34a7120f46bdfcf9991a0c89a72753f86622df0.gzip.hg --debug --traceback
adding changesets
add changeset 8ba995b74e18
add changeset 9b2a99adc05e
transaction abort!
rollback completed
Traceback (most recent call last):
  File "/Users/gps/src/hg/mercurial/dispatch.py", line 162, in _runcatch
    return _dispatch(req)
  File "/Users/gps/src/hg/mercurial/dispatch.py", line 894, in _dispatch
    cmdpats, cmdoptions)
  File "/Users/gps/src/hg/mercurial/dispatch.py", line 655, in runcommand
    ret = _runcommand(ui, options, cmd, d)
  File "/Users/gps/src/hg/mercurial/dispatch.py", line 1011, in _runcommand
    return checkargs()
  File "/Users/gps/src/hg/mercurial/dispatch.py", line 980, in checkargs return cmdfunc()
  File "/Users/gps/src/hg/mercurial/dispatch.py", line 891, in <lambda>
    d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
  File "/Users/gps/src/hg/mercurial/util.py", line 792, in check
    return func(*args, **kwargs)
  File "/Users/gps/src/hg/mercurial/commands.py", line 6382, in unbundle
    'bundle:' + fname)
  File "/Users/gps/src/hg/mercurial/changegroup.py", line 761, in addchangegroup
  File "/Users/gps/src/hg/mercurial/revlog.py", line 1466, in addgroup
    addrevisioncb(self, node)
  File "/Users/gps/src/hg/mercurial/changegroup.py", line 757, in changelogadded
  File "/Users/gps/src/hg/mercurial/changelog.py", line 323, in read
    text = self.revision(node)
  File "/Users/gps/src/hg/mercurial/revlog.py", line 1094, in revision
    bins = self._chunks(chain)
  File "/Users/gps/src/hg/mercurial/revlog.py", line 1015, in _chunks
    ladd(decompress(buffer(data, chunkstart - offset, chunklength)))
  File "/Users/gps/src/hg/mercurial/revlog.py", line 93, in decompress
    raise RevlogError(_("revlog decompress error: %s") % str(e))
RevlogError: revlog decompress error: Error -5 while decompressing data: incomplete or truncated stream
abort: revlog decompress error: Error -5 while decompressing data: incomplete or truncated stream!

diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py
--- a/mercurial/changegroup.py
+++ b/mercurial/changegroup.py
@@ -752,16 +752,18 @@ def addchangegroup(repo, source, srctype
                 self._count += 1
         source.callback = prog(_('changesets'), expectedtotal)
+        def changelogadded(rl, node):
+            efiles.update(rl.read(node)[3])
-        srccontent = cl.addgroup(source, csmap, trp)
+        srccontent = cl.addgroup(source, csmap, trp,
+                                 addrevisioncb=changelogadded)
         if not (srccontent or emptyok):
             raise util.Abort(_("received changelog group is empty"))
         clend = len(cl)
         changesets = clend - clstart
-        for c in xrange(clstart, clend):
-            efiles.update(repo[c].files())
         efiles = len(efiles)
         repo.ui.progress(_('changesets'), None)
         # pull off the manifest group
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -1378,15 +1378,18 @@ class revlog(object):
             self.checkinlinesize(transaction, ifh)
-    def addgroup(self, bundle, linkmapper, transaction):
+    def addgroup(self, bundle, linkmapper, transaction, addrevisioncb=None):
         add a delta group
         given a set of deltas, add them to the revision log. the
         first delta is against its parent, which should be in our
         log, the rest are against the previous delta.
+        An optional ``addrevisioncb`` will be called after each added revision.
+        Its arguments are this revlog instance and the added node.
         # track the base of the current delta log
         content = []
@@ -1458,8 +1461,10 @@ class revlog(object):
                 chain = self._addrevision(node, None, transaction, link,
                                           p1, p2, flags, (baserev, delta),
                                           ifh, dfh)
+                if addrevisioncb:
+                    addrevisioncb(self, node)
                 if not dfh and not self._inline:
                     # addrevision switched from inline to conventional
                     # reopen the index

More information about the Mercurial-devel mailing list