mercurial/changelog.py
author Gregory Szorc <gregory.szorc@gmail.com>
Tue, 13 Mar 2018 19:44:59 -0700
changeset 37050 37d7a1d18b97
parent 36607 c6061cadb400
child 37084 f0b6fbea00cf
permissions -rw-r--r--
wireproto: define content negotiation for HTTPv2 HTTP messages communicate their media types and what media types they can understand via the Content-Type and Accept header, respectively. While I don't want the wire protocol to lean too heavily on HTTP because I'm aiming for the wire protocol to be as transport agnostic as possible, it is nice to play by the spec if possible. This commit defines our media negotiation mechanism for version 2 of the HTTP protocol. Essentially, we mandate the use of a new media type and how clients and servers should react to various headers or lack thereof. The name of the media type is a placeholder. We purposefully don't yet define the format of the new media type because that's a lot of work. I feel pretty strongly that we should use Content-Type. I feel less strongly about Accept. I think it is reasonable for servers to return the media type that was submitted to them. So we may strike this header before the protocol is finished... Differential Revision: https://phab.mercurial-scm.org/D2850
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
25922
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
     8
from __future__ import absolute_import
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
     9
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
    10
from .i18n import _
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
    11
from .node import (
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
    12
    bin,
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
    13
    hex,
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
    14
    nullid,
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
    15
)
34398
e51c8ffa1ffa changelog: use attrs instead of namedtuple
Siddharth Agarwal <sid0@fb.com>
parents: 34296
diff changeset
    16
from .thirdparty import (
e51c8ffa1ffa changelog: use attrs instead of namedtuple
Siddharth Agarwal <sid0@fb.com>
parents: 34296
diff changeset
    17
    attr,
e51c8ffa1ffa changelog: use attrs instead of namedtuple
Siddharth Agarwal <sid0@fb.com>
parents: 34296
diff changeset
    18
)
25922
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
    19
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
    20
from . import (
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
    21
    encoding,
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
    22
    error,
36228
ddeb7653b31c py3: use pycompat.bytestr to convert str to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35974
diff changeset
    23
    pycompat,
25922
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
    24
    revlog,
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
    25
    util,
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
    26
)
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36228
diff changeset
    27
from .utils import dateutil
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    28
16267
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
    29
_defaultextra = {'branch': 'default'}
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
    30
3232
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    31
def _string_escape(text):
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    32
    """
34133
708b5530a273 doctest: replace chr() with pycompat.bytechr()
Yuya Nishihara <yuya@tcha.org>
parents: 34132
diff changeset
    33
    >>> from .pycompat import bytechr as chr
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34028
diff changeset
    34
    >>> d = {b'nl': chr(10), b'bs': chr(92), b'cr': chr(13), b'nul': chr(0)}
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34028
diff changeset
    35
    >>> s = b"ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d
3232
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    36
    >>> s
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    37
    'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n'
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    38
    >>> res = _string_escape(s)
31484
afb335353d28 util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents: 30596
diff changeset
    39
    >>> s == util.unescapestr(res)
3232
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    40
    True
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    41
    """
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    42
    # subset of the string_escape codec
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    43
    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
    44
    return text.replace('\0', '\\0')
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    45
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    46
def decodeextra(text):
15661
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
    47
    """
34133
708b5530a273 doctest: replace chr() with pycompat.bytechr()
Yuya Nishihara <yuya@tcha.org>
parents: 34132
diff changeset
    48
    >>> from .pycompat import bytechr as chr
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34028
diff changeset
    49
    >>> sorted(decodeextra(encodeextra({b'foo': b'bar', b'baz': chr(0) + b'2'})
34132
264872544362 doctest: replace .iteritems() with .items()
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
    50
    ...                    ).items())
18379
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
    51
    [('baz', '\\x002'), ('branch', 'default'), ('foo', 'bar')]
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34028
diff changeset
    52
    >>> sorted(decodeextra(encodeextra({b'foo': b'bar',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34028
diff changeset
    53
    ...                                 b'baz': chr(92) + chr(0) + b'2'})
34132
264872544362 doctest: replace .iteritems() with .items()
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
    54
    ...                    ).items())
18379
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
    55
    [('baz', '\\\\\\x002'), ('branch', 'default'), ('foo', 'bar')]
15661
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
    56
    """
16267
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
    57
    extra = _defaultextra.copy()
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    58
    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
    59
        if l:
15661
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
    60
            if '\\0' in l:
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
    61
                # fix up \0 without getting into trouble with \\0
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
    62
                l = l.replace('\\\\', '\\\\\n')
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
    63
                l = l.replace('\\0', '\0')
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
    64
                l = l.replace('\n', '')
31484
afb335353d28 util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents: 30596
diff changeset
    65
            k, v = util.unescapestr(l).split(':', 1)
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    66
            extra[k] = v
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    67
    return extra
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    68
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    69
def encodeextra(d):
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    70
    # 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
    71
    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
    72
    return "\0".join(items)
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    73
17810
2894d180afa1 changelog: extract description cleaning logic in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17677
diff changeset
    74
