Mercurial > hg
diff mercurial/localrepo.py @ 39958:3d35304bd09b
context: move logic from changectx.__init__ to localrepo.__getitem__ (API)
My motivation for this change was to make repo[node] not load the
dirstate (more about that in the next patch), but I think it makes
more sense this way too. For example, raising RepoLookupError seems to
belong better in the repo lookup function
(i.e. localrepo.__getitem__).
This makes the changectx constructor very simple -- it just assigns
the given repo, revnum, and nodeid to properties.
Differential Revision: https://phab.mercurial-scm.org/D4827
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Wed, 26 Sep 2018 22:53:14 -0700 |
parents | e1e3d1b498d3 |
children | 43d3b09b3e5a |
line wrap: on
line diff
--- a/mercurial/localrepo.py Wed Sep 26 22:44:51 2018 -0700 +++ b/mercurial/localrepo.py Wed Sep 26 22:53:14 2018 -0700 @@ -17,8 +17,10 @@ from .i18n import _ from .node import ( + bin, hex, nullid, + nullrev, short, ) from . import ( @@ -1214,9 +1216,67 @@ for i in pycompat.xrange(*changeid.indices(len(self))) if i not in self.changelog.filteredrevs] try: - return context.changectx(self, changeid) + if isinstance(changeid, int): + node = self.changelog.node(changeid) + rev = changeid + return context.changectx(self, rev, node) + elif changeid == 'null': + node = nullid + rev = nullrev + return context.changectx(self, rev, node) + elif changeid == 'tip': + node = self.changelog.tip() + rev = self.changelog.rev(node) + return context.changectx(self, rev, node) + elif (changeid == '.' + or self.local() and changeid == self.dirstate.p1()): + # this is a hack to delay/avoid loading obsmarkers + # when we know that '.' won't be hidden + node = self.dirstate.p1() + rev = self.unfiltered().changelog.rev(node) + return context.changectx(self, rev, node) + elif len(changeid) == 20: + try: + node = changeid + rev = self.changelog.rev(changeid) + return context.changectx(self, rev, node) + except error.FilteredLookupError: + changeid = hex(changeid) # for the error message + raise + except LookupError: + # check if it might have come from damaged dirstate + # + # XXX we could avoid the unfiltered if we had a recognizable + # exception for filtered changeset access + if (self.local() + and changeid in self.unfiltered().dirstate.parents()): + msg = _("working directory has unknown parent '%s'!") + raise error.Abort(msg % short(changeid)) + changeid = hex(changeid) # for the error message + + elif len(changeid) == 40: + try: + node = bin(changeid) + rev = self.changelog.rev(node) + return context.changectx(self, rev, node) + except error.FilteredLookupError: + raise + except LookupError: + pass + else: + raise error.ProgrammingError( + "unsupported changeid '%s' of type %s" % + (changeid, type(changeid))) + + except (error.FilteredIndexError, error.FilteredLookupError): + raise error.FilteredRepoLookupError(_("filtered revision '%s'") + % pycompat.bytestr(changeid)) + except IndexError: + pass except error.WdirUnsupported: return context.workingctx(self) + raise error.RepoLookupError( + _("unknown revision '%s'") % changeid) def __contains__(self, changeid): """True if the given changeid exists