[PATCH 3 of 9] Add a multi=False argument to repo.lookup

Alexis S. L. Carvalho alexis at cecm.usp.br
Sun Mar 2 13:01:25 CST 2008


# HG changeset patch
# User Alexis S. L. Carvalho <alexis at cecm.usp.br>
# Date 1204481759 10800
# Node ID d50e75fa6401bc17ae1389b8d72a6dbc6f0db22b
# Parent  8894448ad0e8d4aa0ce51a5da4181ecb1c58b24c
Add a multi=False argument to repo.lookup

When multi=True repo.lookup is allowed to return a list of nodes
that correspond to the given name.  Even in this case it may still
return a single node.  Most callers will want to use lookuplist, which
knows how to handle this inconsistency.

The protocols were not changed, so even with multi=True {ssh,http}repo
will still return a single node.

diff -r 8894448ad0e8 -r d50e75fa6401 hgext/parentrevspec.py
--- a/hgext/parentrevspec.py	Sun Mar 02 15:15:59 2008 -0300
+++ b/hgext/parentrevspec.py	Sun Mar 02 15:15:59 2008 -0300
@@ -30,11 +30,13 @@ def reposetup(ui, repo):
         return
 
     class parentrevspecrepo(repo.__class__):
-        def lookup(self, key):
+        def lookup(self, key, multi=False):
             try:
                 _super = super(parentrevspecrepo, self)
-                return _super.lookup(key)
+                return _super.lookup(key, multi)
             except mercurial.repo.RepoError:
+                if multi:
+                    raise
                 pass
 
             circ = key.find('^')
@@ -49,10 +51,10 @@ def reposetup(ui, repo):
             cl = self.changelog
             base = key[:end]
             try:
-                node = _super.lookup(base)
+                node = _super.lookup(base, multi)
             except mercurial.repo.RepoError:
                 # eek - reraise the first error
-                return _super.lookup(key)
+                return _super.lookup(key, multi)
 
             rev = cl.rev(node)
             suffix = key[end:]
diff -r 8894448ad0e8 -r d50e75fa6401 mercurial/cmdutil.py
--- a/mercurial/cmdutil.py	Sun Mar 02 15:15:59 2008 -0300
+++ b/mercurial/cmdutil.py	Sun Mar 02 15:15:59 2008 -0300
@@ -158,11 +158,12 @@ def revrange(repo, revs):
                 seen[rev] = 1
                 l.append(rev)
         else:
-            rev = revfix(repo, spec, None)
-            if rev in seen:
-                continue
-            seen[rev] = 1
-            l.append(rev)
+            for node in repo.lookuplist((spec,)):
+                rev = repo.changelog.rev(node)
+                if rev in seen:
+                    continue
+                seen[rev] = 1
+                l.append(rev)
 
     return l
 
diff -r 8894448ad0e8 -r d50e75fa6401 mercurial/commands.py
--- a/mercurial/commands.py	Sun Mar 02 15:15:59 2008 -0300
+++ b/mercurial/commands.py	Sun Mar 02 15:15:59 2008 -0300
@@ -1164,8 +1164,11 @@ def heads(ui, repo, *branchrevs, **opts)
     else:
         heads = []
         visitedset = util.set()
+        branches = repo.branchtags()
         for branchrev in branchrevs:
-            branch = repo.changectx(branchrev).branch()
+            branch = branchrev
+            if branch not in branches:
+                branch = repo.changectx(branchrev).branch()
             if branch in visitedset:
                 continue
             visitedset.add(branch)
diff -r 8894448ad0e8 -r d50e75fa6401 mercurial/hgweb/protocol.py
--- a/mercurial/hgweb/protocol.py	Sun Mar 02 15:15:59 2008 -0300
+++ b/mercurial/hgweb/protocol.py	Sun Mar 02 15:15:59 2008 -0300
@@ -24,7 +24,8 @@ HGTYPE = 'application/mercurial-0.1'
 
 def lookup(web, req):
     try:
-        r = hex(web.repo.lookup(req.form['key'][0]))
+        nodes = web.repo.lookuplist((req.form['key'][0],))
+        r = hex(nodes[-1])
         success = 1
     except Exception,inst:
         r = str(inst)
