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

login
register
mail settings
Submitter Katsunori FUJIWARA
Date March 29, 2015, 6:34 p.m.
Message ID <5070134e83f1a46a55f7.1427654068@juju>
Download mbox | patch
Permalink /patch/8359/
State Changes Requested
Headers show

Comments

Katsunori FUJIWARA - March 29, 2015, 6:34 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@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()".

Patch

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: