mercurial/changelog.py
author Siddharth Agarwal <sid0@fb.com>
Sat, 12 Jul 2014 17:59:03 -0700
changeset 21880 e6754f5e4cf7
parent 21544 667df8f478d1
child 22484 2b5940f64750
permissions -rw-r--r--
context: generate filtered manifest efficiently for exact matchers When the matcher is exact, there's no reason to iterate over the entire manifest. It's much more efficient to iterate over the list of files instead. For a repository with approximately 300,000 files, this speeds up hg log -l10 --patch --follow for a frequently modified file from 16.5 seconds to 10.5 seconds.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1095
0a18374c0769 changelog: adjust imports, comment
mpm@selenic.com
parents: 1094 1089
diff changeset
     1
# changelog.py - changelog class for mercurial
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     2
#
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4269
diff changeset
     3
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9677
diff changeset
     6
# GNU General Public License version 2 or any later version.
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     7
6211
f89fd07fc51d Expand import * to allow Pyflakes to find problems
Joel Rosdahl <joel@rosdahl.net>
parents: 5791
diff changeset
     8
from node import bin, hex, nullid
7035
9d023ef7b467 forbid username with '\n' at the changelog level
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6259
diff changeset
     9
from i18n import _
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7807
diff changeset
    10
import util, error, revlog, encoding
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    11
16267
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
    12
_defaultextra = {'branch': 'default'}
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
    13
3232
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    14
def _string_escape(text):
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    15
    """
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    16
    >>> d = {'nl': chr(10), 'bs': chr(92), 'cr': chr(13), 'nul': chr(0)}
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    17
    >>> s = "ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    18
    >>> s
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    19
    'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n'
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    20
    >>> res = _string_escape(s)
5745
234e40e636a8 changelog: inline trivial call for extra data unescaping
Matt Mackall <mpm@selenic.com>
parents: 5744
diff changeset
    21
    >>> s == res.decode('string_escape')
3232
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    22
    True
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    23
    """
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    24
    # subset of the string_escape codec
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    25
    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
    26
    return text.replace('\0', '\\0')
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
    27
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    28
def decodeextra(text):
15661
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
    29
    """
18379
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
    30
    >>> sorted(decodeextra(encodeextra({'foo': 'bar', 'baz': chr(0) + '2'})
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
    31
    ...                    ).iteritems())
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
    32
    [('baz', '\\x002'), ('branch', 'default'), ('foo', 'bar')]
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
    33
    >>> sorted(decodeextra(encodeextra({'foo': 'bar',
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
    34
    ...                                 'baz': chr(92) + chr(0) + '2'})
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
    35
    ...                    ).iteritems())
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
    36
    [('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
    37
    """
16267
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
    38
    extra = _defaultextra.copy()
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    39
    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
    40
        if l:
15661
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
    41
            if '\\0' in l:
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
    42
                # 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
    43
                l = l.replace('\\\\', '\\\\\n')
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
    44
                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
    45
                l = l.replace('\n', '')
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    46
            k, v = l.decode('string_escape').split(':', 1)
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    47
            extra[k] = v
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    48
    return extra
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    49
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    50
def encodeextra(d):
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    51
    # 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
    52
    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
    53
    return "\0".join(items)
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
    54
