##// END OF EJS Templates
Add equality operators to changectx and filectx
Matt Mackall -
r3165:e7818574 default
parent child Browse files
Show More
@@ -1,203 +1,209
1 1 # context.py - changeset and file context objects for mercurial
2 2 #
3 3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 from node import *
9 9 from demandload import demandload
10 10 demandload(globals(), "ancestor util")
11 11
12 12 class changectx(object):
13 13 """A changecontext object makes access to data related to a particular
14 14 changeset convenient."""
15 15 def __init__(self, repo, changeid=None):
16 16 """changeid is a revision number, node, or tag"""
17 17 self._repo = repo
18 18
19 19 if not changeid and changeid != 0:
20 20 p1, p2 = self._repo.dirstate.parents()
21 21 self._rev = self._repo.changelog.rev(p1)
22 22 if self._rev == -1:
23 23 changeid = 'tip'
24 24 else:
25 25 self._node = p1
26 26 return
27 27
28 28 self._node = self._repo.lookup(changeid)
29 29 self._rev = self._repo.changelog.rev(self._node)
30 30
31 31 def __repr__(self):
32 32 return "<changectx %s>" % short(self.node())
33 33
34 def __eq__(self, other):
35 return self._rev == other._rev
36
34 37 def changeset(self):
35 38 try:
36 39 return self._changeset
37 40 except AttributeError:
38 41 self._changeset = self._repo.changelog.read(self.node())
39 42 return self._changeset
40 43
41 44 def manifest(self):
42 45 try:
43 46 return self._manifest
44 47 except AttributeError:
45 48 self._manifest = self._repo.manifest.read(self.changeset()[0])
46 49 return self._manifest
47 50
48 51 def rev(self): return self._rev
49 52 def node(self): return self._node
50 53 def user(self): return self.changeset()[1]
51 54 def date(self): return self.changeset()[2]
52 55 def files(self): return self.changeset()[3]
53 56 def description(self): return self.changeset()[4]
54 57
55 58 def parents(self):
56 59 """return contexts for each parent changeset"""
57 60 p = self._repo.changelog.parents(self._node)
58 61 return [ changectx(self._repo, x) for x in p ]
59 62
60 63 def children(self):
61 64 """return contexts for each child changeset"""
62 65 c = self._repo.changelog.children(self._node)
63 66 return [ changectx(self._repo, x) for x in c ]
64 67
65 68 def filenode(self, path):
66 69 node, flag = self._repo.manifest.find(self.changeset()[0], path)
67 70 return node
68 71
69 72 def filectx(self, path, fileid=None):
70 73 """get a file context from this changeset"""
71 74 if fileid is None:
72 75 fileid = self.filenode(path)
73 76 return filectx(self._repo, path, fileid=fileid)
74 77
75 78 def filectxs(self):
76 79 """generate a file context for each file in this changeset's
77 80 manifest"""
78 81 mf = self.manifest()
79 82 m = mf.keys()
80 83 m.sort()
81 84 for f in m:
82 85 yield self.filectx(f, fileid=mf[f])
83 86
84 87 def ancestor(self, c2):
85 88 """
86 89 return the ancestor context of self and c2
87 90 """
88 91 n = self._repo.changelog.ancestor(self._node, c2._node)
89 92 return changectx(self._repo, n)
90 93
91 94 class filectx(object):
92 95 """A filecontext object makes access to data related to a particular
93 96 filerevision convenient."""
94 97 def __init__(self, repo, path, changeid=None, fileid=None, filelog=None):
95 98 """changeid can be a changeset revision, node, or tag.
96 99 fileid can be a file revision or node."""
97 100 self._repo = repo
98 101 self._path = path
99 102
100 103 assert changeid is not None or fileid is not None
101 104
102 105 if filelog:
103 106 self._filelog = filelog
104 107 else:
105 108 self._filelog = self._repo.file(self._path)
106 109
107 110 if fileid is None:
108 111 self._changeid = changeid
109 112 else:
110 113 self._filenode = self._filelog.lookup(fileid)
111 114 self._changeid = self._filelog.linkrev(self._filenode)
112 115
113 116 def __getattr__(self, name):
114 117 if name == '_changectx':
115 118 self._changectx = changectx(self._repo, self._changeid)
116 119 return self._changectx
117 120 elif name == '_filenode':
118 121 self._filenode = self._changectx.filenode(self._path)
119 122 return self._filenode
120 123 elif name == '_filerev':
121 124 self._filerev = self._filelog.rev(self._filenode)
122 125 return self._filerev
123 126 else:
124 127 raise AttributeError, name
125 128
126 129 def __repr__(self):
127 130 return "<filectx %s@%s>" % (self.path(), short(self.node()))
128 131
132 def __eq__(self, other):
133 return self._path == other._path and self._changeid == other._changeid
134
129 135 def filerev(self): return self._filerev
130 136 def filenode(self): return self._filenode
131 137 def filelog(self): return self._filelog
132 138
133 139 def rev(self):
134 140 if hasattr(self, "_changectx"):
135 141 return self._changectx.rev()
136 142 return self._filelog.linkrev(self._filenode)
137 143
138 144 def node(self): return self._changectx.node()
139 145 def user(self): return self._changectx.user()
140 146 def date(self): return self._changectx.date()
141 147 def files(self): return self._changectx.files()
142 148 def description(self): return self._changectx.description()
143 149 def manifest(self): return self._changectx.manifest()
144 150 def changectx(self): return self._changectx
145 151
146 152 def data(self): return self._filelog.read(self._filenode)
147 153 def renamed(self): return self._filelog.renamed(self._filenode)
148 154 def path(self): return self._path
149 155
150 156 def parents(self):
151 157 p = self._path
152 158 fl = self._filelog
153 159 pl = [ (p, n, fl) for n in self._filelog.parents(self._filenode) ]
154 160
155 161 r = self.renamed()
156 162 if r:
157 163 pl[0] = (r[0], r[1], None)
158 164
159 165 return [ filectx(self._repo, p, fileid=n, filelog=l)
160 166 for p,n,l in pl if n != nullid ]
161 167
162 168 def children(self):
163 169 # hard for renames
164 170 c = self._filelog.children(self._filenode)
165 171 return [ filectx(self._repo, self._path, fileid=x,
166 172 filelog=self._filelog) for x in c ]
167 173
168 174 def annotate(self):
169 175 getctx = util.cachefunc(lambda x: filectx(self._repo, self._path,
170 176 changeid=x,
171 177 filelog=self._filelog))
172 178 hist = self._filelog.annotate(self._filenode)
173 179
174 180 return [(getctx(rev), line) for rev, line in hist]
175 181
176 182 def ancestor(self, fc2):
177 183 """
178 184 find the common ancestor file context, if any, of self, and fc2
179 185 """
180 186
181 187 acache = {}
182 188 flcache = {self._path:self._filelog, fc2._path:fc2._filelog}
183 189 def parents(vertex):
184 190 if vertex in acache:
185 191 return acache[vertex]
186 192 f, n = vertex
187 193 if f not in flcache:
188 194 flcache[f] = self._repo.file(f)
189 195 fl = flcache[f]
190 196 pl = [ (f,p) for p in fl.parents(n) if p != nullid ]
191 197 re = fl.renamed(n)
192 198 if re:
193 199 pl.append(re)
194 200 acache[vertex]=pl
195 201 return pl
196 202
197 203 a, b = (self._path, self._filenode), (fc2._path, fc2._filenode)
198 204 v = ancestor.ancestor(a, b, parents)
199 205 if v:
200 206 f,n = v
201 207 return filectx(self._repo, f, fileid=n, filelog=flcache[f])
202 208
203 209 return None
General Comments 0
You need to be logged in to leave comments. Login now