diff --git a/infinitepush/__init__.py b/infinitepush/__init__.py --- a/infinitepush/__init__.py +++ b/infinitepush/__init__.py @@ -1078,7 +1078,12 @@ True) elif part.type == scratchbookmarksparttype: # Save this for later processing. Details below. - scratchbookpart = part + # + # Upstream https://phab.mercurial-scm.org/D1389 and its + # follow-ups stop part.seek support to reduce memory usage + # (https://bz.mercurial-scm.org/5691). So we need to copy + # the part so it can be consumed later. + scratchbookpart = bundleparts.copiedpart(part) else: if handleallparts or part.type in partforwardingwhitelist: # Ideally we would not process any parts, and instead just @@ -1128,7 +1133,7 @@ # processed after the main bundle has been stored, so that any commits it # references are available in the store. if scratchbookpart: - bundle2._processpart(op, part) + bundle2._processpart(op, scratchbookpart) def storebundle(op, params, bundlefile): log = _getorcreateinfinitepushlogger(op) diff --git a/infinitepush/bundleparts.py b/infinitepush/bundleparts.py --- a/infinitepush/bundleparts.py +++ b/infinitepush/bundleparts.py @@ -13,6 +13,7 @@ error, extensions, revsetlang, + util, ) from mercurial.i18n import _ @@ -112,3 +113,27 @@ except KeyError: # Ignore if lfs extension is not enabled return + +class copiedpart(object): + """a copy of unbundlepart content that can be consumed later""" + + def __init__(self, part): + # copy "public properties" + self.type = part.type + self.id = part.id + self.mandatory = part.mandatory + self.mandatoryparams = part.mandatoryparams + self.advisoryparams = part.advisoryparams + self.params = part.params + self.mandatorykeys = part.mandatorykeys + # copy the buffer + self._io = util.stringio(part.read()) + + def consume(self): + return + + def read(self, size=None): + if size is None: + return self._io.read() + else: + return self._io.read(size)