mercurial/manifest.py
author Martin von Zweigbergk <martinvonz@google.com>
Fri, 27 Mar 2015 15:37:46 -0700
changeset 24525 e118f74d246f
parent 24524 63b6031384fc
child 24526 cd50f3717639
permissions -rw-r--r--
manifest: extract method for creating manifest text Similar to the previous change, this one extracts a method for producing a manifest text from an iterator over (path, node, flags) tuples.
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 _
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
     9
import mdiff, parsers, error, revlog, util, scmutil
8312
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8225
diff changeset
    10
import array, struct
79
837d473d54d5 Add basic annotation support
mpm@selenic.com
parents: 78
diff changeset
    11
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
    12
propertycache = util.propertycache
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    13
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    14
def _parse(data):
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    15
    """Generates (path, node, flags) tuples from a manifest text"""
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
24525
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    34
def _text(it):
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    35
    """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
    36
    text"""
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    37
    files = []
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    38
    lines = []
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    39
    _hex = revlog.hex
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    40
    for f, n, fl in it:
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    41
        files.append(f)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    42
        # 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
    43
        # 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
    44
        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
    45
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    46
    _checkforbidden(files)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    47
    return ''.join(lines)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    48
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    49
class _lazymanifest(dict):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    50
    """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
    51
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    52
    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
    53
    """
24223
b4df0d0c49e7 manifest: move parsing functions up in file
Augie Fackler <augie@google.com>
parents: 24215
diff changeset
    54
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    55
    def __init__(self, data):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    56
        dict.__init__(self)
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    57
        for f, n, fl in _parse(data):
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    58
            self[f] = n, fl
24224
d71837d06597 manifest: do parsing inside manifestdict contstructor
Augie Fackler <augie@google.com>
parents: 24223
diff changeset
    59
23594
6f53629ad273 manifest: disallow setting the node id of an entry to None
Augie Fackler <augie@google.com>
parents: 22966
diff changeset
    60
    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
    61
        node, flag = v
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    62
        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
    63
        if len(node) > 21:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    64
            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
    65
        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
    66
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    67
    def __iter__(self):
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
    68
        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
    69
24297
0178f500d61e lazymanifest: fix pure hg iterkeys()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
    70
    def iterkeys(self):
0178f500d61e lazymanifest: fix pure hg iterkeys()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
    71
        return iter(sorted(dict.keys(self)))
0178f500d61e lazymanifest: fix pure hg iterkeys()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
    72
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
    73
    def iterentries(self):
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
    74
        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
    75
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
    76
    def copy(self):
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    77
        c = _lazymanifest('')
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    78
        c.update(self)
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    79
        return c
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    80
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    81
    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
    82
        '''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
    83
        diff = {}
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    84
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    85
        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
    86
            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
    87
                diff[fn] = e1, (None, '')
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    88
            else:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    89
                e2 = m2[fn]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    90
                if e1 != e2:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    91
                    diff[fn] = e1, e2
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    92
                elif clean:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    93
                    diff[fn] = None
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    94
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    95
        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
    96
            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
    97
                diff[fn] = (None, ''), e2
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
        return diff
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   100
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   101
    def filtercopy(self, filterfn):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   102
        c = _lazymanifest('')
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   103
        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
   104
            if filterfn(f):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   105
                c[f] = n, fl
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   106
        return c
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   107
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   108
    def text(self):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   109
        """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
   110
        return _text(self.iterentries())
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   111
24226
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   112
try:
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   113
    _lazymanifest = parsers.lazymanifest
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   114
except AttributeError:
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   115
    pass
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   116
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   117
class manifestdict(object):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   118
    def __init__(self, data=''):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   119
        self._lm = _lazymanifest(data)
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   120
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   121
    def __getitem__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   122
        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
   123
24277
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   124
    def find(self, key):
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   125
        return self._lm[key]
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   126
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   127
    def __len__(self):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   128
        return len(self._lm)
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   129
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   130
    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
   131
        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
   132
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   133
    def __contains__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   134
        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
   135
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   136
    def __delitem__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   137
        del self._lm[key]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   138
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   139
    def __iter__(self):
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   140
        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
   141
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   142
    def iterkeys(self):
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   143
        return self._lm.iterkeys()
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   144
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   145
    def keys(self):
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   146
        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
   147
24495
d2a3a2808974 manifest: make manifest.intersectfiles() internal
Drew Gottlieb <drgott@google.com>
parents: 24467
diff changeset
   148
    def _intersectfiles(self, files):
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   149
        '''make a new lazymanifest with the intersection of self with files
