mercurial/manifest.py
author Ryan McElroy <rmcelroy@fb.com>
Tue, 14 Apr 2015 13:31:50 -0700
changeset 24962 eecd48369caa
parent 24956 48583a1e44f3
child 25091 b5052fc73300
permissions -rw-r--r--
bookmarks: remove unused updatecurrentbookmark function (API) This function was not used anywhere in core and there is no indication that it is used elsewhere either.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
     1
# manifest.py - manifest revision 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: 4633
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: 9420
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
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
     8
from i18n import _
24635
21e1ece30f8c util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents: 24600
diff changeset
     9
import mdiff, parsers, error, revlog, util
8312
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8225
diff changeset
    10
import array, struct
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    11
import os
79
837d473d54d5 Add basic annotation support
mpm@selenic.com
parents: 78
diff changeset
    12
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
    13
propertycache = util.propertycache
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    14
24572
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    15
def _parsev1(data):
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    16
    # This method does a little bit of excessive-looking
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    17
    # precondition checking. This is so that the behavior of this
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    18
    # class exactly matches its C counterpart to try and help
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    19
    # prevent surprise breakage for anyone that develops against
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    20
    # the pure version.
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    21
    if data and data[-1] != '\n':
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    22
        raise ValueError('Manifest did not end in a newline.')
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    23
    prev = None
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    24
    for l in data.splitlines():
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    25
        if prev is not None and prev > l:
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    26
            raise ValueError('Manifest lines not in sorted order.')
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    27
        prev = l
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    28
        f, n = l.split('\0')
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    29
        if len(n) > 40:
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    30
            yield f, revlog.bin(n[:40]), n[40:]
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    31
        else:
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    32
            yield f, revlog.bin(n), ''
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    33
24572
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    34
def _parsev2(data):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    35
    metadataend = data.find('\n')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    36
    # Just ignore metadata for now
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    37
    pos = metadataend + 1
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    38
    prevf = ''
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    39
    while pos < len(data):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    40
        end = data.find('\n', pos + 1) # +1 to skip stem length byte
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    41
        if end == -1:
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    42
            raise ValueError('Manifest ended with incomplete file entry.')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    43
        stemlen = ord(data[pos])
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    44
        items = data[pos + 1:end].split('\0')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    45
        f = prevf[:stemlen] + items[0]
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    46
        if prevf > f:
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    47
            raise ValueError('Manifest entries not in sorted order.')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    48
        fl = items[1]
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    49
        # Just ignore metadata (items[2:] for now)
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    50
        n = data[end + 1:end + 21]
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    51
        yield f, n, fl
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    52
        pos = end + 22
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    53
        prevf = f
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    54
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    55
def _parse(data):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    56
    """Generates (path, node, flags) tuples from a manifest text"""
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    57
    if data.startswith('\0'):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    58
        return iter(_parsev2(data))
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    59
    else:
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    60
        return iter(_parsev1(data))
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    61
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    62
def _text(it, usemanifestv2):
24525
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    63
    """Given an iterator over (path, node, flags) tuples, returns a manifest
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    64
    text"""
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    65
    if usemanifestv2:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    66
        return _textv2(it)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    67
    else:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    68
        return _textv1(it)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    69
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    70
def _textv1(it):
24525
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    71
    files = []
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    72
    lines = []
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    73
    _hex = revlog.hex
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    74
    for f, n, fl in it:
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    75
        files.append(f)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    76
        # if this is changed to support newlines in filenames,
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    77
        # be sure to check the templates/ dir again (especially *-raw.tmpl)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    78
        lines.append("%s\0%s%s\n" % (f, _hex(n), fl))
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    79
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    80
    _checkforbidden(files)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    81
    return ''.join(lines)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    82
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    83
def _textv2(it):
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    84
    files = []
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    85
    lines = ['\0\n']
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    86
    prevf = ''
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    87
    for f, n, fl in it:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    88
        files.append(f)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    89
        stem = os.path.commonprefix([prevf, f])
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    90
        stemlen = min(len(stem), 255)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    91
        lines.append("%c%s\0%s\n%s\n" % (stemlen, f[stemlen:], fl, n))
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    92
        prevf = f
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    93
    _checkforbidden(files)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    94
    return ''.join(lines)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    95
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    96
class _lazymanifest(dict):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    97
    """This is the pure implementation of lazymanifest.
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    98
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    99
    It has not been optimized *at all* and is not lazy.
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   100
    """
24223
b4df0d0c49e7 manifest: move parsing functions up in file
Augie Fackler <augie@google.com>
parents: 24215
diff changeset
   101
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   102
    def __init__(self, data):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   103
        dict.__init__(self)
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
   104
        for f, n, fl in _parse(data):
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
   105
            self[f] = n, fl
24224
d71837d06597 manifest: do parsing inside manifestdict contstructor
Augie Fackler <augie@google.com>
parents: 24223
diff changeset
   106
23594
6f53629ad273 manifest: disallow setting the node id of an entry to None
Augie Fackler <augie@google.com>
parents: 22966
diff changeset
   107
    def __setitem__(self, k, v):
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   108
        node, flag = v
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   109
        assert node is not None
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   110
        if len(node) > 21:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   111
            node = node[:21] # match c implementation behavior
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   112
        dict.__setitem__(self, k, (node, flag))
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   113
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   114
    def __iter__(self):
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   115
        return iter(sorted(dict.keys(self)))
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   116
24297
0178f500d61e lazymanifest: fix pure hg iterkeys()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   117
    def iterkeys(self):
