mercurial/changelog.py
author Dirkjan Ochtman <dirkjan@ochtman.nl>
Mon, 27 Apr 2009 11:37:30 +0200
changeset 8216 25266fe996b0
parent 8209 a1a5a57efe90
child 8225 46293a0c7e9f
permissions -rw-r--r--
hgweb: use new sessionvars code in hgwebdir, too
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1095
0a18374c0769 changelog: adjust imports, comment
mpm@selenic.com
parents: 1094 1089
diff changeset
     1
# changelog.py - changelog class for mercurial
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     2
#
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4269
diff changeset
     3
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     4
#
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     7
6211
f89fd07fc51d Expand import * to allow Pyflakes to find problems
Joel Rosdahl <joel@rosdahl.net>
parents: 5791
diff changeset
     8
from node import bin, hex, nullid
7035
9d023ef7b467 forbid username with '\n' at the changelog level
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6259
diff changeset
     9
from i18n import _
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7807
diff changeset
    10
import util, error, revlog, encoding
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    11
3232
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    12
def _string_escape(text):
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    13
    """
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    14
    >>> d = {'nl': chr(10), 'bs': chr(92), 'cr': chr(13), 'nul': chr(0)}
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    15
    >>> s = "ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    16
    >>> s
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    17
    'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n'
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    18
    >>> res = _string_escape(s)
5745
234e40e636a8 changelog: inline trivial call for extra data unescaping
Matt Mackall <mpm@selenic.com>
parents: 5744
diff changeset
    19
    >>> s == res.decode('string_escape')
3232
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    20
    True
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    21
    """
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    22
    # subset of the string_escape codec
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    23
    text = text.replace('\\', '\\\\').replace('\n', '\\n').replace('\r', '\\r')
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    24
    return text.replace('\0', '\\0')
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    25
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    26
class appender:
7807
bd8f44638847 help: miscellaneous language fixes
timeless <timeless@gmail.com>
parents: 7787
diff changeset
    27
    '''the changelog index must be updated last on disk, so we use this class
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    28
    to delay writes to it'''
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    29
    def __init__(self, fp, buf):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    30
        self.data = buf
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    31
        self.fp = fp
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    32
        self.offset = fp.tell()
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    33
        self.size = util.fstat(fp).st_size
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    34
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    35
    def end(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    36
        return self.size + len("".join(self.data))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    37
    def tell(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    38
        return self.offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    39
    def flush(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    40
        pass
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    41
    def close(self):
4961
3fdd09ad6cce fix bogus close spotted by pychecker (no close() in global scope)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 4635
diff changeset
    42
        self.fp.close()
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    43
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    44
    def seek(self, offset, whence=0):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    45
        '''virtual file offset spans real file and data'''
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    46
        if whence == 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    47
            self.offset = offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    48
        elif whence == 1:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    49
            self.offset += offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    50
        elif whence == 2:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    51
            self.offset = self.end() + offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    52
        if self.offset < self.size:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    53
            self.fp.seek(self.offset)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    54
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    55
    def read(self, count=-1):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    56
        '''only trick here is reads that span real file and data'''
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    57
        ret = ""
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    58
        if self.offset < self.size:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    59
            s = self.fp.read(count)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    60
            ret = s
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    61
            self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    62
            if count > 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    63
                count -= len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    64
        if count != 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    65
            doff = self.offset - self.size
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    66
            self.data.insert(0, "".join(self.data))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    67
            del self.data[1:]
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    68
            s = self.data[0][doff:doff+count]
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    69
            self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    70
            ret += s
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    71
        return ret
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    72
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    73
    def write(self, s):
5450
c728424d44c6 revlog: fix caching of buffer objects
Matt Mackall <mpm@selenic.com>
parents: 4963
diff changeset
    74
        self.data.append(str(s))
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    75
        self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    76
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
    77
class changelog(revlog.revlog):
4258
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 4257
diff changeset
    78
    def __init__(self, opener):
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
    79
        revlog.revlog.__init__(self, opener, "00changelog.i")
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    80
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    81
    def delayupdate(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    82
        "delay visibility of index updates to other readers"
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    83
        self._realopener = self.opener
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
    84
        self.opener = self._delayopener
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6259
diff changeset
    85
        self._delaycount = len(self)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    86
        self._delaybuf = []
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
    87
        self._delayname = None
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    88
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    89
    def finalize(self, tr):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    90
        "finalize index updates"
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    91
        self.opener = self._realopener
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
    92
        # move redirected index data back into place
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
    93
        if self._delayname:
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
    94
            util.rename(self._delayname + ".a", self._delayname)
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
    95
        elif self._delaybuf:
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    96
            fp = self.opener(self.indexfile, 'a')
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    97
            fp.write("".join(self._delaybuf))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    98
            fp.close()
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
    99
            self._delaybuf = []
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   100
        # split when we're done
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   101
        self.checkinlinesize(tr)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   102
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   103
    def _delayopener(self, name, mode='r'):
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   104
        fp = self._realopener(name, mode)
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   105
        # only divert the index
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   106
        if not name == self.indexfile:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   107
            return fp
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   108
        # if we're doing an initial clone, divert to another file
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   109
        if self._delaycount == 0:
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   110
            self._delayname = fp.name
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6259
diff changeset
   111
            if not len(self):
6259
d60aa0308b02 make sure not to reuse an existing append-file from a previous failed pull
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6212
diff changeset
   112
                # make sure to truncate the file
d60aa0308b02 make sure not to reuse an existing append-file from a previous failed pull
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6212
diff changeset
   113
                mode = mode.replace('a', 'w')
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   114
            return self._realopener(name + ".a", mode)
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   115
        # otherwise, divert to memory
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   116
        return appender(fp, self._delaybuf)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   117
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   118
    def readpending(self, file):
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   119
        r = revlog.revlog(self.opener, file)
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   120
        self.index = r.index
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   121
        self.nodemap = r.nodemap
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   122
        self._chunkcache = r._chunkcache
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   123
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   124
    def writepending(self):
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   125
        "create a file containing the unfinalized state for pretxnchangegroup"
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   126
        if self._delaybuf:
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   127
            # make a temporary copy of the index
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   128
            fp1 = self._realopener(self.indexfile)
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   129
            fp2 = self._realopener(self.indexfile + ".a", "w")
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   130
            fp2.write(fp1.read())
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   131
            # add pending data
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   132
            fp2.write("".join(self._delaybuf))
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   133
            fp2.close()
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   134
            # switch modes so finalize can simply rename
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   135
            self._delaybuf = []
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   136
            self._delayname = fp1.name
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   137
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   138
        if self._delayname:
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   139
            return True
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   140
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   141
        return False
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   142
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   143
    def checkinlinesize(self, tr, fp=None):
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   144
        if self.opener == self._delayopener:
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   145
            return
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   146
        return revlog.revlog.checkinlinesize(self, tr, fp)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   147
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   148
    def decode_extra(self, text):
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   149
        extra = {}
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   150
        for l in text.split('\0'):
5745
234e40e636a8 changelog: inline trivial call for extra data unescaping
Matt Mackall <mpm@selenic.com>
parents: 5744
diff changeset
   151
            if l:
5791
d09ccdbf7286 changelog: fix decoding of extra
Matt Mackall <mpm@selenic.com>
parents: 5745
diff changeset
   152
                k, v = l.decode('string_escape').split(':', 1)
5745
234e40e636a8 changelog: inline trivial call for extra data unescaping
Matt Mackall <mpm@selenic.com>
parents: 5744
diff changeset
   153
                extra[k] = v
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   154
        return extra
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   155
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   156
    def encode_extra(self, d):
4847
845e0071b704 Sort changelog extra dict to avoid possible nondeterminism
Brendan Cully <brendan@kublai.com>
parents: 4635
diff changeset
   157
        # keys must be sorted to produce a deterministic changelog entry
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 7948
diff changeset
   158
        items = [_string_escape('%s:%s' % (k, d[k])) for k in sorted(d)]
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   159
        return "\0".join(items)
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   160
5744
9db7fd77417d changelog: remove extract function
Matt Mackall <mpm@selenic.com>
parents: 5450
diff changeset
   161
    def read(self, node):
3077
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
   162
        """
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
   163
        format used:
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   164
        nodeid\n        : manifest node in ascii
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   165
        user\n          : user, no \n or \r allowed
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   166
        time tz extra\n : date (time is int or float, timezone is int)
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   167
                        : extra is metadatas, encoded and separated by '\0'
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   168
                        : older versions ignore it
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   169
        files\n\n       : files modified by the cset, no \n or \r allowed
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   170
        (.*)            : comment (free text, ideally utf-8)
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   171
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   172
        changelog v0 doesn't use extra
3077
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
   173
        """
5744
9db7fd77417d changelog: remove extract function
Matt Mackall <mpm@selenic.com>
parents: 5450
diff changeset
   174
        text = self.revision(node)
37
a8811676c85a Move hex/bin bits to revlog
mpm@selenic.com
parents: 33
diff changeset
   175
        if not text:
4176
f9bbcebcacea "default" is the default branch name
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3771
diff changeset
   176
            return (nullid, "", (0, 0), [], "", {'branch': 'default'})
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   177
        last = text.index("\n\n")
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7807
diff changeset
   178
        desc = encoding.tolocal(text[last + 2:])
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   179
        l = text[:last].split('\n')
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   180
        manifest = bin(l[0])
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7807
diff changeset
   181
        user = encoding.tolocal(l[1])
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   182
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   183
        extra_data = l[2].split(' ', 2)
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   184
        if len(extra_data) != 3:
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   185
            time = float(extra_data.pop(0))
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   186
            try:
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   187
                # various tools did silly things with the time zone field.
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   188
                timezone = int(extra_data[0])
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   189
            except:
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   190
                timezone = 0
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   191
            extra = {}
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   192
        else:
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   193
            time, timezone, extra = extra_data
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   194
            time, timezone = float(time), int(timezone)
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   195
            extra = self.decode_extra(extra)
4176
f9bbcebcacea "default" is the default branch name
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3771
diff changeset
   196
        if not extra.get('branch'):
f9bbcebcacea "default" is the default branch name
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3771
diff changeset
   197
            extra['branch'] = 'default'
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   198
        files = l[3:]
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   199
        return (manifest, user, (time, timezone), files, desc, extra)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   200
6762
f67d1468ac50 util: add sort helper
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   201
    def add(self, manifest, files, desc, transaction, p1=None, p2=None,
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   202
                  user=None, date=None, extra={}):
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   203
7035
9d023ef7b467 forbid username with '\n' at the changelog level
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6259
diff changeset
   204
        user = user.strip()
9d023ef7b467 forbid username with '\n' at the changelog level
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6259
diff changeset
   205
        if "\n" in user:
7633
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7470
diff changeset
   206
            raise error.RevlogError(_("username %s contains a newline")
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7470
diff changeset
   207
                                    % repr(user))
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7807
diff changeset
   208
        user, desc = encoding.fromlocal(user), encoding.fromlocal(desc)
3771
29d91e57d055 Handle transcoding of username and description in changelog
Matt Mackall <mpm@selenic.com>
parents: 3412
diff changeset
   209
1195
f92af8d53330 Validate user input of dates when adding a changelog entry.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1095
diff changeset
   210
        if date:
2523
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
   211
            parseddate = "%d %d" % util.parsedate(date)
1195
f92af8d53330 Validate user input of dates when adding a changelog entry.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1095
diff changeset
   212
        else:
2522
85f796baab10 Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents: 2142
diff changeset
   213
            parseddate = "%d %d" % util.makedate()
4176
f9bbcebcacea "default" is the default branch name
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3771
diff changeset
   214
        if extra and extra.get("branch") in ("default", ""):
f9bbcebcacea "default" is the default branch name
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3771
diff changeset
   215
            del extra["branch"]
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   216
        if extra:
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   217
            extra = self.encode_extra(extra)
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   218
            parseddate = "%s %s" % (parseddate, extra)
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 7948
diff changeset
   219
        l = [hex(manifest), user, parseddate] + sorted(files) + ["", desc]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   220
        text = "\n".join(l)
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6259
diff changeset
   221
        return self.addrevision(text, transaction, len(self), p1, p2)