Mercurial > hg-stable
diff mercurial/context.py @ 16376:d3908c911d5e
context: internalize lookup logic
This allows us to avoid doing rev->node->rev lookups on silly
instances like "0", which end up caching the whole nodemap.
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sun, 08 Apr 2012 12:38:07 -0500 |
parents | 329887a7074c |
children | f8ce254e514f |
line wrap: on
line diff
--- a/mercurial/context.py Sun Apr 08 12:38:02 2012 -0500 +++ b/mercurial/context.py Sun Apr 08 12:38:07 2012 -0500 @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -from node import nullid, nullrev, short, hex +from node import nullid, nullrev, short, hex, bin from i18n import _ import ancestor, mdiff, error, util, scmutil, subrepo, patch, encoding, phases import match as matchmod @@ -21,12 +21,84 @@ if changeid == '': changeid = '.' self._repo = repo - if isinstance(changeid, (long, int)): + + if isinstance(changeid, int): self._rev = changeid - self._node = self._repo.changelog.node(changeid) - else: - self._node = self._repo.lookup(changeid) - self._rev = self._repo.changelog.rev(self._node) + self._node = repo.changelog.node(changeid) + return + if changeid == '.': + self._node = repo.dirstate.p1() + self._rev = repo.changelog.rev(self._node) + return + if changeid == 'null': + self._node = nullid + self._rev = nullrev + return + if changeid == 'tip': + self._rev = len(repo.changelog) - 1 + self._node = repo.changelog.node(self._rev) + return + if len(changeid) == 20: + try: + self._node = changeid + self._rev = repo.changelog.rev(changeid) + return + except LookupError: + pass + + try: + r = int(changeid) + if str(r) != changeid: + raise ValueError + l = len(repo.changelog) + if r < 0: + r += l + if r < 0 or r >= l: + raise ValueError + self._rev = r + self._node = repo.changelog.node(r) + return + except (ValueError, OverflowError): + pass + + if len(changeid) == 40: + try: + self._node = bin(changeid) + self._rev = repo.changelog.rev(self._node) + return + except (TypeError, LookupError): + pass + + if changeid in repo._bookmarks: + self._node = repo._bookmarks[changeid] + self._rev = repo.changelog.rev(self._node) + return + if changeid in repo._tagscache.tags: + self._node = repo._tagscache.tags[changeid] + self._rev = repo.changelog.rev(self._node) + return + if changeid in repo.branchtags(): + self._node = repo.branchtags()[changeid] + self._rev = repo.changelog.rev(self._node) + return + + self._node = repo.changelog._partialmatch(changeid) + if self._node is not None: + self._rev = repo.changelog.rev(self._node) + return + + # lookup failed + # check if it might have come from damaged dirstate + if changeid in repo.dirstate.parents(): + raise error.Abort(_("working directory has unknown parent '%s'!") + % short(changeid)) + try: + if len(changeid) == 20: + changeid = hex(changeid) + except TypeError: + pass + raise error.RepoLookupError( + _("unknown revision '%s'") % changeid) def __str__(self): return short(self.node())