0178f500d61e lazymanifest: fix pure hg iterkeys()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   118
        return iter(sorted(dict.keys(self)))
0178f500d61e lazymanifest: fix pure hg iterkeys()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   119
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   120
    def iterentries(self):
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   121
        return ((f, e[0], e[1]) for f, e in sorted(self.iteritems()))
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   122
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
   123
    def copy(self):
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   124
        c = _lazymanifest('')
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   125
        c.update(self)
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   126
        return c
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   127
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   128
    def diff(self, m2, clean=False):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   129
        '''Finds changes between the current manifest and m2.'''
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   130
        diff = {}
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   131
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   132
        for fn, e1 in self.iteritems():
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   133
            if fn not in m2:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   134
                diff[fn] = e1, (None, '')
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   135
            else:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   136
                e2 = m2[fn]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   137
                if e1 != e2:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   138
                    diff[fn] = e1, e2
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   139
                elif clean:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   140
                    diff[fn] = None
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   141
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   142
        for fn, e2 in m2.iteritems():
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   143
            if fn not in self:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   144
                diff[fn] = (None, ''), e2
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   145
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   146
        return diff
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   147
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   148
    def filtercopy(self, filterfn):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   149
        c = _lazymanifest('')
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   150
        for f, n, fl in self.iterentries():
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   151
            if filterfn(f):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   152
                c[f] = n, fl
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   153
        return c
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   154
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   155
    def text(self):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   156
        """Get the full data of this manifest as a bytestring."""
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   157
        return _textv1(self.iterentries())
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   158
24226
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   159
try:
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   160
    _lazymanifest = parsers.lazymanifest
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   161
except AttributeError:
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   162
    pass
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   163
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   164
class manifestdict(object):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   165
    def __init__(self, data=''):
24572
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   166
        if data.startswith('\0'):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   167
            #_lazymanifest can not parse v2
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   168
            self._lm = _lazymanifest('')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   169
            for f, n, fl in _parsev2(data):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   170
                self._lm[f] = n, fl
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   171
        else:
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   172
            self._lm = _lazymanifest(data)
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   173
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   174
    def __getitem__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   175
        return self._lm[key][0]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   176
24277
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   177
    def find(self, key):
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   178
        return self._lm[key]
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   179
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   180
    def __len__(self):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   181
        return len(self._lm)
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   182
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   183
    def __setitem__(self, key, node):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   184
        self._lm[key] = node, self.flags(key, '')
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   185
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   186
    def __contains__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   187
        return key in self._lm
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   188
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   189
    def __delitem__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   190
        del self._lm[key]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   191
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   192
    def __iter__(self):
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   193
        return self._lm.__iter__()
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   194
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   195
    def iterkeys(self):
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   196
        return self._lm.iterkeys()
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   197
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   198
    def keys(self):
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   199
        return list(self.iterkeys())
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   200
24184
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   201
    def filesnotin(self, m2):
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   202
        '''Set of files in this manifest that are not in the other'''
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   203
        files = set(self)
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   204
        files.difference_update(m2)
24184
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   205
        return files
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   206
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   207
    @propertycache
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   208
    def _dirs(self):
24635
21e1ece30f8c util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents: 24600
diff changeset
   209
        return util.dirs(self)
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   210
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   211
    def dirs(self):
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   212
        return self._dirs
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   213
24324
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   214
    def hasdir(self, dir):
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   215
        return dir in self._dirs
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   216
24685
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   217
    def _filesfastpath(self, match):
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   218
        '''Checks whether we can correctly and quickly iterate over matcher
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   219
        files instead of over manifest files.'''
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   220
        files = match.files()
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   221
        return (len(files) < 100 and (match.isexact() or
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   222
            (not match.anypats() and util.all(fn in self for fn in files))))
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   223
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   224
    def walk(self, match):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   225
        '''Generates matching file names.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   226
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   227
        Equivalent to manifest.matches(match).iterkeys(), but without creating
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   228
        an entirely new manifest.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   229
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   230
        It also reports nonexistent files by marking them bad with match.bad().
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   231
        '''
24683
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   232
        if match.always():
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   233
            for f in iter(self):
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   234
                yield f
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   235
            return
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   236
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   237
        fset = set(match.files())
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   238
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   239
        # avoid the entire walk if we're only looking for specific files
24685
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   240
        if self._filesfastpath(match):
24667
19c5b0913960 manifest.walk: join nested if-conditions
Martin von Zweigbergk <martinvonz@google.com>
parents: 24666
diff changeset
   241
            for fn in sorted(fset):
19c5b0913960 manifest.walk: join nested if-conditions
Martin von Zweigbergk <martinvonz@google.com>
parents: 24666
diff changeset
   242
                yield fn
