Show More
@@ -7,6 +7,8 b'' | |||
|
7 | 7 | |
|
8 | 8 | from __future__ import absolute_import |
|
9 | 9 | |
|
10 | import collections | |
|
11 | ||
|
10 | 12 | from .i18n import _ |
|
11 | 13 | from .node import ( |
|
12 | 14 | bin, |
@@ -136,6 +138,77 b' def _delayopener(opener, target, buf):' | |||
|
136 | 138 | return appender(opener, name, mode, buf) |
|
137 | 139 | return _delay |
|
138 | 140 | |
|
141 | _changelogrevision = collections.namedtuple('changelogrevision', | |
|
142 | ('manifest', 'user', 'date', | |
|
143 | 'files', 'description', 'extra')) | |
|
144 | ||
|
145 | class changelogrevision(object): | |
|
146 | """Holds results of a parsed changelog revision. | |
|
147 | ||
|
148 | Changelog revisions consist of multiple pieces of data, including | |
|
149 | the manifest node, user, and date. This object exposes a view into | |
|
150 | the parsed object. | |
|
151 | """ | |
|
152 | ||
|
153 | __slots__ = ( | |
|
154 | 'date', | |
|
155 | 'description', | |
|
156 | 'extra', | |
|
157 | 'files', | |
|
158 | 'manifest', | |
|
159 | 'user', | |
|
160 | ) | |
|
161 | ||
|
162 | def __new__(cls, text): | |
|
163 | if not text: | |
|
164 | return _changelogrevision( | |
|
165 | manifest=nullid, | |
|
166 | user='', | |
|
167 | date=(0, 0), | |
|
168 | files=[], | |
|
169 | description='', | |
|
170 | extra=_defaultextra, | |
|
171 | ) | |
|
172 | ||
|
173 | self = super(changelogrevision, cls).__new__(cls) | |
|
174 | # We could return here and implement the following as an __init__. | |
|
175 | # But doing it here is equivalent and saves an extra function call. | |
|
176 | ||
|
177 | # format used: | |
|
178 | # nodeid\n : manifest node in ascii | |
|
179 | # user\n : user, no \n or \r allowed | |
|
180 | # time tz extra\n : date (time is int or float, timezone is int) | |
|
181 | # : extra is metadata, encoded and separated by '\0' | |
|
182 | # : older versions ignore it | |
|
183 | # files\n\n : files modified by the cset, no \n or \r allowed | |
|
184 | # (.*) : comment (free text, ideally utf-8) | |
|
185 | # | |
|
186 | # changelog v0 doesn't use extra | |
|
187 | ||
|
188 | last = text.index("\n\n") | |
|
189 | self.description = encoding.tolocal(text[last + 2:]) | |
|
190 | l = text[:last].split('\n') | |
|
191 | self.manifest = bin(l[0]) | |
|
192 | self.user = encoding.tolocal(l[1]) | |
|
193 | ||
|
194 | tdata = l[2].split(' ', 2) | |
|
195 | if len(tdata) != 3: | |
|
196 | time = float(tdata[0]) | |
|
197 | try: | |
|
198 | # various tools did silly things with the time zone field. | |
|
199 | timezone = int(tdata[1]) | |
|
200 | except ValueError: | |
|
201 | timezone = 0 | |
|
202 | self.extra = _defaultextra | |
|
203 | else: | |
|
204 | time, timezone = float(tdata[0]), int(tdata[1]) | |
|
205 | self.extra = decodeextra(tdata[2]) | |
|
206 | ||
|
207 | self.date = (time, timezone) | |
|
208 | self.files = l[3:] | |
|
209 | ||
|
210 | return self | |
|
211 | ||
|
139 | 212 | class changelog(revlog.revlog): |
|
140 | 213 | def __init__(self, opener): |
|
141 | 214 | revlog.revlog.__init__(self, opener, "00changelog.i") |
@@ -323,42 +396,34 b' class changelog(revlog.revlog):' | |||
|
323 | 396 | revlog.revlog.checkinlinesize(self, tr, fp) |
|
324 | 397 | |
|
325 | 398 | def read(self, node): |
|
326 | """ | |
|
327 | format used: | |
|
328 | nodeid\n : manifest node in ascii | |
|
329 | user\n : user, no \n or \r allowed | |
|
330 | time tz extra\n : date (time is int or float, timezone is int) | |
|
331 | : extra is metadata, encoded and separated by '\0' | |
|
332 | : older versions ignore it | |
|
333 | files\n\n : files modified by the cset, no \n or \r allowed | |
|
334 | (.*) : comment (free text, ideally utf-8) | |
|
399 | """Obtain data from a parsed changelog revision. | |
|
400 | ||
|
401 | Returns a 6-tuple of: | |
|
335 | 402 | |
|
336 | changelog v0 doesn't use extra | |
|
403 | - manifest node in binary | |
|
404 | - author/user as a localstr | |
|
405 | - date as a 2-tuple of (time, timezone) | |
|
406 | - list of files | |
|
407 | - commit message as a localstr | |
|
408 | - dict of extra metadata | |
|
409 | ||
|
410 | Unless you need to access all fields, consider calling | |
|
411 | ``changelogrevision`` instead, as it is faster for partial object | |
|
412 | access. | |
|
337 | 413 | """ |
|
338 |
|
|
|
339 | if not text: | |
|
340 | return nullid, "", (0, 0), [], "", _defaultextra | |
|
341 | last = text.index("\n\n") | |
|
342 | desc = encoding.tolocal(text[last + 2:]) | |
|
343 | l = text[:last].split('\n') | |
|
344 | manifest = bin(l[0]) | |
|
345 | user = encoding.tolocal(l[1]) | |
|
414 | c = changelogrevision(self.revision(node)) | |
|
415 | return ( | |
|
416 | c.manifest, | |
|
417 | c.user, | |
|
418 | c.date, | |
|
419 | c.files, | |
|
420 | c.description, | |
|
421 | c.extra | |
|
422 | ) | |
|
346 | 423 | |
|
347 | tdata = l[2].split(' ', 2) | |
|
348 | if len(tdata) != 3: | |
|
349 | time = float(tdata[0]) | |
|
350 | try: | |
|
351 | # various tools did silly things with the time zone field. | |
|
352 | timezone = int(tdata[1]) | |
|
353 | except ValueError: | |
|
354 | timezone = 0 | |
|
355 | extra = _defaultextra | |
|
356 | else: | |
|
357 | time, timezone = float(tdata[0]), int(tdata[1]) | |
|
358 | extra = decodeextra(tdata[2]) | |
|
359 | ||
|
360 | files = l[3:] | |
|
361 | return manifest, user, (time, timezone), files, desc, extra | |
|
424 | def changelogrevision(self, nodeorrev): | |
|
425 | """Obtain a ``changelogrevision`` for a node or revision.""" | |
|
426 | return changelogrevision(self.revision(nodeorrev)) | |
|
362 | 427 | |
|
363 | 428 | def readfiles(self, node): |
|
364 | 429 | """ |
General Comments 0
You need to be logged in to leave comments.
Login now