exchange: add a new method to pull markers
authorPierre-Yves David <pierre-yves.david@fb.com>
Fri, 28 Feb 2014 13:25:34 -0800
changeset 823 9aa20585e158
parent 822 5f5d269278e9
child 824 fed090e07621
exchange: add a new method to pull markers It has both local and wire protocol implementation. This command does not requires escaping of the marker and are expecting to me highly faster than the pushkey method. The other main point is that command is to accept a `heads` and `common` argument to select to pull changeset only relevant to a set a of node. We are not using this capability yet but we'll do it soon
hgext/evolve.py
tests/test-evolve.t
tests/test-obsolete.t
tests/test-tutorial.t
--- a/hgext/evolve.py	Fri Feb 28 00:55:34 2014 -0800
+++ b/hgext/evolve.py	Fri Feb 28 13:25:34 2014 -0800
@@ -63,6 +63,7 @@
 from mercurial.commands import walkopts, commitopts, commitopts2
 from mercurial.node import nullid
 from mercurial import wireproto
+from mercurial import localrepo
 
 _pack = struct.pack
 
@@ -2183,14 +2184,92 @@
         lock.release()
     return wireproto.pushres(0)
 
+@eh.wrapfunction(exchange, '_pullobsolete')
+def _pullobsolete(orig, pullop):
+    if not obsolete._enabled:
+        return None
+    if not pullop.remote.capable('_evoext_pullobsmarkers_0'):
+        return orig(pullop)
+    tr = None
+    ui = pullop.repo.ui
+    ui.status("OBSEXC: pull obsolescence markers\n")
+    obsdata = pullop.remote.evoext_pullobsmarkers_0()
+    obsdata = obsdata.read()
+    if len(obsdata) > 5:
+        ui.status("OBSEXC: merging obsolescence markers (%i bytes)\n"
+                       % len(obsdata))
+        tr = pullop.gettransaction()
+        old = len(pullop.repo.obsstore._all)
+        pullop.repo.obsstore.mergemarkers(tr, obsdata)
+        new = len(pullop.repo.obsstore._all) - old
+        ui.status("OBSEXC: %i markers added\n" % new)
+        if new:
+            pullop.repo.invalidatevolatilesets()
+    ui.status("OBSEXC: DONE\n")
+    return tr
+
+def _getobsmarkersstream(repo, heads=None, common=None):
+    revset = ''
+    args = []
+    repo = repo.unfiltered()
+    if heads is None:
+        revset = 'all()'
+    elif heads:
+        revset += "(::%ln)"
+        args.append(heads)
+    else:
+        assert False, 'pulling no heads?'
+    if common:
+        revset += ' - (::%ln)'
+        args.append(common)
+    nodes = [c.node() for c in repo.set(revset, *args)]
+    markers = repo.obsstore.relevantmarkers(nodes)
+    obsdata = StringIO()
+    _encodemarkersstream(obsdata, markers)
+    obsdata.seek(0)
+    return obsdata
+
+@eh.addattr(wireproto.wirepeer, 'evoext_pullobsmarkers_0')
+def client_pullobsmarkers(self, heads=None, common=None):
+    self.requirecap('_evoext_pullobsmarkers_0', _('look up remote obsmarkers'))
+    opts = {}
+    if heads is not None:
+        opts['heads'] = wireproto.encodelist(heads)
+    if common is not None:
+        opts['common'] = wireproto.encodelist(common)
+    f = self._callstream("evoext_pullobsmarkers_0", **opts)
+    f = self._decompress(f)
+    length= int(f.read(20))
+    return StringIO(f.read(length))
+
+@eh.addattr(localrepo.localpeer, 'evoext_pullobsmarkers_0')
+def local_pullobsmarkers(self, heads=None, common=None):
+    return _getobsmarkersstream(self._repo, heads=heads, common=common)
+
+def srv_pullobsmarkers(repo, proto, others):
+    opts = wireproto.options('', ['heads', 'common'], others)
+    for k, v in opts.iteritems():
+        if k in ('heads', 'common'):
+            opts[k] = wireproto.decodelist(v)
+    obsdata = _getobsmarkersstream(repo, **opts)
+    length = '%20i' % len(obsdata.getvalue())
+    def data():
+        yield length
+        for c in proto.groupchunks(obsdata):
+            yield c
+    return wireproto.streamres(data())
+
 @eh.wrapfunction(wireproto, 'capabilities')
 def capabilities(orig, repo, proto):
     """wrapper to advertise new capability"""
     caps = orig(repo, proto)
     if obsolete._enabled:
         caps += ' _evoext_pushobsmarkers_0'
