Show More
@@ -7,6 +7,8 b'' | |||||
7 |
|
7 | |||
8 | from __future__ import absolute_import |
|
8 | from __future__ import absolute_import | |
9 |
|
9 | |||
|
10 | import collections | |||
|
11 | ||||
10 | from .i18n import _ |
|
12 | from .i18n import _ | |
11 | from .node import ( |
|
13 | from .node import ( | |
12 | bin, |
|
14 | bin, | |
@@ -136,6 +138,77 b' def _delayopener(opener, target, buf):' | |||||
136 | return appender(opener, name, mode, buf) |
|
138 | return appender(opener, name, mode, buf) | |
137 | return _delay |
|
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 | class changelog(revlog.revlog): |
|
212 | class changelog(revlog.revlog): | |
140 | def __init__(self, opener): |
|
213 | def __init__(self, opener): | |
141 | revlog.revlog.__init__(self, opener, "00changelog.i") |
|
214 | revlog.revlog.__init__(self, opener, "00changelog.i") | |
@@ -323,42 +396,34 b' class changelog(revlog.revlog):' | |||||
323 | revlog.revlog.checkinlinesize(self, tr, fp) |
|
396 | revlog.revlog.checkinlinesize(self, tr, fp) | |
324 |
|
397 | |||
325 | def read(self, node): |
|
398 | def read(self, node): | |
326 | """ |
|
399 | """Obtain data from a parsed changelog revision. | |
327 | format used: |
|
400 | ||
328 | nodeid\n : manifest node in ascii |
|
401 | Returns a 6-tuple of: | |
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) |
|
|||
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 |
|
|
414 | c = changelogrevision(self.revision(node)) | |
339 | if not text: |
|
415 | return ( | |
340 | return nullid, "", (0, 0), [], "", _defaultextra |
|
416 | c.manifest, | |
341 | last = text.index("\n\n") |
|
417 | c.user, | |
342 | desc = encoding.tolocal(text[last + 2:]) |
|
418 | c.date, | |
343 | l = text[:last].split('\n') |
|
419 | c.files, | |
344 | manifest = bin(l[0]) |
|
420 | c.description, | |
345 | user = encoding.tolocal(l[1]) |
|
421 | c.extra | |
|
422 | ) | |||
346 |
|
423 | |||
347 | tdata = l[2].split(' ', 2) |
|
424 | def changelogrevision(self, nodeorrev): | |
348 | if len(tdata) != 3: |
|
425 | """Obtain a ``changelogrevision`` for a node or revision.""" | |
349 | time = float(tdata[0]) |
|
426 | return changelogrevision(self.revision(nodeorrev)) | |
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 |
|
|||
362 |
|
427 | |||
363 | def readfiles(self, node): |
|
428 | def readfiles(self, node): | |
364 | """ |
|
429 | """ |
General Comments 0
You need to be logged in to leave comments.
Login now