diff -r 8894448ad0e8 -r d50e75fa6401 mercurial/httprepo.py
--- a/mercurial/httprepo.py	Sun Mar 02 15:15:59 2008 -0300
+++ b/mercurial/httprepo.py	Sun Mar 02 15:15:59 2008 -0300
@@ -355,7 +355,7 @@ class httprepository(remoterepository):
             # if using keepalive, allow connection to be reused
             fp.close()
 
-    def lookup(self, key):
+    def lookup(self, key, multi=False):
         self.requirecap('lookup', _('look up remote revision'))
         d = self.do_cmd("lookup", key = key).read()
         success, data = d[:-1].split(' ', 1)
diff -r 8894448ad0e8 -r d50e75fa6401 mercurial/localrepo.py
--- a/mercurial/localrepo.py	Sun Mar 02 15:15:59 2008 -0300
+++ b/mercurial/localrepo.py	Sun Mar 02 15:15:59 2008 -0300
@@ -428,7 +428,7 @@ class localrepository(repo.repository):
             b = c.branch()
             partial[b] = [c.node()]
 
-    def lookup(self, key):
+    def lookup(self, key, multi=False):
         if key == '.':
             key, second = self.dirstate.parents()
             if key == nullid:
@@ -443,8 +443,15 @@ class localrepository(repo.repository):
             return n
         if key in self.tags():
             return self.tags()[key]
-        if key in self.branchtags():
-            return self.branchtags()[key][-1]
+        branches = self.branchtags()
+        if key in branches:
+            nodes = branches[key]
+            if len(nodes) > 1:
+                if not multi:
+                    raise repo.AmbiguousName(_("the name %s refers to "
+                                               "multiple revisions.") % key)
+                return nodes
+            return nodes[0]
         n = self.changelog._partialmatch(key)
         if n:
             return n
diff -r 8894448ad0e8 -r d50e75fa6401 mercurial/repo.py
--- a/mercurial/repo.py	Sun Mar 02 15:15:59 2008 -0300
+++ b/mercurial/repo.py	Sun Mar 02 15:15:59 2008 -0300
@@ -12,6 +12,9 @@ class RepoError(Exception):
     pass
 
 class NoCapability(RepoError):
+    pass
+
+class AmbiguousName(RepoError):
     pass
 
 class repository(object):
@@ -36,5 +39,12 @@ class repository(object):
                                (purpose, name))
 
     def lookuplist(self, keys):
-        '''lookup multiple keys'''
-        return [self.lookup(k) for k in keys]
+        '''lookup multiple keys; each one can refer to more than one node'''
+        nodes = []
+        for k in keys:
+            n = self.lookup(k, multi=True)
+            if not hasattr(n, '__iter__'):
+                nodes.append(n)
+            else:
+                nodes.extend(n)
+        return nodes
diff -r 8894448ad0e8 -r d50e75fa6401 mercurial/sshrepo.py
--- a/mercurial/sshrepo.py	Sun Mar 02 15:15:59 2008 -0300
+++ b/mercurial/sshrepo.py	Sun Mar 02 15:15:59 2008 -0300
@@ -141,7 +141,7 @@ class sshrepository(remoterepository):
     def unlock(self):
         self.call("unlock")
 
-    def lookup(self, key):
+    def lookup(self, key, multi=False):
         self.requirecap('lookup', _('look up remote revision'))
         d = self.call("lookup", key=key)
         success, data = d[:-1].split(" ", 1)
diff -r 8894448ad0e8 -r d50e75fa6401 mercurial/sshserver.py
--- a/mercurial/sshserver.py	Sun Mar 02 15:15:59 2008 -0300
+++ b/mercurial/sshserver.py	Sun Mar 02 15:15:59 2008 -0300
@@ -52,7 +52,8 @@ class sshserver(object):
         arg, key = self.getarg()
         assert arg == 'key'
         try:
-            r = hex(self.repo.lookup(key))
+            nodes = self.repo.lookuplist((key,))
+            r = hex(nodes[-1])
             success = 1
         except Exception,inst:
             r = str(inst)


More information about the Mercurial-devel mailing list