+        caps += ' _evoext_pullobsmarkers_0'
     return caps
 
 @eh.extsetup
 def _installwireprotocol(ui):
+    localrepo.MODERNCAPS.add('_evoext_pullobsmarkers_0')
     wireproto.commands['evoext_pushobsmarkers_0'] = (srv_pushobsmarkers, '')
+    wireproto.commands['evoext_pullobsmarkers_0'] = (srv_pullobsmarkers, '*')
--- a/tests/test-evolve.t	Fri Feb 28 00:55:34 2014 -0800
+++ b/tests/test-evolve.t	Fri Feb 28 13:25:34 2014 -0800
@@ -384,6 +384,8 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
+  OBSEXC: pull obsolescence markers
+  OBSEXC: DONE
   $ cd alpha
 
   $ cat << EOF > A
@@ -440,6 +442,10 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
+  OBSEXC: pull obsolescence markers
+  OBSEXC: merging obsolescence markers (171 bytes)
+  OBSEXC: 2 markers added
+  OBSEXC: DONE
   (run 'hg update' to get a working copy)
   $ hg up
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/tests/test-obsolete.t	Fri Feb 28 00:55:34 2014 -0800
+++ b/tests/test-obsolete.t	Fri Feb 28 13:25:34 2014 -0800
@@ -285,7 +285,11 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
-  \(run 'hg heads( \.)?' to see heads, 'hg merge' to merge\) (re)
+  OBSEXC: pull obsolescence markers
+  OBSEXC: merging obsolescence markers (245 bytes)
+  OBSEXC: 1 markers added
+  OBSEXC: DONE
+  (run 'hg heads' to see heads, 'hg merge' to merge)
   $ qlog -R ../other-new
   6
   - 909a0fb57e5d
@@ -374,7 +378,11 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
-  \(run 'hg heads( \.)?' to see heads, 'hg merge' to merge\) (re)
+  OBSEXC: pull obsolescence markers
+  OBSEXC: merging obsolescence markers (306 bytes)
+  OBSEXC: 1 markers added
+  OBSEXC: DONE
+  (run 'hg heads' to see heads, 'hg merge' to merge)
 
   $ hg up -q 7 # to check rollback update behavior
   $ qlog
--- a/tests/test-tutorial.t	Fri Feb 28 00:55:34 2014 -0800
+++ b/tests/test-tutorial.t	Fri Feb 28 13:25:34 2014 -0800
@@ -224,6 +224,8 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
+  OBSEXC: pull obsolescence markers
+  OBSEXC: DONE
   (run 'hg heads' to see heads, 'hg merge' to merge)
 
 I now have a new heads. Note that this remote head is immutable
@@ -514,6 +516,10 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
+  OBSEXC: pull obsolescence markers
+  OBSEXC: merging obsolescence markers (560 bytes)
+  OBSEXC: 1 markers added
+  OBSEXC: DONE
   (run 'hg update' to get a working copy)
   $ hg log -G
   o  75954b8cd933 (public): bathroom stuff
@@ -570,6 +576,10 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
+  OBSEXC: pull obsolescence markers
+  OBSEXC: merging obsolescence markers (560 bytes)
+  OBSEXC: 1 markers added
+  OBSEXC: DONE
   (run 'hg update' to get a working copy)
   $ hg log -G
   o  75954b8cd933 (draft): bathroom stuff
@@ -629,6 +639,10 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
+  OBSEXC: pull obsolescence markers
+  OBSEXC: merging obsolescence markers (560 bytes)
+  OBSEXC: 0 markers added
+  OBSEXC: DONE
   (run 'hg heads' to see heads, 'hg merge' to merge)
   1 new unstable changesets
 
@@ -730,6 +744,10 @@
   pulling from $TESTTMP/local
   searching for changes
   no changes found
+  OBSEXC: pull obsolescence markers
+  OBSEXC: merging obsolescence markers (803 bytes)
+  OBSEXC: 0 markers added
+  OBSEXC: DONE
   working directory parent is obsolete!
 
 now let's see where we are, and update to the successor
@@ -759,6 +777,10 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
+  OBSEXC: pull obsolescence markers
+  OBSEXC: merging obsolescence markers (803 bytes)
+  OBSEXC: 0 markers added
+  OBSEXC: DONE
   (run 'hg update' to get a working copy)
   $ hg log -G
   o  99f039c5ec9e (draft): SPAM SPAM SPAM