21879
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
   150
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
   151
        The algorithm assumes that files is much smaller than self.'''
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
   152
        ret = manifestdict()
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   153
        lm = self._lm
21879
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
   154
        for fn in files:
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   155
            if fn in lm:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   156
                ret._lm[fn] = self._lm[fn]
21879
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
   157
        return ret
22964
2793ecb1522d manifest: repurpose flagsdiff() into (node-and-flag)diff()
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22943
diff changeset
   158
24184
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   159
    def filesnotin(self, m2):
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   160
        '''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
   161
        files = set(self)
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   162
        files.difference_update(m2)
24184
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   163
        return files
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   164
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   165
    @propertycache
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   166
    def _dirs(self):
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   167
        return scmutil.dirs(self)
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   168
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   169
    def dirs(self):
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   170
        return self._dirs
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   171
24324
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   172
    def hasdir(self, dir):
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   173
        return dir in self._dirs
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   174
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   175
    def matches(self, match):
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   176
        '''generate a new manifest filtered by the match argument'''
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   177
        if match.always():
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   178
            return self.copy()
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   179
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   180
        files = match.files()
24448
55c449345b10 match: add isexact() method to hide internals
Martin von Zweigbergk <martinvonz@google.com>
parents: 24406
diff changeset
   181
        if (len(files) < 100 and (match.isexact() or
24396
9e03602cd2d8 manifest: avoid intersectfiles for matches > 100 files
Durham Goode <durham@fb.com>
parents: 24350
diff changeset
   182
            (not match.anypats() and util.all(fn in self for fn in files)))):
24495
d2a3a2808974 manifest: make manifest.intersectfiles() internal
Drew Gottlieb <drgott@google.com>
parents: 24467
diff changeset
   183
            return self._intersectfiles(files)
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   184
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   185
        lm = manifestdict('')
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   186
        lm._lm = self._lm.filtercopy(match)
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   187
        return lm
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   188
23756
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   189
    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
   190
        '''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
   191
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   192
        Args:
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   193
          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
   194
          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
   195
                 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
   196
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   197
        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
   198
        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
   199
        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
   200
        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
   201
        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
   202
        string.
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   203
        '''
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   204
        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
   205
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   206
    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
   207
        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
   208
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   209
    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
   210
        try:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   211
            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
   212
        except KeyError:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   213
            return default
22965
b697fa74b475 manifest: for diff(), only iterate over files, not flags
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22964
diff changeset
   214
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   215
    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
   216
        try:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   217
            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
   218
        except KeyError:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   219
            return default
22965
b697fa74b475 manifest: for diff(), only iterate over files, not flags
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22964
diff changeset
   220
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   221
    def copy(self):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   222
        c = manifestdict('')
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   223
        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
   224
        return c
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   226
    def iteritems(self):
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   227
        return (x[:2] for x in self._lm.iterentries())
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
   228
22929
bf69cb09a6c9 manifest: move manifestdict-to-text encoding to manifest class
Augie Fackler <raf@durin42.com>
parents: 22788
diff changeset
   229
    def text(self):
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   230
        return self._lm.text()
