Patchwork [03,of,21,V2] speedy: convert revs to changeset ids when issuing query

mail settings
Submitter Tomasz Kleczek
Date Dec. 14, 2012, 2:52 a.m.
Message ID <>
Download mbox | patch
Permalink /patch/85/
State Deferred, archived
Headers show


Tomasz Kleczek - Dec. 14, 2012, 2:52 a.m.
# HG changeset patch
# User Tomasz Kleczek <tkleczek at>
# Date 1355246303 28800
# Node ID 767d988bfa2dada2286008e279af3241b4f7cdd8
# Parent  0101e7572322e87d2cc80120af17da02a56e4f9e
speedy: convert revs to changeset ids when issuing query

Since client history may diverge from server history we cannot
reliably use revision numbers when talking to server.
We use node ids instead (transmitted as 20 byte binary strings).

Please note that the server may return node ids that are unknown to
the client. This can occur when some changsets in the server repo
have not yet been pulled by the client and are in the result of running
the query against server history. It is the client's responsibilty
to filter out such changes before returning the final result to
the caller of patched functions.


diff --git a/hgext/speedy/ b/hgext/speedy/
--- a/hgext/speedy/
+++ b/hgext/speedy/
@@ -9,6 +9,25 @@ 
 from mercurial.i18n import _
 import server
+def nodestorevs(repo, nodes):
+    return [repo[n].rev() for n in nodes if repo.changelog.hasnode(n)]
+class metapeer(object):
+    """Class that encapsulates communication details with the metadata server.
+    Its responsibilities:
+        - delegating the query to the server
+        - translating node ids from server to revision numbers
+    """
+    def __init__(self, server, repo):
+        self._server = server
+        self._repo = repo
+    def author(self, x):
+        resp =
+        return nodestorevs(self._repo, resp)
 def patchedauthor(metapeer, repo, subset, x):
     """Return the revisions commited by user whose name match x
@@ -28,12 +47,14 @@ 
     serverrepo = localrepo.localrepository(ui, path=repo.root)
     mserver = server.makeserver(serverrepo)
+    mpeer = metapeer(mserver, repo)
     def wrapwithpeer(fun, peer):
         def wrapper(*args, **kwargs):
             return fun(peer, *args, **kwargs)
         return wrapper
-    revset.symbols['author'] = wrapwithpeer(patchedauthor, mserver)
+    revset.symbols['author'] = wrapwithpeer(patchedauthor, mpeer)
 def uisetup(ui):
     # Perform patching and most of the initialization inside log wrapper,
diff --git a/hgext/speedy/ b/hgext/speedy/
--- a/hgext/speedy/
+++ b/hgext/speedy/
@@ -22,10 +22,11 @@ 
         User matches pattern if their name has a `pat` substring (case
-        Returns a list of revs.
+        Returns a list of node ids.
         # This is going to be accelerated in the subsequent patches
-        return, list(self.repo), ('symbol', pat))
+        revs =, list(self.repo), ('symbol', pat))
+        return [self.repo[r].node() for r in revs]
 def makeserver(repo):
     """Return an initialized metaserver instance."""