mercurial/changelog.py
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
Thu, 16 Jun 2011 01:57:53 +0200
changeset 14643 7e295dd10d40
parent 14380 10546bb7d201
child 15661 20ae902c43ec
permissions -rw-r--r--
hidden: Add a hiddenrevs attributes to changelog. This attributes hold the set of all revisions that should be ommited by command and tools displaying changesets. This set is given as a hit. Command and tools are responsible to check it in order to filter they outpur. Code adding revisions to the set are responsible to the consistency of it's data.
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
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9677
diff changeset
     6
# GNU General Public License version 2 or any later version.
0
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
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    26
def decodeextra(text):
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    27
    extra = {}
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    28
    for l in text.split('\0'):
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    29
        if l:
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    30
            k, v = l.decode('string_escape').split(':', 1)
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    31
            extra[k] = v
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    32
    return extra
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    33
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    34
def encodeextra(d):
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    35
    # keys must be sorted to produce a deterministic changelog entry
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    36
    items = [_string_escape('%s:%s' % (k, d[k])) for k in sorted(d)]
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    37
    return "\0".join(items)
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    38
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8644
diff changeset
    39
class appender(object):
7807
bd8f44638847 help: miscellaneous language fixes
timeless <timeless@gmail.com>
parents: 7787
diff changeset
    40
    '''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
    41
    to delay writes to it'''
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    42
    def __init__(self, fp, buf):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    43
        self.data = buf
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    44
        self.fp = fp
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    45
        self.offset = fp.tell()
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    46
        self.size = util.fstat(fp).st_size
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    47
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    48
    def end(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    49
        return self.size + len("".join(self.data))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    50
    def tell(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    51
        return self.offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    52
    def flush(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    53
        pass
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    54
    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
    55
        self.fp.close()
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    56
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    57
    def seek(self, offset, whence=0):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    58
        '''virtual file offset spans real file and data'''
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    59
        if whence == 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    60
            self.offset = offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    61
        elif whence == 1:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    62
            self.offset += offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    63
        elif whence == 2:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    64
            self.offset = self.end() + offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    65
        if self.offset < self.size:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    66
            self.fp.seek(self.offset)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    67
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    68
    def read(self, count=-1):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    69
        '''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
    70
        ret = ""
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    71
        if self.offset < self.size:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    72
            s = self.fp.read(count)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    73
            ret = s
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    74
            self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    75
            if count > 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    76
                count -= len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    77
        if count != 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    78
            doff = self.offset - self.size
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    79
            self.data.insert(0, "".join(self.data))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    80
            del self.data[1:]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    81
            s = self.data[0][doff:doff + count]
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    82
            self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    83
            ret += s
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    84
        return ret
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    85
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    86
    def write(self, s):
5450
c728424d44c6 revlog: fix caching of buffer objects
Matt Mackall <mpm@selenic.com>
parents: 4963
diff changeset
    87
        self.data.append(str(s))
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    88
        self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    89
9166
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
    90
def delayopener(opener, target, divert, buf):
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
    91
    def o(name, mode='r'):
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
    92
        if name != target:
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
    93
            return opener(name, mode)
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
    94
        if divert:
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
    95
            return opener(name + ".a", mode.replace('a', 'w'))
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
    96
        # otherwise, divert to memory
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
    97
        return appender(opener(name, mode), buf)
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
    98
    return o
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
    99
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   100
class changelog(revlog.revlog):
4258
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 4257
diff changeset
   101
    def __init__(self, opener):
9165
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
   102
        revlog.revlog.__init__(self, opener, "00changelog.i")
14334
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
   103
        if self._initempty:
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
   104
            # changelogs don't benefit from generaldelta
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
   105
            self.version &= ~revlog.REVLOGGENERALDELTA
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
   106
            self._generaldelta = False
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
   107
        self._realopener = opener
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
   108
        self._delayed = False
9163
f193b643d1b1 changelog: _delaycount -> _divert
Matt Mackall <mpm@selenic.com>
parents: 8778
diff changeset
   109
        self._divert = False
14643
7e295dd10d40 hidden: Add a hiddenrevs attributes to changelog.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14380
diff changeset
   110
        # hiddenrevs: revs that should be hidden by command and tools
7e295dd10d40 hidden: Add a hiddenrevs attributes to changelog.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14380
diff changeset
   111
        self.hiddenrevs = set()
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   112
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   113
    def delayupdate(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   114
        "delay visibility of index updates to other readers"
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
   115
        self._delayed = True
9163
f193b643d1b1 changelog: _delaycount -> _divert
Matt Mackall <mpm@selenic.com>
parents: 8778
diff changeset
   116
        self._divert = (len(self) == 0)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   117
        self._delaybuf = []
9166
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   118
        self.opener = delayopener(self._realopener, self.indexfile,
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   119
                                  self._divert, self._delaybuf)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   120
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   121
    def finalize(self, tr):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   122
        "finalize index updates"
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
   123
        self._delayed = False
9165
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
   124
        self.opener = self._realopener
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   125
        # move redirected index data back into place
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
   126
        if self._divert:
14207
c1cca38818b9 changelog: fixes leaked file handle
Zachary Gramana <zgramana@pottsconsultinggroup.com>
parents: 14004
diff changeset
   127
            nfile = self.opener(self.indexfile + ".a")
c1cca38818b9 changelog: fixes leaked file handle
Zachary Gramana <zgramana@pottsconsultinggroup.com>
parents: 14004
diff changeset
   128
            n = nfile.name
c1cca38818b9 changelog: fixes leaked file handle
Zachary Gramana <zgramana@pottsconsultinggroup.com>
parents: 14004
diff changeset
   129
            nfile.close()
9166
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   130
            util.rename(n, n[:-2])
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   131
        elif self._delaybuf:
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   132
            fp = self.opener(self.indexfile, 'a')
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   133
            fp.write("".join(self._delaybuf))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   134
            fp.close()
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   135
            self._delaybuf = []
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   136
        # split when we're done
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   137
        self.checkinlinesize(tr)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   138
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   139
    def readpending(self, file):
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   140
        r = revlog.revlog(self.opener, file)
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   141
        self.index = r.index
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   142
        self.nodemap = r.nodemap
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   143
        self._chunkcache = r._chunkcache
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   144
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   145
    def writepending(self):
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   146
        "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
   147
        if self._delaybuf:
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   148
            # make a temporary copy of the index
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   149
            fp1 = self._realopener(self.indexfile)
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   150
            fp2 = self._realopener(self.indexfile + ".a", "w")
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   151
            fp2.write(fp1.read())
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   152
            # add pending data
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   153
            fp2.write("".join(self._delaybuf))
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   154
            fp2.close()
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   155
            # switch modes so finalize can simply rename
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   156
            self._delaybuf = []
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
   157
            self._divert = True
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   158
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
   159
        if self._divert:
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   160
            return True
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   161
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   162
        return False
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   163
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   164
    def checkinlinesize(self, tr, fp=None):
9165
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
   165
        if not self._delayed:
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
   166
            revlog.revlog.checkinlinesize(self, tr, fp)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   167
5744
9db7fd77417d changelog: remove extract function
Matt Mackall <mpm@selenic.com>
parents: 5450
diff changeset
   168
    def read(self, node):
3077
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
   169
        """
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
   170
        format used:
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   171
        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
   172
        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
   173
        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
   174
                        : 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
   175
                        : older versions ignore it
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   176
        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
   177
        (.*)            : 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
   178
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   179
        changelog v0 doesn't use extra
3077
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
   180
        """
5744
9db7fd77417d changelog: remove extract function
Matt Mackall <mpm@selenic.com>
parents: 5450
diff changeset
   181
        text = self.revision(node)
37
a8811676c85a Move hex/bin bits to revlog
mpm@selenic.com
parents: 33
diff changeset
   182
        if not text:
4176
f9bbcebcacea "default" is the default branch name
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3771
diff changeset
   183
            return (nullid, "", (0, 0), [], "", {'branch': 'default'})
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   184
        last = text.index("\n\n")
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7807
diff changeset
   185
        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
   186
        l = text[:last].split('\n')
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   187
        manifest = bin(l[0])
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7807
diff changeset
   188
        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
   189
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   190
        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
   191
        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
   192
            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
   193
            try:
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   194
                # 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
   195
                timezone = int(extra_data[0])
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 10420
diff changeset
   196
            except ValueError:
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   197
                timezone = 0
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   198
            extra = {}
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   199
        else:
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   200
            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
   201
            time, timezone = float(time), int(timezone)
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
   202
            extra = decodeextra(extra)
4176
f9bbcebcacea "default" is the default branch name
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3771
diff changeset
   203
        if not extra.get('branch'):
f9bbcebcacea "default" is the default branch name
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3771
diff changeset
   204
            extra['branch'] = 'default'
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   205
        files = l[3:]
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   206
        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
   207
8422
437e06bbd11e changelog: removed bad default arguments in add method
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
   208
    def add(self, manifest, files, desc, transaction, p1, p2,
9677
0c072e63e3e7 changelog: do not use a mutable default value
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9166
diff changeset
   209
                  user, date=None, extra=None):
14379
bd23d5f28bbb changelog: convert user and desc from local encoding early
Martin Geisler <mg@aragost.com>
parents: 10420
diff changeset
   210
        # Convert to UTF-8 encoded bytestrings as the very first
bd23d5f28bbb changelog: convert user and desc from local encoding early
Martin Geisler <mg@aragost.com>
parents: 10420
diff changeset
   211
        # thing: calling any method on a localstr object will turn it
bd23d5f28bbb changelog: convert user and desc from local encoding early
Martin Geisler <mg@aragost.com>
parents: 10420
diff changeset
   212
        # into a str object and the cached UTF-8 string is thus lost.
bd23d5f28bbb changelog: convert user and desc from local encoding early
Martin Geisler <mg@aragost.com>
parents: 10420
diff changeset
   213
        user, desc = encoding.fromlocal(user), encoding.fromlocal(desc)
bd23d5f28bbb changelog: convert user and desc from local encoding early
Martin Geisler <mg@aragost.com>
parents: 10420
diff changeset
   214
7035
9d023ef7b467 forbid username with '\n' at the changelog level
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6259
diff changeset
   215
        user = user.strip()
8424
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
   216
        # An empty username or a username with a "\n" will make the
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
   217
        # revision text contain two "\n\n" sequences -> corrupt
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
   218
        # repository since read cannot unpack the revision.
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
   219
        if not user:
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
   220
            raise error.RevlogError(_("empty username"))
7035
9d023ef7b467 forbid username with '\n' at the changelog level
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6259
diff changeset
   221
        if "\n" in user:
7633
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7470
diff changeset
   222
            raise error.RevlogError(_("username %s contains a newline")
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7470
diff changeset
   223
                                    % repr(user))
8499
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
   224
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
   225
        # strip trailing whitespace and leading and trailing empty lines
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
   226
        desc = '\n'.join([l.rstrip() for l in desc.splitlines()]).strip('\n')
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
   227
1195
f92af8d53330 Validate user input of dates when adding a changelog entry.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1095
diff changeset
   228
        if date:
2523
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
   229
            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
   230
        else:
2522
85f796baab10 Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents: 2142
diff changeset
   231
            parseddate = "%d %d" % util.makedate()
10417
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   232
        if extra:
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   233
            branch = extra.get("branch")
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   234
            if branch in ("default", ""):
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   235
                del extra["branch"]
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   236
            elif branch in (".", "null", "tip"):
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   237
                raise error.RevlogError(_('the name \'%s\' is reserved')
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   238
                                        % branch)
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   239
        if extra:
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
   240
            extra = encodeextra(extra)
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   241
            parseddate = "%s %s" % (parseddate, extra)
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 7948
diff changeset
   242
        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
   243
        text = "\n".join(l)
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6259
diff changeset
   244
        return self.addrevision(text, transaction, len(self), p1, p2)