From patchwork Sun Mar 29 18:34:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [6,of,9] context: add findbyhash to examine by hash ID strictly From: Katsunori FUJIWARA X-Patchwork-Id: 8359 Message-Id: <5070134e83f1a46a55f7.1427654068@juju> To: mercurial-devel@selenic.com Date: Mon, 30 Mar 2015 03:34:28 +0900 # HG changeset patch # User FUJIWARA Katsunori # 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: