--- a/mercurial/changelog.py Fri Mar 11 11:51:22 2016 -0500
+++ b/mercurial/changelog.py Sun Mar 06 14:28:02 2016 -0800
@@ -7,6 +7,8 @@
from __future__ import absolute_import
+import collections
+
from .i18n import _
from .node import (
bin,
@@ -136,6 +138,77 @@
return appender(opener, name, mode, buf)
return _delay
+_changelogrevision = collections.namedtuple('changelogrevision',
+ ('manifest', 'user', 'date',
+ 'files', 'description', 'extra'))
+
+class changelogrevision(object):
+ """Holds results of a parsed changelog revision.
+
+ Changelog revisions consist of multiple pieces of data, including
+ the manifest node, user, and date. This object exposes a view into
+ the parsed object.
+ """
+
+ __slots__ = (
+ 'date',
+ 'description',
+ 'extra',
+ 'files',
+ 'manifest',
+ 'user',
+ )
+
+ def __new__(cls, text):
+ if not text:
+ return _changelogrevision(
+ manifest=nullid,
+ user='',
+ date=(0, 0),
+ files=[],
+ description='',
+ extra=_defaultextra,
+ )
+
+ self = super(changelogrevision, cls).__new__(cls)
+ # We could return here and implement the following as an __init__.
+ # But doing it here is equivalent and saves an extra function call.
+
+ # format used:
+ # nodeid\n : manifest node in ascii
+ # user\n : user, no \n or \r allowed
+ # time tz extra\n : date (time is int or float, timezone is int)
+ # : extra is metadata, encoded and separated by '\0'
+ # : older versions ignore it
+ # files\n\n : files modified by the cset, no \n or \r allowed
+ # (.*) : comment (free text, ideally utf-8)
+ #
+ # changelog v0 doesn't use extra
+
+ last = text.index("\n\n")
+ self.description = encoding.tolocal(text[last + 2:])
+ l = text[:last].split('\n')
+ self.manifest = bin(l[0])
+ self.user = encoding.tolocal(l[1])
+
+ tdata = l[2].split(' ', 2)
+ if len(tdata) != 3:
+ time = float(tdata[0])
+ try:
+ # various tools did silly things with the time zone field.
+ timezone = int(tdata[1])
+ except ValueError:
+ timezone = 0
+ self.extra = _defaultextra
+ else:
+ time, timezone = float(tdata[0]), int(tdata[1])
+ self.extra = decodeextra(tdata[2])
+
+ self.date = (time, timezone)
+ self.files = l[3:]
+
+ return self
+
class changelog(revlog.revlog):
def __init__(self, opener):
revlog.revlog.__init__(self, opener, "00changelog.i")
@@ -323,42 +396,34 @@
revlog.revlog.checkinlinesize(self, tr, fp)
def read(self, node):
- """
- format used:
- nodeid\n : manifest node in ascii
- user\n : user, no \n or \r allowed
- time tz extra\n : date (time is int or float, timezone is int)
- : extra is metadata, encoded and separated by '\0'
- : older versions ignore it
- files\n\n : files modified by the cset, no \n or \r allowed
- (.*) : comment (free text, ideally utf-8)
+ """Obtain data from a parsed changelog revision.
+
+ Returns a 6-tuple of:
- changelog v0 doesn't use extra
+ - manifest node in binary
+ - author/user as a localstr
+ - date as a 2-tuple of (time, timezone)
+ - list of files
+ - commit message as a localstr
+ - dict of extra metadata
+
+ Unless you need to access all fields, consider calling
+ ``changelogrevision`` instead, as it is faster for partial object
+ access.
"""
- text = self.revision(node)
- if not text:
- return nullid, "", (0, 0), [], "", _defaultextra
- last = text.index("\n\n")
- desc = encoding.tolocal(text[last + 2:])
- l = text[:last].split('\n')
- manifest = bin(l[0])
- user = encoding.tolocal(l[1])
+ c = changelogrevision(self.revision(node))
+ return (
+ c.manifest,
+ c.user,
+ c.date,
+ c.files,
+ c.description,
+ c.extra
+ )
- tdata = l[2].split(' ', 2)
- if len(tdata) != 3:
- time = float(tdata[0])
- try:
- # various tools did silly things with the time zone field.
- timezone = int(tdata[1])
- except ValueError:
- timezone = 0
- extra = _defaultextra
- else:
- time, timezone = float(tdata[0]), int(tdata[1])
- extra = decodeextra(tdata[2])
-
- files = l[3:]
- return manifest, user, (time, timezone), files, desc, extra
+ def changelogrevision(self, nodeorrev):
+ """Obtain a ``changelogrevision`` for a node or revision."""
+ return changelogrevision(self.revision(nodeorrev))
def readfiles(self, node):
"""