hgext/evolve.py
changeset 817 c2bf0eb727f1
parent 816 03587920dfd9
child 819 0b6af104fd78
--- a/hgext/evolve.py	Thu Feb 27 18:30:55 2014 -0800
+++ b/hgext/evolve.py	Thu Feb 27 19:58:08 2014 -0800
@@ -46,6 +46,7 @@
 from mercurial import context
 from mercurial import copies
 from mercurial import error
+from mercurial import exchange
 from mercurial import extensions
 from mercurial import hg
 from mercurial import lock as lockmod
@@ -2074,3 +2075,61 @@
     return seenmarkers
 
 
+_pushkeyescape = getattr(obsolete, '_pushkeyescape', None)
+if _pushkeyescape is None:
+    def _pushkeyescape(markers):
+        """encode markers into a dict suitable for pushkey exchange
+
+        - binary data are base86 encoded
+        - splited in chunk less than 5300 bytes"""
+        parts = []
+        currentlen = _maxpayload * 2  # ensure we create a new part
+        for marker in markers:
+            nextdata = _encodeonemarker(marker)
+            if (len(nextdata) + currentlen > _maxpayload):
+                currentpart = []
+                currentlen = 0
+                parts.append(currentpart)
+            currentpart.append(nextdata)
+            currentlen += len(nextdata)
+        keys = {}
+        for idx, part in enumerate(reversed(parts)):
+            data = ''.join([_pack('>B', _fmversion)] + part)
+            keys['dump%i' % idx] = base85.b85encode(data)
+        return keys
+
+
+
+@eh.wrapfunction(exchange, '_pushobsolete')
+def _pushobsolete(orig, pushop):
+    """utility function to push obsolete markers to a remote"""
+    pushop.ui.debug('try to push obsolete markers to remote\n')
+    repo = pushop.repo
+    remote = pushop.remote
+    unfi = repo.unfiltered()
+    if (obsolete._enabled and repo.obsstore and
+        'obsolete' in remote.listkeys('namespaces')):
+        repo.ui.status("OBSEXC: computing relevant nodes\n")
+        nodes = [ctx.node() for ctx in unfi.set('::%ln', pushop.commonheads)]
+        repo.ui.status("OBSEXC: computing markers relevant to %i nodes\n"
+                       % len(nodes))
+        markers = repo.obsstore.relevantmarkers(nodes)
+        rslts = []
+        repo.ui.status("OBSEXC: encoding %i markers\n" % len(markers))
+        remotedata = obsolete._pushkeyescape(markers).items()
+        totalbytes = sum(len(d) for k,d in remotedata)
+        sentbytes = 0
+        repo.ui.status("OBSEXC: sending %i pushkey payload (%i bytes)\n"
+                        % (len(remotedata), totalbytes))
+        for key, data in remotedata:
+            repo.ui.progress('OBSEXC', sentbytes, item=key, unit="bytes",
+                             total=totalbytes)
+            rslts.append(remote.pushkey('obsolete', key, '', data))
+            sentbytes += len(data)
+            repo.ui.progress('OBSEXC', sentbytes, item=key, unit="bytes",
+                             total=totalbytes)
+        repo.ui.progress('OBSEXC', None)
+        if [r for r in rslts if not r]:
+            msg = _('failed to push some obsolete markers!\n')
+            repo.ui.warn(msg)
+        repo.ui.status("OBSEXC: DONE\n")