22408
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   231
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   232
    def fastdelta(self, base, changes):
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   233
        """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
   234
        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
   235
        """
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   236
        delta = []
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   237
        dstart = None
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   238
        dend = None
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   239
        dline = [""]
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   240
        start = 0
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   241
        # zero copy representation of base as a buffer
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   242
        addbuf = util.buffer(base)
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   243
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   244
        # 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
   245
        # each line and creates the deltas
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   246
        for f, todelete in changes:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   247
            # 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
   248
            start, end = _msearch(addbuf, f, start)
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   249
            if not todelete:
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   250
                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
   251
                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
   252
            else:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   253
                if start == end:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   254
                    # 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
   255
                    raise AssertionError(
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   256
                            _("failed to remove %s from manifest") % f)
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   257
                l = ""
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   258
            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
   259
                if dend < end:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   260
                    dend = end
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   261
                if l:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   262
                    dline.append(l)
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   263
            else:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   264
                if dstart is not None:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   265
                    delta.append([dstart, dend, "".join(dline)])
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   266
                dstart = start
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   267
                dend = end
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   268
                dline = [l]
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   269
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   270
        if dstart is not None:
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   271
            delta.append([dstart, dend, "".join(dline)])
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   272
        # 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
   273
        deltatext, arraytext = _addlistdelta(base, delta)
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   274
        return arraytext, deltatext
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   275
22930
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   276
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
   277
    '''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
   278
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   279
    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
   280
    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
   281
    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
   282
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   283
    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
   284
    s is a string'''
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   285
    def advance(i, c):
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   286
        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
   287
            i += 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   288
        return i
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   289
    if not s:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   290
        return (lo, lo)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   291
    lenm = len(m)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   292
    if not hi:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   293
        hi = lenm
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   294
    while lo < hi:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   295
        mid = (lo + hi) // 2
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   296
        start = mid
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   297
        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
   298
            start -= 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   299
        end = advance(start, '\0')
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   300
        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
   301
            # 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
   302
            # 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
   303
            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
   304
        else:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   305
            # 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
   306
            hi = start
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   307
    end = advance(lo, '\0')
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   308
    found = m[lo:end]
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   309
    if s == found:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   310
        # 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
   311
        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
   312
        return (lo, end + 1)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   313
    else:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   314
        return (lo, lo)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   315
22415
65ec6c5c0fb3 manifest: mark addlistdelta and checkforbidden as module-private
Augie Fackler <raf@durin42.com>
parents: 22409
diff changeset
   316
def _checkforbidden(l):
22408
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   317
    """Check filenames for illegal characters."""
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   318
    for f in l:
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   319
        if '\n' in f or '\r' in f:
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   320
            raise error.RevlogError(
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   321
                _("'\\n' and '\\r' disallowed in filenames: %r") % f)
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   322
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   323
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   324
# 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
   325
# 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
   326
