changelog.py
107 lines
| 3.7 KiB
| text/x-python
|
PythonLexer
/ mercurial / changelog.py
mpm@selenic.com
|
r1095 | # changelog.py - changelog class for mercurial | ||
mpm@selenic.com
|
r1089 | # | ||
Vadim Gelfer
|
r2859 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | ||
mpm@selenic.com
|
r1089 | # | ||
# This software may be used and distributed according to the terms | ||||
# of the GNU General Public License, incorporated herein by reference. | ||||
from revlog import * | ||||
Benoit Boissinot
|
r1400 | from i18n import gettext as _ | ||
Bryan O'Sullivan
|
r1321 | from demandload import demandload | ||
demandload(globals(), "os time util") | ||||
mpm@selenic.com
|
r1089 | |||
Benoit Boissinot
|
r3232 | def _string_escape(text): | ||
""" | ||||
>>> d = {'nl': chr(10), 'bs': chr(92), 'cr': chr(13), 'nul': chr(0)} | ||||
>>> s = "ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d | ||||
>>> s | ||||
'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n' | ||||
>>> res = _string_escape(s) | ||||
>>> s == _string_unescape(res) | ||||
True | ||||
""" | ||||
# subset of the string_escape codec | ||||
text = text.replace('\\', '\\\\').replace('\n', '\\n').replace('\r', '\\r') | ||||
return text.replace('\0', '\\0') | ||||
def _string_unescape(text): | ||||
return text.decode('string_escape') | ||||
mpm@selenic.com
|
r1089 | class changelog(revlog): | ||
Thomas Arendsen Hein
|
r2142 | def __init__(self, opener, defversion=REVLOGV0): | ||
mason@suse.com
|
r2072 | revlog.__init__(self, opener, "00changelog.i", "00changelog.d", | ||
defversion) | ||||
mpm@selenic.com
|
r1089 | |||
Benoit Boissinot
|
r3233 | def decode_extra(self, text): | ||
extra = {} | ||||
for l in text.split('\0'): | ||||
if not l: | ||||
continue | ||||
k, v = _string_unescape(l).split(':', 1) | ||||
extra[k] = v | ||||
return extra | ||||
def encode_extra(self, d): | ||||
items = [_string_escape(":".join(t)) for t in d.iteritems()] | ||||
return "\0".join(items) | ||||
mpm@selenic.com
|
r1089 | def extract(self, text): | ||
Benoit Boissinot
|
r3077 | """ | ||
format used: | ||||
Benoit Boissinot
|
r3233 | 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 metadatas, 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 | ||||
Benoit Boissinot
|
r3077 | """ | ||
mpm@selenic.com
|
r1089 | if not text: | ||
Alexis S. L. Carvalho
|
r4176 | return (nullid, "", (0, 0), [], "", {'branch': 'default'}) | ||
mpm@selenic.com
|
r1089 | last = text.index("\n\n") | ||
Matt Mackall
|
r3771 | desc = util.tolocal(text[last + 2:]) | ||
Benoit Boissinot
|
r3233 | l = text[:last].split('\n') | ||
mpm@selenic.com
|
r1089 | manifest = bin(l[0]) | ||
Matt Mackall
|
r3771 | user = util.tolocal(l[1]) | ||
Benoit Boissinot
|
r3233 | |||
extra_data = l[2].split(' ', 2) | ||||
if len(extra_data) != 3: | ||||
time = float(extra_data.pop(0)) | ||||
try: | ||||
# various tools did silly things with the time zone field. | ||||
timezone = int(extra_data[0]) | ||||
except: | ||||
timezone = 0 | ||||
extra = {} | ||||
else: | ||||
time, timezone, extra = extra_data | ||||
time, timezone = float(time), int(timezone) | ||||
extra = self.decode_extra(extra) | ||||
Alexis S. L. Carvalho
|
r4176 | if not extra.get('branch'): | ||
extra['branch'] = 'default' | ||||
mpm@selenic.com
|
r1089 | files = l[3:] | ||
Benoit Boissinot
|
r3233 | return (manifest, user, (time, timezone), files, desc, extra) | ||
mpm@selenic.com
|
r1089 | |||
def read(self, node): | ||||
return self.extract(self.revision(node)) | ||||
def add(self, manifest, list, desc, transaction, p1=None, p2=None, | ||||
Benoit Boissinot
|
r3233 | user=None, date=None, extra={}): | ||
Matt Mackall
|
r3771 | user, desc = util.fromlocal(user), util.fromlocal(desc) | ||
Bryan O'Sullivan
|
r1195 | if date: | ||
Benoit Boissinot
|
r2523 | parseddate = "%d %d" % util.parsedate(date) | ||
Bryan O'Sullivan
|
r1195 | else: | ||
Jose M. Prieto
|
r2522 | parseddate = "%d %d" % util.makedate() | ||
Alexis S. L. Carvalho
|
r4176 | if extra and extra.get("branch") in ("default", ""): | ||
del extra["branch"] | ||||
Benoit Boissinot
|
r3233 | if extra: | ||
extra = self.encode_extra(extra) | ||||
parseddate = "%s %s" % (parseddate, extra) | ||||
mpm@selenic.com
|
r1089 | list.sort() | ||
Jose M. Prieto
|
r2522 | l = [hex(manifest), user, parseddate] + list + ["", desc] | ||
mpm@selenic.com
|
r1089 | text = "\n".join(l) | ||
return self.addrevision(text, transaction, self.count(), p1, p2) | ||||