24682
aef3d1469773 manifest.walk: use return instead of StopIteration in generator
Martin von Zweigbergk <martinvonz@google.com>
parents: 24670
diff changeset
   243
            return
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   244
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   245
        for fn in self:
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   246
            if fn in fset:
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   247
                # specified pattern is the exact name
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   248
                fset.remove(fn)
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   249
            if match(fn):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   250
                yield fn
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   251
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   252
        # for dirstate.walk, files=['.'] means "walk the whole tree".
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   253
        # follow that here, too
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   254
        fset.discard('.')
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   255
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   256
        for fn in sorted(fset):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   257
            if not self.hasdir(fn):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   258
                match.bad(fn, None)
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   259
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   260
    def matches(self, match):
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   261
        '''generate a new manifest filtered by the match argument'''
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   262
        if match.always():
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   263
            return self.copy()
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   264
24685
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   265
        if self._filesfastpath(match):
24666
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   266
            m = manifestdict()
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   267
            lm = self._lm
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   268
            for fn in match.files():
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   269
                if fn in lm:
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   270
                    m._lm[fn] = lm[fn]
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   271
            return m
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   272
24700
32b268cbff00 manifestdict: drop empty-string argument when creating empty manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24685
diff changeset
   273
        m = manifestdict()
24664
ea4a7c8909ae manifestdict.matches: avoid name 'lm' for a not-lazymanifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24647
diff changeset
   274
        m._lm = self._lm.filtercopy(match)
ea4a7c8909ae manifestdict.matches: avoid name 'lm' for a not-lazymanifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24647
diff changeset
   275
        return m
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   276
23756
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   277
    def diff(self, m2, clean=False):
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   278
        '''Finds changes between the current manifest and m2.
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   279
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   280
        Args:
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   281
          m2: the manifest to which this manifest should be compared.
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   282
          clean: if true, include files unchanged between these manifests
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   283
                 with a None value in the returned dictionary.
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   284
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   285
        The result is returned as a dict with filename as key and
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   286
        values of the form ((n1,fl1),(n2,fl2)), where n1/n2 is the
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   287
        nodeid in the current/other manifest and fl1/fl2 is the flag
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   288
        in the current/other manifest. Where the file does not exist,
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   289
        the nodeid will be None and the flags will be the empty
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   290
        string.
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   291
        '''
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   292
        return self._lm.diff(m2._lm, clean)
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   293
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   294
    def setflag(self, key, flag):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   295
        self._lm[key] = self[key], flag
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   296
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   297
    def get(self, key, default=None):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   298
        try:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   299
            return self._lm[key][0]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   300
        except KeyError:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   301
            return default
22965
b697fa74b475 manifest: for diff(), only iterate over files, not flags
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22964
diff changeset
   302
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   303
    def flags(self, key, default=''):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   304
        try:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   305
            return self._lm[key][1]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   306
        except KeyError:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   307
            return default
22965
b697fa74b475 manifest: for diff(), only iterate over files, not flags
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22964
diff changeset
   308
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   309
    def copy(self):
24700
32b268cbff00 manifestdict: drop empty-string argument when creating empty manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24685
diff changeset
   310
        c = manifestdict()
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   311
        c._lm = self._lm.copy()
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   312
        return c
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   313
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   314
    def iteritems(self):
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   315
        return (x[:2] for x in self._lm.iterentries())
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
   316
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   317
    def text(self, usemanifestv2=False):
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   318
        if usemanifestv2:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   319
            return _textv2(self._lm.iterentries())
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   320
        else:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   321
            # use (probably) native version for v1
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   322
            return self._lm.text()
22408
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   323
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   324
    def fastdelta(self, base, changes):
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   325
        """Given a base manifest text as an array.array and a list of changes
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   326
        relative to that text, compute a delta that can be used by revlog.
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   327
        """
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   328
        delta = []
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   329
        dstart = None
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   330
        dend = None
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   331
        dline = [""]
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   332
        start = 0
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   333
        # zero copy representation of base as a buffer
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   334
        addbuf = util.buffer(base)
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   335
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   336
        # start with a readonly loop that finds the offset of
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   337
        # each line and creates the deltas
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   338
        for f, todelete in changes:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   339
            # bs will either be the index of the item or the insert point
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   340
            start, end = _msearch(addbuf, f, start)
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   341
            if not todelete:
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   342
                h, fl = self._lm[f]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   343
                l = "%s\0%s%s\n" % (f, revlog.hex(h), fl)
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   344
            else:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   345
                if start == end:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   346
                    # item we want to delete was not found, error out
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   347
                    raise AssertionError(
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   348
                            _("failed to remove %s from manifest") % f)
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   349
                l = ""
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   350
            if dstart is not None and dstart <= start and dend >= start:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   351
                if dend < end:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   352
                    dend = end
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   353
                if l:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   354
                    dline.append(l)
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   355
            else:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   356
                if dstart is not None:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   357
                    delta.append([dstart, dend, "".join(dline)])
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   358
                dstart = start
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   359
                dend = end
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   360
                dline = [l]
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   361
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   362
        if dstart is not None:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   363
            delta.append([dstart, dend, "".join(dline)])
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   364
        # apply the delta to the base, and get a delta for addrevision
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   365
        deltatext, arraytext = _addlistdelta(base, delta)
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   366
        return arraytext, deltatext
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   367
22930
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   368
def _msearch(m, s, lo=0, hi=None):
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   369
    '''return a tuple (start, end) that says where to find s within m.
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   370
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   371
    If the string is found m[start:end] are the line containing
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   372
    that string.  If start == end the string was not found and
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   373
    they indicate the proper sorted insertion point.
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   374
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   375
    m should be a buffer or a string
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   376
    s is a string'''
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   377
    def advance(i, c):
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   378
        while i < lenm and m[i] != c:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   379
            i += 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   380
        return i
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   381
    if not s:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   382
        return (lo, lo)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   383
    lenm = len(m)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   384
    if not hi:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   385
        hi = lenm
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   386
    while lo < hi:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   387
        mid = (lo + hi) // 2
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   388
        start = mid
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   389
        while start > 0 and m[start - 1] != '\n':
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   390
            start -= 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   391
        end = advance(start, '\0')
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   392
        if m[start:end] < s:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   393
            # we know that after the null there are 40 bytes of sha1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   394
            # this translates to the bisect lo = mid + 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   395
            lo = advance(end + 40, '\n') + 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   396
        else:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   397
            # this translates to the bisect hi = mid
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   398
            hi = start
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   399
    end = advance(lo, '\0')
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   400
    found = m[lo:end]
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   401
    if s == found:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   402
        # we know that after the null there are 40 bytes of sha1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   403
        end = advance(end + 40, '\n')
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   404
        return (lo, end + 1)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   405
    else:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   406
        return (lo, lo)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   407