def _addlistdelta(addlist, x):
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   327
    # 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
   328
    # than repeatedly modifying the existing one
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   329
    currentposition = 0
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   330
    newaddlist = array.array('c')
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   331
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   332
    for start, end, content in x:
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   333
        newaddlist += addlist[currentposition:start]
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   334
        if content:
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   335
            newaddlist += array.array('c', content)
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   336
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   337
        currentposition = end
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   338
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   339
    newaddlist += addlist[currentposition:]
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   340
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   341
    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
   342
                   + content for start, end, content in x)
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   343
    return deltatext, newaddlist
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   344
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   345
def _splittopdir(f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   346
    if '/' in f:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   347
        dir, subpath = f.split('/', 1)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   348
        return dir + '/', subpath
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   349
    else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   350
        return '', f
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   351
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   352
class treemanifest(object):
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   353
    def __init__(self, dir='', text=''):
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   354
        self._dir = dir
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   355
        self._dirs = {}
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   356
        # 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
   357
        self._files = {}
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   358
        self._flags = {}
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
   359
        for f, n, fl in _parse(text):
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   360
            self[f] = n
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   361
            if fl:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   362
                self.setflag(f, fl)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   363
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   364
    def _subpath(self, path):
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   365
        return self._dir + path
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   366
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   367
    def __len__(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   368
        size = len(self._files)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   369
        for m in self._dirs.values():
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   370
            size += m.__len__()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   371
        return size
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   372
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   373
    def __str__(self):
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   374
        return '<treemanifest dir=%s>' % self._dir
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   375
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   376
    def iteritems(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   377
        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
   378
            if p in self._files:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   379
                yield self._subpath(p), n
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   380
            else:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   381
                for f, sn in n.iteritems():
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   382
                    yield f, sn
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   383
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   384
    def iterkeys(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   385
        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
   386
            if p in self._files:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   387
                yield self._subpath(p)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   388
            else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   389
                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
   390
                    yield f
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   391
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   392
    def keys(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   393
        return list(self.iterkeys())
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   394
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   395
    def __iter__(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   396
        return self.iterkeys()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   397
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   398
    def __contains__(self, f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   399
        if f is None:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   400
            return False
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   401
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   402
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   403
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   404
                return False
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   405
            return self._dirs[dir].__contains__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   406
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   407
            return f in self._files
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   408
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   409
    def get(self, f, default=None):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   410
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   411
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   412
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   413
                return default
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   414
            return self._dirs[dir].get(subpath, default)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   415
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   416
            return self._files.get(f, default)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   417
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   418
    def __getitem__(self, f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   419
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   420
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   421
            return self._dirs[dir].__getitem__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   422
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   423
            return self._files[f]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   424
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   425
    def flags(self, f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   426
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   427
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   428
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   429
                return ''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   430
            return self._dirs[dir].flags(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   431
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   432
            if f in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   433
                return ''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   434
            return self._flags.get(f, '')
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   435
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   436
    def find(self, f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   437
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   438
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   439
            return self._dirs[dir].find(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   440
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   441
            return self._files[f], self._flags.get(f, '')
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   442
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   443
    def __delitem__(self, f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   444
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   445
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   446
            self._dirs[dir].__delitem__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   447
            # If the directory is now empty, remove it
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   448
            if not self._dirs[dir]._dirs and not self._dirs[dir]._files:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   449
                del self._dirs[dir]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   450
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   451
            del self._files[f]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   452
            if f in self._flags:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   453
                del self._flags[f]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   454
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   455
    def __setitem__(self, f, n):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   456
        assert n is not None
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   457
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   458
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   459
            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
   460
                self._dirs[dir] = treemanifest(self._subpath(dir))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   461
            self._dirs[dir].__setitem__(subpath, n)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   462
        else:
24467
bfb754050ccd treemanifest: drop 22nd byte for consistency with manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24448
diff changeset
   463
            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
   464
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   465
    def setflag(self, f, flags):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   466
        """Set the flags (symlink, executable) for path f."""
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   467
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   468
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   469
            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
   470
                self._dirs[dir] = treemanifest(self._subpath(dir))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   471
            self._dirs[dir].setflag(subpath, flags)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   472
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   473
            self._flags[f] = flags
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   474
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   475
    def copy(self):
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   476
        copy = treemanifest(self._dir)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   477
        for d in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   478
            copy._dirs[d] = self._dirs[d].copy()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   479
        copy._files = dict.copy(self._files)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   480
        copy._flags = dict.copy(self._flags)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   481
        return copy
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   482
24495
d2a3a2808974 manifest: make manifest.intersectfiles() internal
Drew Gottlieb <drgott@google.com>
parents: 24467
diff changeset
   483
    def _intersectfiles(self, files):
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   484
        '''make a new treemanifest with the intersection of self with files
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   485
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   486
        The algorithm assumes that files is much smaller than self.'''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   487
        ret = treemanifest()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   488
        for fn in files:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   489
            if fn in self:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   490
                ret[fn] = self[fn]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   491
                flags = self.flags(fn)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   492
                if flags:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   493
                    ret.setflag(fn, flags)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   494
        return ret
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   495
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   496
    def filesnotin(self, m2):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   497
        '''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
   498
        files = set()
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   499
        def _filesnotin(t1, t2):
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   500
            for d, m1 in t1._dirs.iteritems():
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   501
                if d in t2._dirs:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   502
                    m2 = t2._dirs[d]
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   503
                    _filesnotin(m1, m2)
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   504
                else:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   505
                    files.update(m1.iterkeys())
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   506
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   507
            for fn in t1._files.iterkeys():
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   508
                if fn not in t2._files:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   509
                    files.add(t1._subpath(fn))
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   510
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   511
        _filesnotin(self, m2)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   512
        return files
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   513
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   514
    @propertycache
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   515
    def _alldirs(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   516
        return scmutil.dirs(self)
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 dirs(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   519
        return self._alldirs
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   520
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   521
    def hasdir(self, dir):
24406
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   522
        topdir, subdir = _splittopdir(dir)
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   523
        if topdir:
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   524
            if topdir in self._dirs:
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   525
                return self._dirs[topdir].hasdir(subdir)
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   526
            return False
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   527
        return (dir + '/') in self._dirs
24401
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 matches(self, match):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   530
        '''generate a new manifest filtered by the match argument'''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   531
        if match.always():
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   532
            return self.copy()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   533
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   534
        files = match.files()
24448
55c449345b10 match: add isexact() method to hide internals
Martin von Zweigbergk <martinvonz@google.com>
parents: 24406
diff changeset
   535
        if (match.isexact() or
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   536
            (not match.anypats() and util.all(fn in self for fn in files))):
24495
d2a3a2808974 manifest: make manifest.intersectfiles() internal
Drew Gottlieb <drgott@google.com>
parents: 24467
diff changeset
   537
            return self._intersectfiles(files)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   538
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   539
        m = self.copy()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   540
        for fn in m.keys():
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   541
            if not match(fn):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   542
                del m[fn]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   543
        return m
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   544
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   545
    def diff(self, m2, clean=False):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   546
        '''Finds changes between the current manifest and m2.
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
        Args:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   549
          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
   550
          clean: if true, include files unchanged between these manifests
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   551
                 with a None value in the returned dictionary.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   552
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   553
        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
   554
        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
   555
        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
   556
        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
   557
        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
   558
        string.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   559
        '''
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   560
        result = {}
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   561
        emptytree = treemanifest()
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   562
        def _diff(t1, t2):
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   563
            for d, m1 in t1._dirs.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   564
                m2 = t2._dirs.get(d, emptytree)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   565
                _diff(m1, m2)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   566
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   567
            for d, m2 in t2._dirs.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   568
                if d not in t1._dirs:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   569
                    _diff(emptytree, m2)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   570
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   571
            for fn, n1 in t1._files.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   572
                fl1 = t1._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   573
                n2 = t2._files.get(fn, None)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   574
                fl2 = t2._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   575
                if n1 != n2 or fl1 != fl2:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   576
                    result[t1._subpath(fn)] = ((n1, fl1), (n2, fl2))
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   577
                elif clean:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   578
                    result[t1._subpath(fn)] = None
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   579
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   580
            for fn, n2 in t2._files.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   581
                if fn not in t1._files:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   582
                    fl2 = t2._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   583
                    result[t2._subpath(fn)] = ((None, ''), (n2, fl2))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   584
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   585
        _diff(self, m2)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   586
        return result
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   587
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   588
    def text(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   589
        """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
   590
        flags = self.flags
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
   591
        return _text((f, self[f], flags(f)) for f in self.keys())
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   592
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   593
class manifest(revlog.revlog):
4258
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 4257
diff changeset
   594
    def __init__(self, opener):
24033
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
   595
        # 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
   596
        # 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
   597
        # 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
   598
        cachesize = 4
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   599
        usetreemanifest = False
24033
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
   600
        opts = getattr(opener, 'options', None)
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
   601
        if opts is not None:
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
   602
            cachesize = opts.get('manifestcachesize', cachesize)
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   603
            usetreemanifest = opts.get('usetreemanifest', usetreemanifest)
24033
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
   604
        self._mancache = util.lrucachedict(cachesize)
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   605
        revlog.revlog.__init__(self, opener, "00manifest.i")
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   606
        self._usetreemanifest = usetreemanifest
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   607
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   608
    def _newmanifest(self, data=''):
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   609
        if self._usetreemanifest:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   610
            return treemanifest('', data)
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   611
        return manifestdict(data)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   612
3196
f3b939444c72 Abstract manifest block parsing.
Brendan Cully <brendan@kublai.com>
parents: 3148
diff changeset
   613
    def readdelta(self, node):
7362
6db4a2ccef3a revlog: remove delta function
Matt Mackall <mpm@selenic.com>
parents: 6765
diff changeset
   614
        r = self.rev(node)
24224
d71837d06597 manifest: do parsing inside manifestdict contstructor
Augie Fackler <augie@google.com>
parents: 24223
diff changeset
   615
        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
   616
        return self._newmanifest(d)
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3196
diff changeset
   617
13711
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   618
    def readfast(self, node):
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   619
        '''use the faster of readdelta or read'''
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   620
        r = self.rev(node)
14208
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 13711
diff changeset
   621
        deltaparent = self.deltaparent(r)
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 13711
diff changeset
   622
        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
   623
            return self.readdelta(node)
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   624
        return self.read(node)
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   625
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   626
    def read(self, node):
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   627
        if node == revlog.nullid:
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   628
            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
   629
        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
   630
            return self._mancache[node][0]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   631
        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
   632
        arraytext = array.array('c', text)
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   633
        m = self._newmanifest(text)
24147
ba4fcd80079d manifest: rename 'mf', 'map', and 'mapping' to 'm'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24146
diff changeset
   634
        self._mancache[node] = (m, arraytext)
ba4fcd80079d manifest: rename 'mf', 'map', and 'mapping' to 'm'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24146
diff changeset
   635
        return m
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   636
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   637
    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
   638
        '''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
   639
        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
   640
        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
   641
        try:
24292
b7add2ebef9e manifest: rewrite find(node, f) in terms of read(node)
Martin von Zweigbergk <martinvonz@google.com>
parents: 24277
diff changeset
   642
            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
   643
        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
   644
            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
   645
24147
ba4fcd80079d manifest: rename 'mf', 'map', and 'mapping' to 'm'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24146
diff changeset
   646
    def add(self, m, transaction, link, p1, p2, added, removed):
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
   647
        if p1 in self._mancache and not self._usetreemanifest:
22788
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   648
            # 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
   649
            # 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
   650
            # 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
   651
            # revlog layer.
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   652
22415
65ec6c5c0fb3 manifest: mark addlistdelta and checkforbidden as module-private
Augie Fackler <raf@durin42.com>
parents: 22409
diff changeset
   653
            _checkforbidden(added)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   654
            # 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
   655
            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
   656
            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
   657
            # 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
   658
            # since the lists are already sorted
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   659
            work.sort()
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   660
24147
ba4fcd80079d manifest: rename 'mf', 'map', and 'mapping' to 'm'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24146
diff changeset
   661
            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
   662
            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
   663
            text = util.buffer(arraytext)
22788
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   664
        else:
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   665
            # 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
   666
            # 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
   667
            # 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
   668
            # process.
24147
ba4fcd80079d manifest: rename 'mf', 'map', and 'mapping' to 'm'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24146
diff changeset
   669
            text = m.text()
22788
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   670
            arraytext = array.array('c', text)
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   671
            cachedelta = None
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   672
9420
d0db168136dc manifest/revlog: do not let the revlog cache mutable objects
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9416
diff changeset
   673
        n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
24147
ba4fcd80079d manifest: rename 'mf', 'map', and 'mapping' to 'm'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24146
diff changeset
   674
        self._mancache[n] = (m, arraytext)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   675
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   676
        return n