def stripdesc(desc):
2894d180afa1 changelog: extract description cleaning logic in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17677
diff changeset
    75
    """strip trailing whitespace and leading and trailing empty lines"""
2894d180afa1 changelog: extract description cleaning logic in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17677
diff changeset
    76
    return '\n'.join([l.rstrip() for l in desc.splitlines()]).strip('\n')
2894d180afa1 changelog: extract description cleaning logic in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17677
diff changeset
    77
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8644
diff changeset
    78
class appender(object):
7807
bd8f44638847 help: miscellaneous language fixes
timeless <timeless@gmail.com>
parents: 7787
diff changeset
    79
    '''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
    80
    to delay writes to it'''
19899
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19898
diff changeset
    81
    def __init__(self, vfs, name, mode, buf):
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    82
        self.data = buf
19899
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19898
diff changeset
    83
        fp = vfs(name, mode)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    84
        self.fp = fp
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    85
        self.offset = fp.tell()
19899
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19898
diff changeset
    86
        self.size = vfs.fstat(fp).st_size
30596
be520fe3a3e9 changelog: keep track of file end in appender (issue5444)
Durham Goode <durham@fb.com>
parents: 30210
diff changeset
    87
        self._end = self.size
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 end(self):
30596
be520fe3a3e9 changelog: keep track of file end in appender (issue5444)
Durham Goode <durham@fb.com>
parents: 30210
diff changeset
    90
        return self._end
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    91
    def tell(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    92
        return self.offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    93
    def flush(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    94
        pass
35963
69aaad59dc02 changelog: add the missing 'closed' property on 'appender' object
Boris Feld <boris.feld@octobus.net>
parents: 35962
diff changeset
    95
69aaad59dc02 changelog: add the missing 'closed' property on 'appender' object
Boris Feld <boris.feld@octobus.net>
parents: 35962
diff changeset
    96
    @property
69aaad59dc02 changelog: add the missing 'closed' property on 'appender' object
Boris Feld <boris.feld@octobus.net>
parents: 35962
diff changeset
    97
    def closed(self):
69aaad59dc02 changelog: add the missing 'closed' property on 'appender' object
Boris Feld <boris.feld@octobus.net>
parents: 35962
diff changeset
    98
        return self.fp.closed
69aaad59dc02 changelog: add the missing 'closed' property on 'appender' object
Boris Feld <boris.feld@octobus.net>
parents: 35962
diff changeset
    99
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   100
    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
   101
        self.fp.close()
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   102
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   103
    def seek(self, offset, whence=0):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   104
        '''virtual file offset spans real file and data'''
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   105
        if whence == 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   106
            self.offset = offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   107
        elif whence == 1:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   108
            self.offset += offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   109
        elif whence == 2:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   110
            self.offset = self.end() + offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   111
        if self.offset < self.size:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   112
            self.fp.seek(self.offset)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   113
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   114
    def read(self, count=-1):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   115
        '''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
   116
        ret = ""
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   117
        if self.offset < self.size:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   118
            s = self.fp.read(count)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   119
            ret = s
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   120
            self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   121
            if count > 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   122
                count -= len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   123
        if count != 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   124
            doff = self.offset - self.size
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   125
            self.data.insert(0, "".join(self.data))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   126
            del self.data[1:]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   127
            s = self.data[0][doff:doff + count]
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   128
            self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   129
            ret += s
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   130
        return ret
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   131
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   132
    def write(self, s):
31642
addc392cc3d3 py3: use bytes() to cast to immutable bytes in changelog.appender.write()
Yuya Nishihara <yuya@tcha.org>
parents: 31484
diff changeset
   133
        self.data.append(bytes(s))
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   134
        self.offset += len(s)
30596
be520fe3a3e9 changelog: keep track of file end in appender (issue5444)
Durham Goode <durham@fb.com>
parents: 30210
diff changeset
   135
        self._end += len(s)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   136
35962
fa15a70f88de changelog: implement context manager method for 'appender' object
Boris Feld <boris.feld@octobus.net>
parents: 35672
diff changeset
   137
    def __enter__(self):
fa15a70f88de changelog: implement context manager method for 'appender' object
Boris Feld <boris.feld@octobus.net>
parents: 35672
diff changeset
   138
        self.fp.__enter__()
fa15a70f88de changelog: implement context manager method for 'appender' object
Boris Feld <boris.feld@octobus.net>
parents: 35672
diff changeset
   139
        return self
fa15a70f88de changelog: implement context manager method for 'appender' object
Boris Feld <boris.feld@octobus.net>
parents: 35672
diff changeset
   140
fa15a70f88de changelog: implement context manager method for 'appender' object
Boris Feld <boris.feld@octobus.net>
parents: 35672
diff changeset
   141
    def __exit__(self, *args):
fa15a70f88de changelog: implement context manager method for 'appender' object
Boris Feld <boris.feld@octobus.net>
parents: 35672
diff changeset
   142
        return self.fp.__exit__(*args)
fa15a70f88de changelog: implement context manager method for 'appender' object
Boris Feld <boris.feld@octobus.net>
parents: 35672
diff changeset
   143
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   144
def _divertopener(opener, target):
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   145
    """build an opener that writes in 'target.a' instead of 'target'"""
29997
b5e5ddf48bd2 revlog: specify checkambig at writing to avoid file stat ambiguity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29696
diff changeset
   146
    def _divert(name, mode='r', checkambig=False):
9166
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   147
        if name != target:
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   148
            return opener(name, mode)
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   149
        return opener(name + ".a", mode)
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   150
    return _divert
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   151
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   152
def _delayopener(opener, target, buf):
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   153
    """build an opener that stores chunks in 'buf' instead of 'target'"""
29997
b5e5ddf48bd2 revlog: specify checkambig at writing to avoid file stat ambiguity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29696
diff changeset
   154
    def _delay(name, mode='r', checkambig=False):
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   155
        if name != target:
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   156
            return opener(name, mode)
19899
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19898
diff changeset
   157
        return appender(opener, name, mode, buf)
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   158
    return _delay
9166
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   159
34398
e51c8ffa1ffa changelog: use attrs instead of namedtuple
Siddharth Agarwal <sid0@fb.com>
parents: 34296
diff changeset
   160
@attr.s
e51c8ffa1ffa changelog: use attrs instead of namedtuple
Siddharth Agarwal <sid0@fb.com>
parents: 34296
diff changeset
   161
class _changelogrevision(object):
e51c8ffa1ffa changelog: use attrs instead of namedtuple
Siddharth Agarwal <sid0@fb.com>
parents: 34296
diff changeset
   162
    # Extensions might modify _defaultextra, so let the constructor below pass
e51c8ffa1ffa changelog: use attrs instead of namedtuple
Siddharth Agarwal <sid0@fb.com>
parents: 34296
diff changeset
   163
    # it in
e51c8ffa1ffa changelog: use attrs instead of namedtuple
Siddharth Agarwal <sid0@fb.com>
parents: 34296
diff changeset
   164
    extra = attr.ib()
e51c8ffa1ffa changelog: use attrs instead of namedtuple
Siddharth Agarwal <sid0@fb.com>
parents: 34296
diff changeset
   165
    manifest = attr.ib(default=nullid)
e51c8ffa1ffa changelog: use attrs instead of namedtuple
Siddharth Agarwal <sid0@fb.com>
parents: 34296
diff changeset
   166
    user = attr.ib(default='')
e51c8ffa1ffa changelog: use attrs instead of namedtuple
Siddharth Agarwal <sid0@fb.com>
parents: 34296
diff changeset
   167
    date = attr.ib(default=(0, 0))
34441
50474f0b3f1b changelog: use a Factory for default value for files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34398
diff changeset
   168
    files = attr.ib(default=attr.Factory(list))
34398
e51c8ffa1ffa changelog: use attrs instead of namedtuple
Siddharth Agarwal <sid0@fb.com>
parents: 34296
diff changeset
   169
    description = attr.ib(default='')
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   170
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   171
class changelogrevision(object):
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   172
    """Holds results of a parsed changelog revision.
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   173
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   174
    Changelog revisions consist of multiple pieces of data, including
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   175
    the manifest node, user, and date. This object exposes a view into
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   176
    the parsed object.
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   177
    """
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   178
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   179
    __slots__ = (
29696
2f64e5a6efb8 py3: use unicode literals in changelog.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28495
diff changeset
   180
        u'_offsets',
2f64e5a6efb8 py3: use unicode literals in changelog.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28495
diff changeset
   181
        u'_text',
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   182
    )
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   183
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   184
    def __new__(cls, text):
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   185
        if not text:
34398
e51c8ffa1ffa changelog: use attrs instead of namedtuple
Siddharth Agarwal <sid0@fb.com>
parents: 34296
diff changeset
   186
            return _changelogrevision(extra=_defaultextra)
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   187
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   188
        self = super(changelogrevision, cls).__new__(cls)
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   189
        # We could return here and implement the following as an __init__.
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   190
        # But doing it here is equivalent and saves an extra function call.
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   191
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   192
        # format used:
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   193
        # nodeid\n        : manifest node in ascii
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   194
        # user\n          : user, no \n or \r allowed
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   195
        # time tz extra\n : date (time is int or float, timezone is int)
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   196
        #                 : extra is metadata, encoded and separated by '\0'
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   197
        #                 : older versions ignore it
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   198
        # files\n\n       : files modified by the cset, no \n or \r allowed
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   199
        # (.*)            : comment (free text, ideally utf-8)
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   200
        #
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   201
        # changelog v0 doesn't use extra
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   202
28490
959eadae589a changelog: lazily parse manifest node
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28489
diff changeset
   203
        nl1 = text.index('\n')
28491
f57f7500a095 changelog: lazily parse user
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28490
diff changeset
   204
        nl2 = text.index('\n', nl1 + 1)
28492
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   205
        nl3 = text.index('\n', nl2 + 1)
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   206
28493
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
   207
        # The list of files may be empty. Which means nl3 is the first of the
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
   208
        # double newline that precedes the description.
32153
6f173560c7f4 py3: slice over bytes to prevent getting ascii values
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31642
diff changeset
   209
        if text[nl3 + 1:nl3 + 2] == '\n':
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   210
            doublenl = nl3
28493
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
   211
        else:
28494
63653147e9bb changelog: parse description last
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28493
diff changeset
   212
            doublenl = text.index('\n\n', nl3 + 1)
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   213
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   214
        self._offsets = (nl1, nl2, nl3, doublenl)
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   215
        self._text = text
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   216
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   217
        return self
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   218
28489
8939a95064f1 changelog: lazily parse description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28487
diff changeset
   219
    @property
28490
959eadae589a changelog: lazily parse manifest node
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28489
diff changeset
   220
    def manifest(self):
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   221
        return bin(self._text[0:self._offsets[0]])
28490
959eadae589a changelog: lazily parse manifest node
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28489
diff changeset
   222
959eadae589a changelog: lazily parse manifest node
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28489
diff changeset
   223
    @property
28491
f57f7500a095 changelog: lazily parse user
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28490
diff changeset
   224
    def user(self):
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   225
        off = self._offsets
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   226
        return encoding.tolocal(self._text[off[0] + 1:off[1]])
28491
f57f7500a095 changelog: lazily parse user
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28490
diff changeset
   227
f57f7500a095 changelog: lazily parse user
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28490
diff changeset
   228
    @property
28492
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   229
    def _rawdate(self):
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   230
        off = self._offsets
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   231
        dateextra = self._text[off[1] + 1:off[2]]
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   232
        return dateextra.split(' ', 2)[0:2]
28492
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   233
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   234
    @property
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   235
    def _rawextra(self):
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   236
        off = self._offsets
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   237
        dateextra = self._text[off[1] + 1:off[2]]
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   238
        fields = dateextra.split(' ', 2)
28492
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   239
        if len(fields) != 3:
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   240
            return None
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   241
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   242
        return fields[2]
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   243
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   244
    @property
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   245
    def date(self):
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   246
        raw = self._rawdate
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   247
        time = float(raw[0])
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   248
        # Various tools did silly things with the timezone.
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   249
        try:
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   250
            timezone = int(raw[1])
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   251
        except ValueError:
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   252
            timezone = 0
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   253
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   254
        return time, timezone
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   255
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   256
    @property
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   257
    def extra(self):
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   258
        raw = self._rawextra
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   259
        if raw is None:
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   260
            return _defaultextra
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   261
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   262
        return decodeextra(raw)
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   263
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
   264
    @property
28493
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
   265
    def files(self):
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   266
        off = self._offsets
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   267
        if off[2] == off[3]:
28493
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
   268
            return []
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
   269
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   270
        return self._text[off[2] + 1:off[3]].split('\n')
28493
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
   271
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
   272
    @property
28489
8939a95064f1 changelog: lazily parse description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28487
diff changeset
   273
    def description(self):
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
   274
        return encoding.tolocal(self._text[self._offsets[3] + 2:])
28489
8939a95064f1 changelog: lazily parse description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28487
diff changeset
   275
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   276
class changelog(revlog.revlog):
32292
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   277
    def __init__(self, opener, trypending=False):
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   278
        """Load a changelog revlog using an opener.
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   279
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   280
        If ``trypending`` is true, we attempt to load the index from a
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   281
        ``00changelog.i.a`` file instead of the default ``00changelog.i``.
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   282
        The ``00changelog.i.a`` file contains index (and possibly inline
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   283
        revision) data for a transaction that hasn't been finalized yet.
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   284
        It exists in a separate file to facilitate readers (such as
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   285
        hooks processes) accessing data before a transaction is finalized.
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   286
        """
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   287
        if trypending and opener.exists('00changelog.i.a'):
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   288
            indexfile = '00changelog.i.a'
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   289
        else:
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   290
            indexfile = '00changelog.i'
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   291
32307
3caec778774b changelog: make sure datafile is 00changelog.d (API)
Jun Wu <quark@fb.com>
parents: 32292
diff changeset
   292
        datafile = '00changelog.d'
3caec778774b changelog: make sure datafile is 00changelog.d (API)
Jun Wu <quark@fb.com>
parents: 32292
diff changeset
   293
        revlog.revlog.__init__(self, opener, indexfile, datafile=datafile,
34296
3c9691728237 revlog: add option to mmap revlog index
Mark Thomas <mbthomas@fb.com>
parents: 34133
diff changeset
   294
                               checkambig=True, mmaplargeindex=True)
32292
0ad0d26ff703 changelog: load pending file directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32262
diff changeset
   295
14334
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
   296
        if self._initempty:
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
   297
            # changelogs don't benefit from generaldelta
32315
67026d65a4fc revlog: rename constants (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32307
diff changeset
   298
            self.version &= ~revlog.FLAG_GENERALDELTA
14334
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
   299
            self._generaldelta = False
30155
b7a966ce89ed changelog: disable delta chains
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30000
diff changeset
   300
b7a966ce89ed changelog: disable delta chains
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30000
diff changeset
   301
        # Delta chains for changelogs tend to be very small because entries
b7a966ce89ed changelog: disable delta chains
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30000
diff changeset
   302
        # tend to be small and don't delta well with each. So disable delta
b7a966ce89ed changelog: disable delta chains
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30000
diff changeset
   303
        # chains.
30210
5e4f16874a9f revlog: make 'storedeltachains' a "public" attribute
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30155
diff changeset
   304
        self.storedeltachains = False
30155
b7a966ce89ed changelog: disable delta chains
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30000
diff changeset
   305
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
   306
        self._realopener = opener
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
   307
        self._delayed = False
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   308
        self._delaybuf = None
9163
f193b643d1b1 changelog: _delaycount -> _divert
Matt Mackall <mpm@selenic.com>
parents: 8778
diff changeset
   309
        self._divert = False
18231
c0c943ef4e55 clfilter: use empty frozenset intead of empty tuple
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17951
diff changeset
   310
        self.filteredrevs = frozenset()
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   311
35671
8810f0643fa1 changelog: introduce a 'tiprev' method
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   312
    def tiprev(self):
8810f0643fa1 changelog: introduce a 'tiprev' method
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   313
        for i in xrange(len(self) -1, -2, -1):
8810f0643fa1 changelog: introduce a 'tiprev' method
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   314
            if i not in self.filteredrevs:
8810f0643fa1 changelog: introduce a 'tiprev' method
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   315
                return i
8810f0643fa1 changelog: introduce a 'tiprev' method
Boris Feld <boris.feld@octobus.net>
parents: 35308
diff changeset
   316
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   317
    def tip(self):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   318
        """filtered version of revlog.tip"""
35672
5a6e0eee7781 changelog: use 'tiprev()' in 'tip()'
Boris Feld <boris.feld@octobus.net>
parents: 35671
diff changeset
   319
        return self.node(self.tiprev())
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   320
24030
828dc8db5515 revlog: add __contains__ for fast membership test
Yuya Nishihara <yuya@tcha.org>
parents: 23292
diff changeset
   321
    def __contains__(self, rev):
828dc8db5515 revlog: add __contains__ for fast membership test
Yuya Nishihara <yuya@tcha.org>
parents: 23292
diff changeset
   322
        """filtered version of revlog.__contains__"""
24662
b5cd8c2f6e65 changelog: inline revlog.__contains__ in case it is used in hot loop
Yuya Nishihara <yuya@tcha.org>
parents: 24030
diff changeset
   323
        return (0 <= rev < len(self)
24030
828dc8db5515 revlog: add __contains__ for fast membership test
Yuya Nishihara <yuya@tcha.org>
parents: 23292
diff changeset
   324
                and rev not in self.filteredrevs)
828dc8db5515 revlog: add __contains__ for fast membership test
Yuya Nishihara <yuya@tcha.org>
parents: 23292
diff changeset
   325
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   326
    def __iter__(self):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   327
        """filtered version of revlog.__iter__"""
17951
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   328
        if len(self.filteredrevs) == 0:
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   329
            return revlog.revlog.__iter__(self)
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   330
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   331
        def filterediter():
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   332
            for i in xrange(len(self)):
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   333
                if i not in self.filteredrevs:
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   334
                    yield i
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   335
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   336
        return filterediter()
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   337
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   338
    def revs(self, start=0, stop=None):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   339
        """filtered version of revlog.revs"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   340
        for i in super(changelog, self).revs(start, stop):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   341
            if i not in self.filteredrevs:
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   342
                yield i
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   343
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   344
    @util.propertycache
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   345
    def nodemap(self):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   346
        # XXX need filtering too
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   347
        self.rev(self.node(0))
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   348
        return self._nodecache
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   349
26005
6f4a280298c1 changelog: add way to call the reachableroots C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25922
diff changeset
   350
    def reachableroots(self, minroot, heads, roots, includepath=False):
26094
df41c7be16d6 reachableroots: construct and sort baseset in revset module
Yuya Nishihara <yuya@tcha.org>
parents: 26061
diff changeset
   351
        return self.index.reachableroots2(minroot, heads, roots, includepath)
26005
6f4a280298c1 changelog: add way to call the reachableroots C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25922
diff changeset
   352
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   353
    def headrevs(self):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   354
        if self.filteredrevs:
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 21544
diff changeset
   355
            try:
23088
fe5f044b753d changelog: use headrevsfiltered
Mads Kiilerich <madski@unity3d.com>
parents: 23015
diff changeset
   356
                return self.index.headrevsfiltered(self.filteredrevs)
fe5f044b753d changelog: use headrevsfiltered
Mads Kiilerich <madski@unity3d.com>
parents: 23015
diff changeset
   357
            # AttributeError covers non-c-extension environments and
fe5f044b753d changelog: use headrevsfiltered
Mads Kiilerich <madski@unity3d.com>
parents: 23015
diff changeset
   358
            # old c extensions without filter handling.
fe5f044b753d changelog: use headrevsfiltered
Mads Kiilerich <madski@unity3d.com>
parents: 23015
diff changeset
   359
            except AttributeError:
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 21544
diff changeset
   360
                return self._headrevs()
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 21544
diff changeset
   361
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   362
        return super(changelog, self).headrevs()
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   363
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   364
    def strip(self, *args, **kwargs):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   365
        # XXX make something better than assert
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   366
        # We can't expect proper strip behavior if we are filtered.
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   367
        assert not self.filteredrevs
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   368
        super(changelog, self).strip(*args, **kwargs)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   369
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   370
    def rev(self, node):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   371
        """filtered version of revlog.rev"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   372
        r = super(changelog, self).rev(node)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   373
        if r in self.filteredrevs:
23015
21c44c1aed87 repoview: add a FilteredLookupError class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23014
diff changeset
   374
            raise error.FilteredLookupError(hex(node), self.indexfile,
21c44c1aed87 repoview: add a FilteredLookupError class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23014
diff changeset
   375
                                            _('filtered node'))
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   376
        return r
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   377
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   378
    def node(self, rev):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   379
        """filtered version of revlog.node"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   380
        if rev in self.filteredrevs:
23014
f00813325c5a repoview: add a FilteredIndexError class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22484
diff changeset
   381
            raise error.FilteredIndexError(rev)
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   382
        return super(changelog, self).node(rev)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   383
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   384
    def linkrev(self, rev):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   385
        """filtered version of revlog.linkrev"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   386
        if rev in self.filteredrevs:
23014
f00813325c5a repoview: add a FilteredIndexError class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22484
diff changeset
   387
            raise error.FilteredIndexError(rev)
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   388
        return super(changelog, self).linkrev(rev)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   389
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   390
    def parentrevs(self, rev):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   391
        """filtered version of revlog.parentrevs"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   392
        if rev in self.filteredrevs:
23014
f00813325c5a repoview: add a FilteredIndexError class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22484
diff changeset
   393
            raise error.FilteredIndexError(rev)
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   394
        return super(changelog, self).parentrevs(rev)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   395
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   396
    def flags(self, rev):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   397
        """filtered version of revlog.flags"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   398
        if rev in self.filteredrevs:
23014
f00813325c5a repoview: add a FilteredIndexError class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22484
diff changeset
   399
            raise error.FilteredIndexError(rev)
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   400
        return super(changelog, self).flags(rev)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   401
23203
3872d563e01a changelog: handle writepending in the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23201
diff changeset
   402
    def delayupdate(self, tr):
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   403
        "delay visibility of index updates to other readers"
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   404
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   405
        if not self._delayed:
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   406
            if len(self) == 0:
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   407
                self._divert = True
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   408
                if self._realopener.exists(self.indexfile + '.a'):
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   409
                    self._realopener.unlink(self.indexfile + '.a')
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   410
                self.opener = _divertopener(self._realopener, self.indexfile)
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   411
            else:
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   412
                self._delaybuf = []
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   413
                self.opener = _delayopener(self._realopener, self.indexfile,
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   414
                                           self._delaybuf)
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
   415
        self._delayed = True
23203
3872d563e01a changelog: handle writepending in the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23201
diff changeset
   416
        tr.addpending('cl-%i' % id(self), self._writepending)
23281
f60ed8cf4afc transaction: pass the transaction to 'finalize' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23280
diff changeset
   417
        tr.addfinalize('cl-%i' % id(self), self._finalize)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   418
23205
2d54aa5397cd changelog: rely on transaction for finalization
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23203
diff changeset
   419
    def _finalize(self, tr):
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   420
        "finalize index updates"
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
   421
        self._delayed = False
9165
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
   422
        self.opener = self._realopener
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   423
        # move redirected index data back into place
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
   424
        if self._divert:
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   425
            assert not self._delaybuf
19898
3f92e749d381 changelog: use "vfs.rename()" instead of "util.rename()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18587
diff changeset
   426
            tmpname = self.indexfile + ".a"
3f92e749d381 changelog: use "vfs.rename()" instead of "util.rename()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18587
diff changeset
   427
            nfile = self.opener.open(tmpname)
14207
c1cca38818b9 changelog: fixes leaked file handle
Zachary Gramana <zgramana@pottsconsultinggroup.com>
parents: 14004
diff changeset
   428
            nfile.close()
29999
003c41edc5f5 changelog: specify checkambig=True to avoid ambiguity around truncation
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29997
diff changeset
   429
            self.opener.rename(tmpname, self.indexfile, checkambig=True)
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   430
        elif self._delaybuf:
29999
003c41edc5f5 changelog: specify checkambig=True to avoid ambiguity around truncation
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29997
diff changeset
   431
            fp = self.opener(self.indexfile, 'a', checkambig=True)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   432
            fp.write("".join(self._delaybuf))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   433
            fp.close()
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   434
            self._delaybuf = None
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   435
        self._divert = False
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   436
        # split when we're done
35974
9ba1d0c724e2 revlog: rename 'self.checkinlinesize' into '_enforceinlinesize'
Boris Feld <boris.feld@octobus.net>
parents: 35963
diff changeset
   437
        self._enforceinlinesize(tr)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   438
23280
b01c491af0cf transaction: pass the transaction to 'pending' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23205
diff changeset
   439
    def _writepending(self, tr):
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   440
        "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
   441
        if self._delaybuf:
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   442
            # make a temporary copy of the index
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   443
            fp1 = self._realopener(self.indexfile)
23292
e44399c494ab changelog: register changelog.i.a as a temporary file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23281
diff changeset
   444
            pendingfilename = self.indexfile + ".a"
e44399c494ab changelog: register changelog.i.a as a temporary file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23281
diff changeset
   445
            # register as a temp file to ensure cleanup on failure
e44399c494ab changelog: register changelog.i.a as a temporary file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23281
diff changeset
   446
            tr.registertmp(pendingfilename)
e44399c494ab changelog: register changelog.i.a as a temporary file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23281
diff changeset
   447
            # write existing data
e44399c494ab changelog: register changelog.i.a as a temporary file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23281
diff changeset
   448
            fp2 = self._realopener(pendingfilename, "w")
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   449
            fp2.write(fp1.read())
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   450
            # add pending data
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   451
            fp2.write("".join(self._delaybuf))
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   452
            fp2.close()
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   453
            # switch modes so finalize can simply rename
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   454
            self._delaybuf = None
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
   455
            self._divert = True
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
   456
            self.opener = _divertopener(self._realopener, self.indexfile)
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   457
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
   458
        if self._divert:
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   459
            return True
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   460
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   461
        return False
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   462
35974
9ba1d0c724e2 revlog: rename 'self.checkinlinesize' into '_enforceinlinesize'
Boris Feld <boris.feld@octobus.net>
parents: 35963
diff changeset
   463
    def _enforceinlinesize(self, tr, fp=None):
9165
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
   464
        if not self._delayed:
35974
9ba1d0c724e2 revlog: rename 'self.checkinlinesize' into '_enforceinlinesize'
Boris Feld <boris.feld@octobus.net>
parents: 35963
diff changeset
   465
            revlog.revlog._enforceinlinesize(self, tr, fp)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   466
5744
9db7fd77417d changelog: remove extract function
Matt Mackall <mpm@selenic.com>
parents: 5450
diff changeset
   467
    def read(self, node):
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   468
        """Obtain data from a parsed changelog revision.
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   469
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   470
        Returns a 6-tuple of:
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   471
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   472
           - manifest node in binary
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   473
           - author/user as a localstr
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   474
           - date as a 2-tuple of (time, timezone)
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   475
           - list of files
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   476
           - commit message as a localstr
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   477
           - dict of extra metadata
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   478
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   479
        Unless you need to access all fields, consider calling
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   480
        ``changelogrevision`` instead, as it is faster for partial object
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   481
        access.
3077
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
   482
        """
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   483
        c = changelogrevision(self.revision(node))
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   484
        return (
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   485
            c.manifest,
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   486
            c.user,
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   487
            c.date,
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   488
            c.files,
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   489
            c.description,
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   490
            c.extra
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   491
        )
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   492
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   493
    def changelogrevision(self, nodeorrev):
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   494
        """Obtain a ``changelogrevision`` for a node or revision."""
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
   495
        return changelogrevision(self.revision(nodeorrev))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   496
27439
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
   497
    def readfiles(self, node):
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
   498
        """
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
   499
        short version of read that only returns the files modified by the cset
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
   500
        """
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
   501
        text = self.revision(node)
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
   502
        if not text:
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
   503
            return []
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
   504
        last = text.index("\n\n")
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
   505
        l = text[:last].split('\n')
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
   506
        return l[3:]
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
   507
8422
437e06bbd11e changelog: removed bad default arguments in add method
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
   508
    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
   509
                  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
   510
        # 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
   511
        # 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
   512
        # 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
   513
        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
   514
7035
9d023ef7b467 forbid username with '\n' at the changelog level
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6259
diff changeset
   515
        user = user.strip()
8424
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
   516
        # 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
   517
        # 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
   518
        # 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
   519
        if not user:
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
   520
            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
   521
        if "\n" in user:
36228
ddeb7653b31c py3: use pycompat.bytestr to convert str to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35974
diff changeset
   522
            raise error.RevlogError(_("username %r contains a newline")
ddeb7653b31c py3: use pycompat.bytestr to convert str to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35974
diff changeset
   523
                                    % pycompat.bytestr(user))
8499
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
   524
17810
2894d180afa1 changelog: extract description cleaning logic in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17677
diff changeset
   525
        desc = stripdesc(desc)
8499
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
   526
1195
f92af8d53330 Validate user input of dates when adding a changelog entry.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1095
diff changeset
   527
        if date:
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36228
diff changeset
   528
            parseddate = "%d %d" % dateutil.parsedate(date)
1195
f92af8d53330 Validate user input of dates when adding a changelog entry.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1095
diff changeset
   529
        else:
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36228
diff changeset
   530
            parseddate = "%d %d" % dateutil.makedate()
10417
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   531
        if extra:
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   532
            branch = extra.get("branch")
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   533
            if branch in ("default", ""):
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   534
                del extra["branch"]
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   535
            elif branch in (".", "null", "tip"):
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   536
                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
   537
                                        % branch)
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   538
        if extra:
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
   539
            extra = encodeextra(extra)
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   540
            parseddate = "%s %s" % (parseddate, extra)
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 7948
diff changeset
   541
        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
   542
        text = "\n".join(l)
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6259
diff changeset
   543
        return self.addrevision(text, transaction, len(self), p1, p2)
18306
06185554e7e3 changelog: add a `branch` method, bypassing changectx
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18231
diff changeset
   544
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 19899
diff changeset
   545
    def branchinfo(self, rev):
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 19899
diff changeset
   546
        """return the branch name and open/close state of a revision
18306
06185554e7e3 changelog: add a `branch` method, bypassing changectx
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18231
diff changeset
   547
18308
4e27b06a0fd9 changelog: please check-code and remove tabs
Mads Kiilerich <mads@kiilerich.com>
parents: 18306
diff changeset
   548
        This function exists because creating a changectx object
4e27b06a0fd9 changelog: please check-code and remove tabs
Mads Kiilerich <mads@kiilerich.com>
parents: 18306
diff changeset
   549
        just to access this is costly."""
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 19899
diff changeset
   550
        extra = self.read(rev)[5]
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 19899
diff changeset
   551
        return encoding.tolocal(extra.get("branch")), 'close' in extra
32262
85ef5a073114 transaction: track newly introduced revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 32153
diff changeset
   552
85ef5a073114 transaction: track newly introduced revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 32153
diff changeset
   553
    def _addrevision(self, node, rawtext, transaction, *args, **kwargs):
85ef5a073114 transaction: track newly introduced revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 32153
diff changeset
   554
        # overlay over the standard revlog._addrevision to track the new
85ef5a073114 transaction: track newly introduced revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 32153
diff changeset
   555
        # revision on the transaction.
85ef5a073114 transaction: track newly introduced revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 32153
diff changeset
   556
        rev = len(self)
85ef5a073114 transaction: track newly introduced revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 32153
diff changeset
   557
        node = super(changelog, self)._addrevision(node, rawtext, transaction,
85ef5a073114 transaction: track newly introduced revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 32153
diff changeset
   558
                                                   *args, **kwargs)
85ef5a073114 transaction: track newly introduced revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 32153
diff changeset
   559
        revs = transaction.changes.get('revs')
85ef5a073114 transaction: track newly introduced revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 32153
diff changeset
   560
        if revs is not None:
35308
137a08d82232 transaction: build changes['revs'] as range instead of a set
Joerg Sonnenberger <joerg@bec.de>
parents: 34441
diff changeset
   561
            if revs:
137a08d82232 transaction: build changes['revs'] as range instead of a set
Joerg Sonnenberger <joerg@bec.de>
parents: 34441
diff changeset
   562
                assert revs[-1] + 1 == rev
137a08d82232 transaction: build changes['revs'] as range instead of a set
Joerg Sonnenberger <joerg@bec.de>
parents: 34441
diff changeset
   563
                revs = xrange(revs[0], rev + 1)
137a08d82232 transaction: build changes['revs'] as range instead of a set
Joerg Sonnenberger <joerg@bec.de>
parents: 34441
diff changeset
   564
            else:
137a08d82232 transaction: build changes['revs'] as range instead of a set
Joerg Sonnenberger <joerg@bec.de>
parents: 34441
diff changeset
   565
                revs = xrange(rev, rev + 1)
137a08d82232 transaction: build changes['revs'] as range instead of a set
Joerg Sonnenberger <joerg@bec.de>
parents: 34441
diff changeset
   566
            transaction.changes['revs'] = revs
32262
85ef5a073114 transaction: track newly introduced revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 32153
diff changeset
   567
        return node