22415
65ec6c5c0fb3 manifest: mark addlistdelta and checkforbidden as module-private
Augie Fackler <raf@durin42.com>
parents: 22409
diff changeset
   408
def _checkforbidden(l):
22408
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   409
    """Check filenames for illegal characters."""
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   410
    for f in l:
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   411
        if '\n' in f or '\r' in f:
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   412
            raise error.RevlogError(
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   413
                _("'\\n' and '\\r' disallowed in filenames: %r") % f)
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   414
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   415
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   416
# apply the changes collected during the bisect loop to our addlist
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   417
# return a delta suitable for addrevision
22415
65ec6c5c0fb3 manifest: mark addlistdelta and checkforbidden as module-private
Augie Fackler <raf@durin42.com>
parents: 22409
diff changeset
   418
def _addlistdelta(addlist, x):
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   419
    # for large addlist arrays, building a new array is cheaper
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   420
    # than repeatedly modifying the existing one
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   421
    currentposition = 0
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   422
    newaddlist = array.array('c')
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   423
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   424
    for start, end, content in x:
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   425
        newaddlist += addlist[currentposition:start]
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   426
        if content:
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   427
            newaddlist += array.array('c', content)
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   428
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   429
        currentposition = end
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   430
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   431
    newaddlist += addlist[currentposition:]
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   432
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   433
    deltatext = "".join(struct.pack(">lll", start, end, len(content))
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   434
                   + content for start, end, content in x)
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   435
    return deltatext, newaddlist
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   436
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   437
def _splittopdir(f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   438
    if '/' in f:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   439
        dir, subpath = f.split('/', 1)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   440
        return dir + '/', subpath
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   441
    else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   442
        return '', f
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   443
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   444
class treemanifest(object):
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   445
    def __init__(self, dir='', text=''):
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   446
        self._dir = dir
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   447
        self._dirs = {}
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   448
        # Using _lazymanifest here is a little slower than plain old dicts
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   449
        self._files = {}
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   450
        self._flags = {}
24781
055b3cbe6c57 treemanifest: extract parse method from constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 24780
diff changeset
   451
        self.parse(text)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   452
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   453
    def _subpath(self, path):
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   454
        return self._dir + path
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   455
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   456
    def __len__(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   457
        size = len(self._files)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   458
        for m in self._dirs.values():
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   459
            size += m.__len__()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   460
        return size
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   461
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   462
    def _isempty(self):
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   463
        return (not self._files and (not self._dirs or
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   464
                util.all(m._isempty() for m in self._dirs.values())))
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   465
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   466
    def __str__(self):
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   467
        return '<treemanifest dir=%s>' % self._dir
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   468
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   469
    def iteritems(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   470
        for p, n in sorted(self._dirs.items() + self._files.items()):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   471
            if p in self._files:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   472
                yield self._subpath(p), n
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   473
            else:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   474
                for f, sn in n.iteritems():
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   475
                    yield f, sn
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   476
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   477
    def iterkeys(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   478
        for p in sorted(self._dirs.keys() + self._files.keys()):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   479
            if p in self._files:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   480
                yield self._subpath(p)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   481
            else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   482
                for f in self._dirs[p].iterkeys():
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   483
                    yield f
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   484
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   485
    def keys(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   486
        return list(self.iterkeys())
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   487
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   488
    def __iter__(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   489
        return self.iterkeys()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   490
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   491
    def __contains__(self, f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   492
        if f is None:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   493
            return False
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   494
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   495
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   496
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   497
                return False
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   498
            return self._dirs[dir].__contains__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   499
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   500
            return f in self._files
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   501
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   502
    def get(self, f, default=None):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   503
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   504
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   505
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   506
                return default
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   507
            return self._dirs[dir].get(subpath, default)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   508
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   509
            return self._files.get(f, default)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   510
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   511
    def __getitem__(self, f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   512
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   513
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   514
            return self._dirs[dir].__getitem__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   515
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   516
            return self._files[f]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   517
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   518
    def flags(self, f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   519
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   520
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   521
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   522
                return ''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   523
            return self._dirs[dir].flags(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   524
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   525
            if f in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   526
                return ''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   527
            return self._flags.get(f, '')
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   528
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   529
    def find(self, f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   530
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   531
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   532
            return self._dirs[dir].find(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   533
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   534
            return self._files[f], self._flags.get(f, '')
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   535
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   536
    def __delitem__(self, f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   537
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   538
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   539
            self._dirs[dir].__delitem__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   540
            # If the directory is now empty, remove it
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   541
            if self._dirs[dir]._isempty():
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   542
                del self._dirs[dir]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   543
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   544
            del self._files[f]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   545
            if f in self._flags:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   546
                del self._flags[f]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   547
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   548
    def __setitem__(self, f, n):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   549
        assert n is not None
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   550
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   551
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   552
            if dir not in self._dirs:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   553
                self._dirs[dir] = treemanifest(self._subpath(dir))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   554
            self._dirs[dir].__setitem__(subpath, n)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   555
        else:
24467
bfb754050ccd treemanifest: drop 22nd byte for consistency with manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24448
diff changeset
   556
            self._files[f] = n[:21] # to match manifestdict's behavior
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   557
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   558
    def setflag(self, f, flags):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   559
        """Set the flags (symlink, executable) for path f."""
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   560
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   561
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   562
            if dir not in self._dirs:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   563
                self._dirs[dir] = treemanifest(self._subpath(dir))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   564
            self._dirs[dir].setflag(subpath, flags)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   565
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   566
            self._flags[f] = flags
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   567
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   568
    def copy(self):
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   569
        copy = treemanifest(self._dir)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   570
        for d in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   571
            copy._dirs[d] = self._dirs[d].copy()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   572
        copy._files = dict.copy(self._files)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   573
        copy._flags = dict.copy(self._flags)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   574
        return copy
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   575
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   576
    def filesnotin(self, m2):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   577
        '''Set of files in this manifest that are not in the other'''
24405
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   578
        files = set()
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   579
        def _filesnotin(t1, t2):
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   580
            for d, m1 in t1._dirs.iteritems():
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   581
                if d in t2._dirs:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   582
                    m2 = t2._dirs[d]
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   583
                    _filesnotin(m1, m2)
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   584
                else:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   585
                    files.update(m1.iterkeys())
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   586
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   587
            for fn in t1._files.iterkeys():
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   588
                if fn not in t2._files:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   589
                    files.add(t1._subpath(fn))
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   590
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   591
        _filesnotin(self, m2)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   592
        return files
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   593
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   594
    @propertycache
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   595
    def _alldirs(self):
24635
21e1ece30f8c util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents: 24600
diff changeset
   596
        return util.dirs(self)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   597
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   598
    def dirs(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   599
        return self._alldirs
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   600
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   601
    def hasdir(self, dir):
24406
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   602
        topdir, subdir = _splittopdir(dir)
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   603
        if topdir:
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   604
            if topdir in self._dirs:
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   605
                return self._dirs[topdir].hasdir(subdir)
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   606
            return False
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   607
        return (dir + '/') in self._dirs
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   608
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   609
    def walk(self, match):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   610
        '''Generates matching file names.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   611
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   612
        Equivalent to manifest.matches(match).iterkeys(), but without creating
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   613
        an entirely new manifest.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   614
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   615
        It also reports nonexistent files by marking them bad with match.bad().
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   616
        '''
24683
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   617
        if match.always():
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   618
            for f in iter(self):
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   619
                yield f
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   620
            return
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   621
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   622
        fset = set(match.files())
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   623
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   624
        for fn in self._walk(match):
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   625
            if fn in fset:
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   626
                # specified pattern is the exact name
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   627
                fset.remove(fn)
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   628
            yield fn
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   629
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   630
        # for dirstate.walk, files=['.'] means "walk the whole tree".
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   631
        # follow that here, too
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   632
        fset.discard('.')
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   633
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   634
        for fn in sorted(fset):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   635
            if not self.hasdir(fn):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   636
                match.bad(fn, None)
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   637
24670
dfb86af18a35 treemanifest: optimize treemanifest._walk() to skip directories
Drew Gottlieb <drgott@google.com>
parents: 24667
diff changeset
   638
    def _walk(self, match, alldirs=False):
dfb86af18a35 treemanifest: optimize treemanifest._walk() to skip directories
Drew Gottlieb <drgott@google.com>
parents: 24667
diff changeset
   639
        '''Recursively generates matching file names for walk().
dfb86af18a35 treemanifest: optimize treemanifest._walk() to skip directories
Drew Gottlieb <drgott@google.com>
parents: 24667
diff changeset
   640
dfb86af18a35 treemanifest: optimize treemanifest._walk() to skip directories
Drew Gottlieb <drgott@google.com>
parents: 24667
diff changeset
   641
        Will visit all subdirectories if alldirs is True, otherwise it will
dfb86af18a35 treemanifest: optimize treemanifest._walk() to skip directories
Drew Gottlieb <drgott@google.com>
parents: 24667
diff changeset
   642
        only visit subdirectories for which match.visitdir is True.'''
dfb86af18a35 treemanifest: optimize treemanifest._walk() to skip directories
Drew Gottlieb <drgott@google.com>
parents: 24667
diff changeset
   643
dfb86af18a35 treemanifest: optimize treemanifest._walk() to skip directories
Drew Gottlieb <drgott@google.com>
parents: 24667
diff changeset
   644
        if not alldirs:
dfb86af18a35 treemanifest: optimize treemanifest._walk() to skip directories
Drew Gottlieb <drgott@google.com>
parents: 24667
diff changeset
   645
            # substring to strip trailing slash
dfb86af18a35 treemanifest: optimize treemanifest._walk() to skip directories
Drew Gottlieb <drgott@google.com>
parents: 24667
diff changeset
   646
            visit = match.visitdir(self._dir[:-1] or '.')
dfb86af18a35 treemanifest: optimize treemanifest._walk() to skip directories
Drew Gottlieb <drgott@google.com>
parents: 24667
diff changeset
   647
            if not visit:
dfb86af18a35 treemanifest: optimize treemanifest._walk() to skip directories
Drew Gottlieb <drgott@google.com>
parents: 24667
diff changeset
   648
                return
dfb86af18a35 treemanifest: optimize treemanifest._walk() to skip directories
Drew Gottlieb <drgott@google.com>
parents: 24667
diff changeset
   649
            alldirs = (visit == 'all')
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   650
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   651
        # yield this dir's files and walk its submanifests
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   652
        for p in sorted(self._dirs.keys() + self._files.keys()):
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   653
            if p in self._files:
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   654
                fullp = self._subpath(p)
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   655
                if match(fullp):
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   656
                    yield fullp
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   657
            else:
24670
dfb86af18a35 treemanifest: optimize treemanifest._walk() to skip directories
Drew Gottlieb <drgott@google.com>
parents: 24667
diff changeset
   658
                for f in self._dirs[p]._walk(match, alldirs):
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   659
                    yield f
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   660
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   661
    def matches(self, match):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   662
        '''generate a new manifest filtered by the match argument'''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   663
        if match.always():
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   664
            return self.copy()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   665
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   666
        return self._matches(match)
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   667
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24635
diff changeset
   668
    def _matches(self, match, alldirs=False):
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   669
        '''recursively generate a new manifest filtered by the match argument.
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24635
diff changeset
   670
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24635
diff changeset
   671
        Will visit all subdirectories if alldirs is True, otherwise it will
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24635
diff changeset
   672
        only visit subdirectories for which match.visitdir is True.'''
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   673
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   674
        ret = treemanifest(self._dir)
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24635
diff changeset
   675
        if not alldirs:
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24635
diff changeset
   676
            # substring to strip trailing slash
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24635
diff changeset
   677
            visit = match.visitdir(self._dir[:-1] or '.')
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24635
diff changeset
   678
            if not visit:
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24635
diff changeset
   679
                return ret
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24635
diff changeset
   680
            alldirs = (visit == 'all')
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   681
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   682
        for fn in self._files:
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   683
            fullp = self._subpath(fn)
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   684
            if not match(fullp):
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   685
                continue
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   686
            ret._files[fn] = self._files[fn]
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   687
            if fn in self._flags:
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   688
                ret._flags[fn] = self._flags[fn]
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   689
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   690
        for dir, subm in self._dirs.iteritems():
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24635
diff changeset
   691
            m = subm._matches(match, alldirs)
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   692
            if not m._isempty():
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   693
                ret._dirs[dir] = m
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   694
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   695
        return ret
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   696
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   697
    def diff(self, m2, clean=False):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   698
        '''Finds changes between the current manifest and m2.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   699
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   700
        Args:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   701
          m2: the manifest to which this manifest should be compared.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   702
          clean: if true, include files unchanged between these manifests
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   703
                 with a None value in the returned dictionary.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   704
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   705
        The result is returned as a dict with filename as key and
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   706
        values of the form ((n1,fl1),(n2,fl2)), where n1/n2 is the
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   707
        nodeid in the current/other manifest and fl1/fl2 is the flag
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   708
        in the current/other manifest. Where the file does not exist,
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   709
        the nodeid will be None and the flags will be the empty
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   710
        string.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   711
        '''
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   712
        result = {}
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   713
        emptytree = treemanifest()
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   714
        def _diff(t1, t2):
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   715
            for d, m1 in t1._dirs.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   716
                m2 = t2._dirs.get(d, emptytree)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   717
                _diff(m1, m2)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   718
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   719
            for d, m2 in t2._dirs.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   720
                if d not in t1._dirs:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   721
                    _diff(emptytree, m2)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   722
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   723
            for fn, n1 in t1._files.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   724
                fl1 = t1._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   725
                n2 = t2._files.get(fn, None)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   726
                fl2 = t2._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   727
                if n1 != n2 or fl1 != fl2:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   728
                    result[t1._subpath(fn)] = ((n1, fl1), (n2, fl2))
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   729
                elif clean:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   730
                    result[t1._subpath(fn)] = None
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   731
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   732
            for fn, n2 in t2._files.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   733
                if fn not in t1._files:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   734
                    fl2 = t2._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   735
                    result[t2._subpath(fn)] = ((None, ''), (n2, fl2))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   736
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   737
        _diff(self, m2)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   738
        return result
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   739
24781
055b3cbe6c57 treemanifest: extract parse method from constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 24780
diff changeset
   740
    def parse(self, text):
055b3cbe6c57 treemanifest: extract parse method from constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 24780
diff changeset
   741
        for f, n, fl in _parse(text):
055b3cbe6c57 treemanifest: extract parse method from constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 24780
diff changeset
   742
            self[f] = n
055b3cbe6c57 treemanifest: extract parse method from constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 24780
diff changeset
   743
            if fl:
055b3cbe6c57 treemanifest: extract parse method from constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 24780
diff changeset
   744
                self.setflag(f, fl)
055b3cbe6c57 treemanifest: extract parse method from constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 24780
diff changeset
   745
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   746
    def text(self, usemanifestv2=False):
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   747
        """Get the full data of this manifest as a bytestring."""
24525
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
   748
        flags = self.flags
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   749
        return _text(((f, self[f], flags(f)) for f in self.keys()),
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   750
                     usemanifestv2)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   751
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   752
class manifest(revlog.revlog):
4258
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 4257
diff changeset
   753
    def __init__(self, opener):
24033
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
   754
        # During normal operations, we expect to deal with not more than four
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
   755
        # revs at a time (such as during commit --amend). When rebasing large
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
   756
        # stacks of commits, the number can go up, hence the config knob below.
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
   757
        cachesize = 4
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   758
        usetreemanifest = False
24526
cd50f3717639 manifestv2: add (unused) config option
Martin von Zweigbergk <martinvonz@google.com>
parents: 24525
diff changeset
   759
        usemanifestv2 = False
24033
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
   760
        opts = getattr(opener, 'options', None)
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
   761
        if opts is not None:
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
   762
            cachesize = opts.get('manifestcachesize', cachesize)
24956
48583a1e44f3 treemanifest: set requires at repo creation time, ignore config after
Martin von Zweigbergk <martinvonz@google.com>
parents: 24925
diff changeset
   763
            usetreemanifest = opts.get('treemanifest', usetreemanifest)
24571
919f8ce040be manifestv2: set requires at repo creation time
Martin von Zweigbergk <martinvonz@google.com>
parents: 24552
diff changeset
   764
            usemanifestv2 = opts.get('manifestv2', usemanifestv2)
24033
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
   765
        self._mancache = util.lrucachedict(cachesize)
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   766
        revlog.revlog.__init__(self, opener, "00manifest.i")
24701
03ee576784e6 treemanifest: separate flags for trees in memory and trees on disk
Martin von Zweigbergk <martinvonz@google.com>
parents: 24700
diff changeset
   767
        self._treeinmem = usetreemanifest
03ee576784e6 treemanifest: separate flags for trees in memory and trees on disk
Martin von Zweigbergk <martinvonz@google.com>
parents: 24700
diff changeset
   768
        self._treeondisk = usetreemanifest
24526
cd50f3717639 manifestv2: add (unused) config option
Martin von Zweigbergk <martinvonz@google.com>
parents: 24525
diff changeset
   769
        self._usemanifestv2 = usemanifestv2
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   770
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   771
    def _newmanifest(self, data=''):
24701
03ee576784e6 treemanifest: separate flags for trees in memory and trees on disk
Martin von Zweigbergk <martinvonz@google.com>
parents: 24700
diff changeset
   772
        if self._treeinmem:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   773
            return treemanifest('', data)
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   774
        return manifestdict(data)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   775
24528
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
   776
    def _slowreaddelta(self, node):
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
   777
        r0 = self.deltaparent(self.rev(node))
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
   778
        m0 = self.read(self.node(r0))
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
   779
        m1 = self.read(node)
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
   780
        md = self._newmanifest()
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
   781
        for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
   782
            if n1:
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
   783
                md[f] = n1
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
   784
                if fl1:
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
   785
                    md.setflag(f, fl1)
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
   786
        return md
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
   787
3196
f3b939444c72 Abstract manifest block parsing.
Brendan Cully <brendan@kublai.com>
parents: 3148
diff changeset
   788
    def readdelta(self, node):
24701
03ee576784e6 treemanifest: separate flags for trees in memory and trees on disk
Martin von Zweigbergk <martinvonz@google.com>
parents: 24700
diff changeset
   789
        if self._usemanifestv2 or self._treeondisk:
24528
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
   790
            return self._slowreaddelta(node)
7362
6db4a2ccef3a revlog: remove delta function
Matt Mackall <mpm@selenic.com>
parents: 6765
diff changeset
   791
        r = self.rev(node)
24224
d71837d06597 manifest: do parsing inside manifestdict contstructor
Augie Fackler <augie@google.com>
parents: 24223
diff changeset
   792
        d = mdiff.patchtext(self.revdiff(self.deltaparent(r), r))
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   793
        return self._newmanifest(d)
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3196
diff changeset
   794
13711
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   795
    def readfast(self, node):
24925
d9832a12a06e manifest: document return type of readfast()
Augie Fackler <augie@google.com>
parents: 24781
diff changeset
   796
        '''use the faster of readdelta or read
d9832a12a06e manifest: document return type of readfast()
Augie Fackler <augie@google.com>
parents: 24781
diff changeset
   797
d9832a12a06e manifest: document return type of readfast()
Augie Fackler <augie@google.com>
parents: 24781
diff changeset
   798
        This will return a manifest which is either only the files
d9832a12a06e manifest: document return type of readfast()
Augie Fackler <augie@google.com>
parents: 24781
diff changeset
   799
        added/modified relative to p1, or all files in the
d9832a12a06e manifest: document return type of readfast()
Augie Fackler <augie@google.com>
parents: 24781
diff changeset
   800
        manifest. Which one is returned depends on the codepath used
d9832a12a06e manifest: document return type of readfast()
Augie Fackler <augie@google.com>
parents: 24781
diff changeset
   801
        to retrieve the data.
d9832a12a06e manifest: document return type of readfast()
Augie Fackler <augie@google.com>
parents: 24781
diff changeset
   802
        '''
13711
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   803
        r = self.rev(node)
14208
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 13711
diff changeset
   804
        deltaparent = self.deltaparent(r)
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 13711
diff changeset
   805
        if deltaparent != revlog.nullrev and deltaparent in self.parentrevs(r):
13711
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   806
            return self.readdelta(node)
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   807
        return self.read(node)
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   808
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   809
    def read(self, node):
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   810
        if node == revlog.nullid:
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   811
            return self._newmanifest() # don't upset local cache
18604
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
   812
        if node in self._mancache:
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
   813
            return self._mancache[node][0]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   814
        text = self.revision(node)
9414
65dc516363ee manifest: simplify cache handling, use a unique cache
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9413
diff changeset
   815
        arraytext = array.array('c', text)
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   816
        m = self._newmanifest(text)
24147
ba4fcd80079d manifest: rename 'mf', 'map', and 'mapping' to 'm'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24146
diff changeset
   817
        self._mancache[node] = (m, arraytext)
ba4fcd80079d manifest: rename 'mf', 'map', and 'mapping' to 'm'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24146
diff changeset
   818
        return m
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   819
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   820
    def find(self, node, f):
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   821
        '''look up entry for a single file efficiently.
4159
a896607d3ec3 fix manifest.find
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3891
diff changeset
   822
        return (node, flags) pair if found, (None, None) if not.'''
24292
b7add2ebef9e manifest: rewrite find(node, f) in terms of read(node)
Martin von Zweigbergk <martinvonz@google.com>
parents: 24277
diff changeset
   823
        m = self.read(node)
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   824
        try:
24292
b7add2ebef9e manifest: rewrite find(node, f) in terms of read(node)
Martin von Zweigbergk <martinvonz@google.com>
parents: 24277
diff changeset
   825
            return m.find(f)
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   826
        except KeyError:
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   827
            return None, None
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   828
24147
ba4fcd80079d manifest: rename 'mf', 'map', and 'mapping' to 'm'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24146
diff changeset
   829
    def add(self, m, transaction, link, p1, p2, added, removed):
24701
03ee576784e6 treemanifest: separate flags for trees in memory and trees on disk
Martin von Zweigbergk <martinvonz@google.com>
parents: 24700
diff changeset
   830
        if (p1 in self._mancache and not self._treeinmem
24527
8aead3bc5ff8 manifestv2: disable fastdelta optimization
Martin von Zweigbergk <martinvonz@google.com>
parents: 24526
diff changeset
   831
            and not self._usemanifestv2):
22788
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   832
            # If our first parent is in the manifest cache, we can
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   833
            # compute a delta here using properties we know about the
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   834
            # manifest up-front, which may save time later for the
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   835
            # revlog layer.
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   836
22415
65ec6c5c0fb3 manifest: mark addlistdelta and checkforbidden as module-private
Augie Fackler <raf@durin42.com>
parents: 22409
diff changeset
   837
            _checkforbidden(added)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   838
            # combine the changed lists into one list for sorting
9415
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   839
            work = [(x, False) for x in added]
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   840
            work.extend((x, True) for x in removed)
17428
72803c8edaa4 avoid using abbreviations that look like spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17426
diff changeset
   841
            # this could use heapq.merge() (from Python 2.6+) or equivalent
9415
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   842
            # since the lists are already sorted
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   843
            work.sort()
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   844
24147
ba4fcd80079d manifest: rename 'mf', 'map', and 'mapping' to 'm'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24146
diff changeset
   845
            arraytext, deltatext = m.fastdelta(self._mancache[p1][1], work)
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   846
            cachedelta = self.rev(p1), deltatext
15657
d976b1ef6760 util: don't mess with builtins to emulate buffer()
Matt Mackall <mpm@selenic.com>
parents: 14632
diff changeset
   847
            text = util.buffer(arraytext)
24780
4ea521b3c554 manifest: duplicate call to addrevision()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24701
diff changeset
   848
            n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
22788
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   849
        else:
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   850
            # The first parent manifest isn't already loaded, so we'll
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   851
            # just encode a fulltext of the manifest and pass that
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   852
            # through to the revlog layer, and let it handle the delta
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   853
            # process.
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   854
            text = m.text(self._usemanifestv2)
22788
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   855
            arraytext = array.array('c', text)
24780
4ea521b3c554 manifest: duplicate call to addrevision()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24701
diff changeset
   856
            n = self.addrevision(text, transaction, link, p1, p2)
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   857
24147
ba4fcd80079d manifest: rename 'mf', 'map', and 'mapping' to 'm'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24146
diff changeset
   858
        self._mancache[n] = (m, arraytext)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   859
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   860
        return n