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