comparison 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
comparison
equal deleted inserted replaced
16375:d7d64b89a65c 16376:d3908c911d5e
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com> 3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 # 4 #
5 # This software may be used and distributed according to the terms of the 5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 from node import nullid, nullrev, short, hex 8 from node import nullid, nullrev, short, hex, bin
9 from i18n import _ 9 from i18n import _
10 import ancestor, mdiff, error, util, scmutil, subrepo, patch, encoding, phases 10 import ancestor, mdiff, error, util, scmutil, subrepo, patch, encoding, phases
11 import match as matchmod 11 import match as matchmod
12 import os, errno, stat 12 import os, errno, stat
13 13
19 def __init__(self, repo, changeid=''): 19 def __init__(self, repo, changeid=''):
20 """changeid is a revision number, node, or tag""" 20 """changeid is a revision number, node, or tag"""
21 if changeid == '': 21 if changeid == '':
22 changeid = '.' 22 changeid = '.'
23 self._repo = repo 23 self._repo = repo
24 if isinstance(changeid, (long, int)): 24
25 if isinstance(changeid, int):
25 self._rev = changeid 26 self._rev = changeid
26 self._node = self._repo.changelog.node(changeid) 27 self._node = repo.changelog.node(changeid)
27 else: 28 return
28 self._node = self._repo.lookup(changeid) 29 if changeid == '.':
29 self._rev = self._repo.changelog.rev(self._node) 30 self._node = repo.dirstate.p1()
31 self._rev = repo.changelog.rev(self._node)
32 return
33 if changeid == 'null':
34 self._node = nullid
35 self._rev = nullrev
36 return
37 if changeid == 'tip':
38 self._rev = len(repo.changelog) - 1
39 self._node = repo.changelog.node(self._rev)
40 return
41 if len(changeid) == 20:
42 try:
43 self._node = changeid
44 self._rev = repo.changelog.rev(changeid)
45 return
46 except LookupError:
47 pass
48
49 try:
50 r = int(changeid)
51 if str(r) != changeid:
52 raise ValueError
53 l = len(repo.changelog)
54 if r < 0:
55 r += l
56 if r < 0 or r >= l:
57 raise ValueError
58 self._rev = r
59 self._node = repo.changelog.node(r)
60 return
61 except (ValueError, OverflowError):
62 pass
63
64 if len(changeid) == 40:
65 try:
66 self._node = bin(changeid)
67 self._rev = repo.changelog.rev(self._node)
68 return
69 except (TypeError, LookupError):
70 pass
71
72 if changeid in repo._bookmarks:
73 self._node = repo._bookmarks[changeid]
74 self._rev = repo.changelog.rev(self._node)
75 return
76 if changeid in repo._tagscache.tags:
77 self._node = repo._tagscache.tags[changeid]
78 self._rev = repo.changelog.rev(self._node)
79 return
80 if changeid in repo.branchtags():
81 self._node = repo.branchtags()[changeid]
82 self._rev = repo.changelog.rev(self._node)
83 return
84
85 self._node = repo.changelog._partialmatch(changeid)
86 if self._node is not None:
87 self._rev = repo.changelog.rev(self._node)
88 return
89
90 # lookup failed
91 # check if it might have come from damaged dirstate
92 if changeid in repo.dirstate.parents():
93 raise error.Abort(_("working directory has unknown parent '%s'!")
94 % short(changeid))
95 try:
96 if len(changeid) == 20:
97 changeid = hex(changeid)
98 except TypeError:
99 pass
100 raise error.RepoLookupError(
101 _("unknown revision '%s'") % changeid)
30 102
31 def __str__(self): 103 def __str__(self):
32 return short(self.node()) 104 return short(self.node())
33 105
34 def __int__(self): 106 def __int__(self):