wireproto: add known([id]) function
authorPeter Arrenbrecht <peter.arrenbrecht@gmail.com>
Tue, 22 Mar 2011 09:22:21 +0100
changeset 13723 e615765fdcc7
parent 13722 f4a85acef50c
child 13724 fe57046e9448
wireproto: add known([id]) function known([Node]) -> [1/0] Returns 1/0 for each node, indicating whether it's known by the server. Needed for new discovery protocols introduced in later patches.
mercurial/commands.py
mercurial/localrepo.py
mercurial/wireproto.py
tests/test-debugcomplete.t
tests/test-hgweb-commands.t
tests/test-known.t
--- a/mercurial/commands.py	Tue Mar 22 07:40:02 2011 +0100
+++ b/mercurial/commands.py	Tue Mar 22 09:22:21 2011 +0100
@@ -5,7 +5,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-from node import hex, nullid, nullrev, short
+from node import hex, bin, nullid, nullrev, short
 from lock import release
 from i18n import _, gettext
 import os, re, sys, difflib, time, tempfile
@@ -1218,6 +1218,18 @@
                      ui.configsource(section, name, untrusted))
             ui.write('%s=%s\n' % (sectname, value))
 
+def debugknown(ui, repopath, *ids, **opts):
+    """test whether node ids are known to a repo
+
+    Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
+    indicating unknown/known.
+    """
+    repo = hg.repository(ui, repopath)
+    if not repo.capable('known'):
+        raise util.Abort("known() not supported by target repository")
+    flags = repo.known([bin(s) for s in ids])
+    ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
+
 def debugpushkey(ui, repopath, namespace, *keyinfo):
     '''access the pushkey key/value protocol
 
@@ -4446,6 +4458,7 @@
                    _('FILE')),
     "debugindexdot": (debugindexdot, [], _('FILE')),
     "debuginstall": (debuginstall, [], ''),
+    "debugknown": (debugknown, [], _('REPO ID...')),
     "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
     "debugrebuildstate":
         (debugrebuildstate,
@@ -4810,6 +4823,7 @@
 }
 
 norepo = ("clone init version help debugcommands debugcomplete"
-          " debugdate debuginstall debugfsinfo debugpushkey debugwireargs")
+          " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
+          " debugknown")
 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
                 " debugdata debugindex debugindexdot")
--- a/mercurial/localrepo.py	Tue Mar 22 07:40:02 2011 +0100
+++ b/mercurial/localrepo.py	Tue Mar 22 09:22:21 2011 +0100
@@ -20,7 +20,8 @@
 propertycache = util.propertycache
 
 class localrepository(repo.repository):
-    capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey'))
+    capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey',
+                        'known'))
     supportedformats = set(('revlogv1', 'parentdelta'))
     supported = supportedformats | set(('store', 'fncache', 'shared',
                                         'dotencode'))
@@ -558,6 +559,10 @@
         repo = (remote and remote.local()) and remote or self
         return repo[key].branch()
 
+    def known(self, nodes):
+        nm = self.changelog.nodemap
+        return [(n in nm) for n in nodes]
+
     def local(self):
         return True
 
--- a/mercurial/wireproto.py	Tue Mar 22 07:40:02 2011 +0100
+++ b/mercurial/wireproto.py	Tue Mar 22 09:22:21 2011 +0100
@@ -40,6 +40,14 @@
         except:
             self._abort(error.ResponseError(_("unexpected response:"), d))
 
+    def known(self, nodes):
+        n = encodelist(nodes)
+        d = self._call("known", nodes=n)
+        try:
+            return [bool(int(f)) for f in d]
+        except:
+            self._abort(error.ResponseError(_("unexpected response:"), d))
+
     def branchmap(self):
         d = self._call("branchmap")
         try:
@@ -198,7 +206,7 @@
     return "".join(r)
 
 def capabilities(repo, proto):
-    caps = 'lookup changegroupsubset branchmap pushkey'.split()
+    caps = 'lookup changegroupsubset branchmap pushkey known'.split()
     if _allowstream(repo.ui):
         requiredformats = repo.requirements & repo.supportedformats
         # if our local revlogs are just revlogv1, add 'stream' cap
@@ -255,6 +263,9 @@
         success = 0
     return "%s %s\n" % (success, r)
 
+def known(repo, proto, nodes):
+    return ''.join(b and "1" or "0" for b in repo.known(decodelist(nodes)))
+
 def pushkey(repo, proto, namespace, key, old, new):
     # compatibility with pre-1.8 clients which were accidentally
     # sending raw binary nodes rather than utf-8-encoded hex
@@ -373,6 +384,7 @@
     'debugwireargs': (debugwireargs, 'one two *'),
     'heads': (heads, ''),
     'hello': (hello, ''),
+    'known': (known, 'nodes'),
     'listkeys': (listkeys, 'namespace'),
     'lookup': (lookup, 'key'),
     'pushkey': (pushkey, 'namespace key old new'),
--- a/tests/test-debugcomplete.t	Tue Mar 22 07:40:02 2011 +0100
+++ b/tests/test-debugcomplete.t	Tue Mar 22 09:22:21 2011 +0100
@@ -79,6 +79,7 @@
   debugindex
   debugindexdot
   debuginstall
+  debugknown
   debugpushkey
   debugrebuildstate
   debugrename
@@ -220,6 +221,7 @@
   debugindex: format
   debugindexdot: 
   debuginstall: 
+  debugknown: 
   debugpushkey: 
   debugrebuildstate: rev
   debugrename: rev
--- a/tests/test-hgweb-commands.t	Tue Mar 22 07:40:02 2011 +0100
+++ b/tests/test-hgweb-commands.t	Tue Mar 22 09:22:21 2011 +0100
@@ -905,7 +905,7 @@
   $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'; echo
   200 Script output follows
   
-  lookup changegroupsubset branchmap pushkey unbundle=HG10GZ,HG10BZ,HG10UN
+  lookup changegroupsubset branchmap pushkey known unbundle=HG10GZ,HG10BZ,HG10UN
 
 heads
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-known.t	Tue Mar 22 09:22:21 2011 +0100
@@ -0,0 +1,37 @@
+
+= Test the known() protocol function =
+
+Create a test repository:
+
+  $ hg init repo
+  $ cd repo
+  $ touch a ; hg add a ; hg ci -ma
+  $ touch b ; hg add b ; hg ci -mb
+  $ touch c ; hg add c ; hg ci -mc
+  $ hg log --template '{node}\n'
+  991a3460af53952d10ec8a295d3d2cc2e5fa9690
+  0e067c57feba1a5694ca4844f05588bb1bf82342
+  3903775176ed42b1458a6281db4a0ccf4d9f287a
+  $ cd ..
+
+Test locally:
+
+  $ hg debugknown repo 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a
+  111
+  $ hg debugknown repo 000a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 0003775176ed42b1458a6281db4a0ccf4d9f287a
+  010
+  $ hg debugknown repo
+  
+
+Test via HTTP:
+
+  $ hg serve -R repo -p $HGPORT -d --pid-file=hg.pid -E error.log -A access.log
+  $ cat hg.pid >> $DAEMON_PIDS
+  $ hg debugknown http://localhost:$HGPORT/ 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a
+  111
+  $ hg debugknown http://localhost:$HGPORT/ 000a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 0003775176ed42b1458a6281db4a0ccf4d9f287a
+  010
+  $ hg debugknown http://localhost:$HGPORT/
+  
+  $ cat error.log
+