17810
2894d180afa1 changelog: extract description cleaning logic in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17677
diff changeset
    55
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
    56
    """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
    57
    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
    58
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8644
diff changeset
    59
class appender(object):
7807
bd8f44638847 help: miscellaneous language fixes
timeless <timeless@gmail.com>
parents: 7787
diff changeset
    60
    '''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
    61
    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
    62
    def __init__(self, vfs, name, mode, buf):
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    63
        self.data = buf
19899
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19898
diff changeset
    64
        fp = vfs(name, mode)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    65
        self.fp = fp
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    66
        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
    67
        self.size = vfs.fstat(fp).st_size
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    68
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    69
    def end(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    70
        return self.size + len("".join(self.data))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    71
    def tell(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    72
        return self.offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    73
    def flush(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    74
        pass
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    75
    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
    76
        self.fp.close()
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    77
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    78
    def seek(self, offset, whence=0):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    79
        '''virtual file offset spans real file and data'''
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    80
        if whence == 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    81
            self.offset = offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    82
        elif whence == 1:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    83
            self.offset += offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    84
        elif whence == 2:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    85
            self.offset = self.end() + offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    86
        if self.offset < self.size:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    87
            self.fp.seek(self.offset)
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 read(self, count=-1):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    90
        '''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
    91
        ret = ""
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    92
        if self.offset < self.size:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    93
            s = self.fp.read(count)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    94
            ret = s
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    95
            self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    96
            if count > 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    97
                count -= len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    98
        if count != 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
    99
            doff = self.offset - self.size
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   100
            self.data.insert(0, "".join(self.data))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   101
            del self.data[1:]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   102
            s = self.data[0][doff:doff + count]
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   103
            self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   104
            ret += s
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   105
        return ret
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   106
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   107
    def write(self, s):
5450
c728424d44c6 revlog: fix caching of buffer objects
Matt Mackall <mpm@selenic.com>
parents: 4963
diff changeset
   108
        self.data.append(str(s))
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   109
        self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   110
9166
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   111
def delayopener(opener, target, divert, buf):
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   112
    def o(name, mode='r'):
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   113
        if name != target:
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   114
            return opener(name, mode)
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   115
        if divert:
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   116
            return opener(name + ".a", mode.replace('a', 'w'))
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   117
        # otherwise, divert to memory
19899
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19898
diff changeset
   118
        return appender(opener, name, mode, buf)
9166
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   119
    return o
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   120
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   121
class changelog(revlog.revlog):
4258
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 4257
diff changeset
   122
    def __init__(self, opener):
9165
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
   123
        revlog.revlog.__init__(self, opener, "00changelog.i")
14334
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
   124
        if self._initempty:
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
   125
            # changelogs don't benefit from generaldelta
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
   126
            self.version &= ~revlog.REVLOGGENERALDELTA
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
   127
            self._generaldelta = False
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
   128
        self._realopener = opener
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
   129
        self._delayed = False
21544
667df8f478d1 changelog: ensure changelog._delaybuf is initialized
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20185
diff changeset
   130
        self._delaybuf = []
9163
f193b643d1b1 changelog: _delaycount -> _divert
Matt Mackall <mpm@selenic.com>
parents: 8778
diff changeset
   131
        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
   132
        self.filteredrevs = frozenset()
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   133
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   134
    def tip(self):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   135
        """filtered version of revlog.tip"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   136
        for i in xrange(len(self) -1, -2, -1):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   137
            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
   138
                return self.node(i)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   139
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   140
    def __iter__(self):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   141
        """filtered version of revlog.__iter__"""
