[PATCH 6 of 9] context: add findbyhash to examine by hash ID strictly

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Sun Mar 29 13:34:28 CDT 2015


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1427653752 -32400
#      Mon Mar 30 03:29:12 2015 +0900
# Node ID 5070134e83f1a46a55f74e6e6dce6ebd75a5eee9
# Parent  f9e9783d4f10af2974d77dbfaacd217f24fd3035
context: add findbyhash to examine by hash ID strictly

Before this patch, there is no easy way to examine existence of the
revision by hash ID in 40 characters strictly.

"hashid in repo" implies unexpected (and meaningless, maybe) matching.

This patch adds "findbyhash()" to examine existence of the revision by
hash ID in 40 characters strcitly and easily. This patch also factors
out the logic for it in "changectx.__init__()" to avoid duplication of
similar code.

This is a preparation to fix equivalence problem of revset predicate
"id()".

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -416,6 +416,36 @@ def findbyrevnum(repo, revnum, abort=Fal
     assert isinstance(revnum, int)
     return _wraplookup(_findbyrevnum, repo, revnum, abort)
 
+def _findby40hash(repo, changeid):
+    try:
+        node = bin(changeid)
+        rev = repo.changelog.rev(node)
+        return (node, rev)
+    except error.FilteredLookupError:
+        raise
+    except (TypeError, LookupError):
+        return None
+
+def findbyhash(repo, hashid, abort=False):
+    """Find the revision by hash ID
+
+    ``hashid`` should be ``str``.
+
+    This returns ``(node, revnum)`` tuple, if the revision
+    corresponded to the specified ``hashid`` is found. If that
+    revision is hidden one, this raises FilteredRepoLookupError.
+
+    Other wise, this returns ``None`` (or raises RepoLookupError if
+    ``abort``).
+
+    This can avoid meaningless matching against "repo.dirstate.p1()",
+    reserved names (e.g. "null", "tip", "."), bookmarks, tags,
+    branches and so on.
+    """
+    assert isinstance(hashid, str)
+    assert len(hashid) == 40
+    return _wraplookup(_findby40hash, repo, hashid, abort)
+
 class changectx(basectx):
     """A changecontext object makes access to data related to a particular
     changeset convenient. It represents a read-only context already present in
@@ -481,14 +511,10 @@ class changectx(basectx):
                 pass
 
             if len(changeid) == 40:
-                try:
-                    self._node = bin(changeid)
-                    self._rev = repo.changelog.rev(self._node)
+                found = _findby40hash(repo, changeid)
+                if found:
+                    self._node, self._rev = found
                     return
-                except error.FilteredLookupError:
-                    raise
-                except (TypeError, LookupError):
-                    pass
 
             # lookup bookmarks through the name interface
             try:


More information about the Mercurial-devel mailing list