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): |