17951
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   142
        if len(self.filteredrevs) == 0:
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   143
            return revlog.revlog.__iter__(self)
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   144
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   145
        def filterediter():
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   146
            for i in xrange(len(self)):
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   147
                if i not in self.filteredrevs:
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   148
                    yield i
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   149
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
   150
        return filterediter()
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   151
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   152
    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
   153
        """filtered version of revlog.revs"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   154
        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
   155
            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
   156
                yield i
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   157
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   158
    @util.propertycache
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   159
    def nodemap(self):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   160
        # XXX need filtering too
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   161
        self.rev(self.node(0))
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   162
        return self._nodecache
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   163
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   164
    def hasnode(self, node):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   165
        """filtered version of revlog.hasnode"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   166
        try:
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   167
            i = self.rev(node)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   168
            return i not in self.filteredrevs
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   169
        except KeyError:
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   170
            return False
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   171
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   172
    def headrevs(self):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   173
        if self.filteredrevs:
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   174
            # XXX we should fix and use the C version
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   175
            return self._headrevs()
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   176
        return super(changelog, self).headrevs()
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   177
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   178
    def strip(self, *args, **kwargs):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   179
        # 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
   180
        # 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
   181
        assert not self.filteredrevs
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   182
        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
   183
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   184
    def rev(self, node):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   185
        """filtered version of revlog.rev"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   186
        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
   187
        if r in self.filteredrevs:
18587
cbf5f3eb9d13 changelog: hexlify node when throwing a LookupError on a filtered node
Augie Fackler <raf@durin42.com>
parents: 18379
diff changeset
   188
            raise error.LookupError(hex(node), self.indexfile, _('no node'))
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   189
        return r
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   190
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   191
    def node(self, rev):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   192
        """filtered version of revlog.node"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   193
        if rev in self.filteredrevs:
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   194
            raise IndexError(rev)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   195
        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
   196
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   197
    def linkrev(self, rev):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   198
        """filtered version of revlog.linkrev"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   199
        if rev in self.filteredrevs:
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   200
            raise IndexError(rev)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   201
        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
   202
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   203
    def parentrevs(self, rev):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   204
        """filtered version of revlog.parentrevs"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   205
        if rev in self.filteredrevs:
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   206
            raise IndexError(rev)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   207
        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
   208
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   209
    def flags(self, rev):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   210
        """filtered version of revlog.flags"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   211
        if rev in self.filteredrevs:
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   212
            raise IndexError(rev)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
   213
        return super(changelog, self).flags(rev)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   214
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   215
    def delayupdate(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   216
        "delay visibility of index updates to other readers"
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
   217
        self._delayed = True
9163
f193b643d1b1 changelog: _delaycount -> _divert
Matt Mackall <mpm@selenic.com>
parents: 8778
diff changeset
   218
        self._divert = (len(self) == 0)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   219
        self._delaybuf = []
9166
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   220
        self.opener = delayopener(self._realopener, self.indexfile,
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
   221
                                  self._divert, self._delaybuf)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   222
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   223
    def finalize(self, tr):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   224
        "finalize index updates"
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
   225
        self._delayed = False
9165
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
   226
        self.opener = self._realopener
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   227
        # move redirected index data back into place
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
   228
        if self._divert:
19898
3f92e749d381 changelog: use "vfs.rename()" instead of "util.rename()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18587
diff changeset
   229
            tmpname = self.indexfile + ".a"
3f92e749d381 changelog: use "vfs.rename()" instead of "util.rename()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18587
diff changeset
   230
            nfile = self.opener.open(tmpname)
14207
c1cca38818b9 changelog: fixes leaked file handle
Zachary Gramana <zgramana@pottsconsultinggroup.com>
parents: 14004
diff changeset
   231
            nfile.close()
19898
3f92e749d381 changelog: use "vfs.rename()" instead of "util.rename()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18587
diff changeset
   232
            self.opener.rename(tmpname, self.indexfile)
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   233
        elif self._delaybuf:
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   234
            fp = self.opener(self.indexfile, 'a')
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   235
            fp.write("".join(self._delaybuf))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   236
            fp.close()
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   237
            self._delaybuf = []
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
   238
        # split when we're done
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   239
        self.checkinlinesize(tr)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   240
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   241
    def readpending(self, file):
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   242
        r = revlog.revlog(self.opener, file)
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   243
        self.index = r.index
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   244
        self.nodemap = r.nodemap
16619
bc84a1aeaf5a changelog: ensure that nodecache is valid (issue3428)
Bryan O'Sullivan <bryano@fb.com>
parents: 16267
diff changeset
   245
        self._nodecache = r._nodecache
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   246
        self._chunkcache = r._chunkcache
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   247
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   248
    def writepending(self):
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   249
        "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
   250
        if self._delaybuf:
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   251
            # make a temporary copy of the index
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   252
            fp1 = self._realopener(self.indexfile)
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   253
            fp2 = self._realopener(self.indexfile + ".a", "w")
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   254
            fp2.write(fp1.read())
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   255
            # add pending data
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   256
            fp2.write("".join(self._delaybuf))
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   257
            fp2.close()
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   258
            # switch modes so finalize can simply rename
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   259
            self._delaybuf = []
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
   260
            self._divert = True
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   261
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
   262
        if self._divert:
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   263
            return True
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   264
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   265
        return False
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
   266
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   267
    def checkinlinesize(self, tr, fp=None):
9165
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
   268
        if not self._delayed:
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
   269
            revlog.revlog.checkinlinesize(self, tr, fp)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
   270
5744
9db7fd77417d changelog: remove extract function
Matt Mackall <mpm@selenic.com>
parents: 5450
diff changeset
   271
    def read(self, node):
3077
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
   272
        """
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
   273
        format used:
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   274
        nodeid\n        : manifest node in ascii
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   275
        user\n          : user, no \n or \r allowed
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   276
        time tz extra\n : date (time is int or float, timezone is int)
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17207
diff changeset
   277
                        : extra is metadata, encoded and separated by '\0'
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   278
                        : older versions ignore it
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   279
        files\n\n       : files modified by the cset, no \n or \r allowed
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   280
        (.*)            : comment (free text, ideally utf-8)
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   281
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   282
        changelog v0 doesn't use extra
3077
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
   283
        """
5744
9db7fd77417d changelog: remove extract function
Matt Mackall <mpm@selenic.com>
parents: 5450
diff changeset
   284
        text = self.revision(node)
37
a8811676c85a Move hex/bin bits to revlog
mpm@selenic.com
parents: 33
diff changeset
   285
        if not text:
16267
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
   286
            return (nullid, "", (0, 0), [], "", _defaultextra)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   287
        last = text.index("\n\n")
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7807
diff changeset
   288
        desc = encoding.tolocal(text[last + 2:])
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   289
        l = text[:last].split('\n')
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   290
        manifest = bin(l[0])
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7807
diff changeset
   291
        user = encoding.tolocal(l[1])
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   292
16267
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
   293
        tdata = l[2].split(' ', 2)
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
   294
        if len(tdata) != 3:
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
   295
            time = float(tdata[0])
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   296
            try:
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   297
                # various tools did silly things with the time zone field.
16267
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
   298
                timezone = int(tdata[1])
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 10420
diff changeset
   299
            except ValueError:
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   300
                timezone = 0
16267
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
   301
            extra = _defaultextra
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   302
        else:
16267
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
   303
            time, timezone = float(tdata[0]), int(tdata[1])
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
   304
            extra = decodeextra(tdata[2])
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
   305
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   306
        files = l[3:]
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   307
        return (manifest, user, (time, timezone), files, desc, extra)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   308
8422
437e06bbd11e changelog: removed bad default arguments in add method
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
   309
    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
   310
                  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
   311
        # 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
   312
        # 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
   313
        # 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
   314
        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
   315
7035
9d023ef7b467 forbid username with '\n' at the changelog level
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6259
diff changeset
   316
        user = user.strip()
8424
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
   317
        # 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
   318
        # 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
   319
        # 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
   320
        if not user:
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
   321
            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
   322
        if "\n" in user:
7633
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7470
diff changeset
   323
            raise error.RevlogError(_("username %s contains a newline")
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7470
diff changeset
   324
                                    % repr(user))
8499
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
   325
17810
2894d180afa1 changelog: extract description cleaning logic in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17677
diff changeset
   326
        desc = stripdesc(desc)
8499
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
   327
1195
f92af8d53330 Validate user input of dates when adding a changelog entry.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1095
diff changeset
   328
        if date:
2523
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
   329
            parseddate = "%d %d" % util.parsedate(date)
1195
f92af8d53330 Validate user input of dates when adding a changelog entry.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1095
diff changeset
   330
        else:
2522
85f796baab10 Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents: 2142
diff changeset
   331
            parseddate = "%d %d" % util.makedate()
10417
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   332
        if extra:
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   333
            branch = extra.get("branch")
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   334
            if branch in ("default", ""):
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   335
                del extra["branch"]
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   336
            elif branch in (".", "null", "tip"):
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
   337
                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
   338
                                        % branch)
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   339
        if extra:
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
   340
            extra = encodeextra(extra)
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
   341
            parseddate = "%s %s" % (parseddate, extra)
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 7948
diff changeset
   342
        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
   343
        text = "\n".join(l)
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6259
diff changeset
   344
        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
   345
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 19899
diff changeset
   346
    def branchinfo(self, rev):
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 19899
diff changeset
   347
        """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
   348
18308
4e27b06a0fd9 changelog: please check-code and remove tabs
Mads Kiilerich <mads@kiilerich.com>
parents: 18306
diff changeset
   349
        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
   350
        just to access this is costly."""
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 19899
diff changeset
   351
        extra = self.read(rev)[5]
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 19899
diff changeset
   352
        return encoding.tolocal(extra.get("branch")), 'close' in extra