mercurial/manifest.py
author Durham Goode <durham@fb.com>
Tue, 13 Sep 2016 16:00:41 -0700
changeset 29940 fa145a205a7f
parent 29939 80be4436e4cc
child 29941 1cc93a154723
permissions -rw-r--r--
manifest: move revlog specific options from manifest to manifestrevlog The manifestv2 and treeondisk options are specific to how we serialize the manifest into revlogs, so let's move them onto the manifestrevlog class. This will allow us to add a manifestlog.add() function in a future diff that will rely on manifestrevlog to make decisions about how to serialize the given manifest to disk. We have to move a little bit of extra logic about the 'dir' as well, since it is used in conjunction with the treeondisk option to decide the revlog file name. It's probably good to move this down to the manifestrevlog class anyway, since it's specific to the revlog.
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
27502
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
     8
from __future__ import absolute_import
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
     9
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    10
import array
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    11
import heapq
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    12
import os
27502
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    13
import struct
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    14
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    15
from .i18n import _
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    16
from . import (
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    17
    error,
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    18
    mdiff,
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    19
    parsers,
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    20
    revlog,
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    21
    util,
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    22
)
79
837d473d54d5 Add basic annotation support
mpm@selenic.com
parents: 78
diff changeset
    23
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
    24
propertycache = util.propertycache
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    25
24572
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    26
def _parsev1(data):
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    27
    # 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
    28
    # 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
    29
    # 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
    30
    # 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
    31
    # the pure version.
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    32
    if data and data[-1] != '\n':
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    33
        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
    34
    prev = None
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    35
    for l in data.splitlines():
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    36
        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
    37
            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
    38
        prev = l
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    39
        f, n = l.split('\0')
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    40
        if len(n) > 40:
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    41
            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
    42
        else:
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    43
            yield f, revlog.bin(n), ''
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    44
24572
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    45
def _parsev2(data):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    46
    metadataend = data.find('\n')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    47
    # Just ignore metadata for now
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    48
    pos = metadataend + 1
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    49
    prevf = ''
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    50
    while pos < len(data):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    51
        end = data.find('\n', pos + 1) # +1 to skip stem length byte
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    52
        if end == -1:
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    53
            raise ValueError('Manifest ended with incomplete file entry.')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    54
        stemlen = ord(data[pos])
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    55
        items = data[pos + 1:end].split('\0')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    56
        f = prevf[:stemlen] + items[0]
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    57
        if prevf > f:
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    58
            raise ValueError('Manifest entries not in sorted order.')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    59
        fl = items[1]
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    60
        # Just ignore metadata (items[2:] for now)
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    61
        n = data[end + 1:end + 21]
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    62
        yield f, n, fl
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    63
        pos = end + 22
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    64
        prevf = f
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    65
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    66
def _parse(data):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    67
    """Generates (path, node, flags) tuples from a manifest text"""
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    68
    if data.startswith('\0'):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    69
        return iter(_parsev2(data))
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    70
    else:
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    71
        return iter(_parsev1(data))
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    72
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    73
def _text(it, usemanifestv2):
24525
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    74
    """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
    75
    text"""
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    76
    if usemanifestv2:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    77
        return _textv2(it)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    78
    else:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    79
        return _textv1(it)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    80
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    81
def _textv1(it):
24525
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    82
    files = []
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    83
    lines = []
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    84
    _hex = revlog.hex
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    85
    for f, n, fl in it:
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    86
        files.append(f)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    87
        # 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
    88
        # 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
    89
        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
    90
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    91
    _checkforbidden(files)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    92
    return ''.join(lines)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    93
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    94
def _textv2(it):
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    95
    files = []
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    96
    lines = ['\0\n']
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    97
    prevf = ''
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    98
    for f, n, fl in it:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    99
        files.append(f)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   100
        stem = os.path.commonprefix([prevf, f])
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   101
        stemlen = min(len(stem), 255)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   102
        lines.append("%c%s\0%s\n%s\n" % (stemlen, f[stemlen:], fl, n))
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   103
        prevf = f
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   104
    _checkforbidden(files)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   105
    return ''.join(lines)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   106
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   107
class _lazymanifest(dict):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   108
    """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
   109
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   110
    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
   111
    """
24223
b4df0d0c49e7 manifest: move parsing functions up in file
Augie Fackler <augie@google.com>
parents: 24215
diff changeset
   112
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   113
    def __init__(self, data):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   114
        dict.__init__(self)
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
   115
        for f, n, fl in _parse(data):
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
   116
            self[f] = n, fl
24224
d71837d06597 manifest: do parsing inside manifestdict contstructor
Augie Fackler <augie@google.com>
parents: 24223
diff changeset
   117
23594
6f53629ad273 manifest: disallow setting the node id of an entry to None
Augie Fackler <augie@google.com>
parents: 22966
diff changeset
   118
    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
   119
        node, flag = v
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   120
        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
   121
        if len(node) > 21:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   122
            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
   123
        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
   124
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   125
    def __iter__(self):
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   126
        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
   127
24297
0178f500d61e lazymanifest: fix pure hg iterkeys()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   128
    def iterkeys(self):
0178f500d61e lazymanifest: fix pure hg iterkeys()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   129
        return iter(sorted(dict.keys(self)))
0178f500d61e lazymanifest: fix pure hg iterkeys()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   130
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   131
    def iterentries(self):
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   132
        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
   133
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
   134
    def copy(self):
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   135
        c = _lazymanifest('')
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   136
        c.update(self)
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   137
        return c
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   138
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   139
    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
   140
        '''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
   141
        diff = {}
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   142
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   143
        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
   144
            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
   145
                diff[fn] = e1, (None, '')
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   146
            else:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   147
                e2 = m2[fn]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   148
                if e1 != e2:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   149
                    diff[fn] = e1, e2
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   150
                elif clean:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   151
                    diff[fn] = None
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   152
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   153
        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
   154
            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
   155
                diff[fn] = (None, ''), e2
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   156
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   157
        return diff
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   158
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   159
    def filtercopy(self, filterfn):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   160
        c = _lazymanifest('')
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   161
        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
   162
            if filterfn(f):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   163
                c[f] = n, fl
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   164
        return c
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   165
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   166
    def text(self):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   167
        """Get the full data of this manifest as a bytestring."""
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   168
        return _textv1(self.iterentries())
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   169
24226
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   170
try:
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   171
    _lazymanifest = parsers.lazymanifest
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   172
except AttributeError:
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   173
    pass
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   174
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   175
class manifestdict(object):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   176
    def __init__(self, data=''):
24572
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   177
        if data.startswith('\0'):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   178
            #_lazymanifest can not parse v2
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   179
            self._lm = _lazymanifest('')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   180
            for f, n, fl in _parsev2(data):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   181
                self._lm[f] = n, fl
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   182
        else:
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   183
            self._lm = _lazymanifest(data)
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   184
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   185
    def __getitem__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   186
        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
   187
24277
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   188
    def find(self, key):
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   189
        return self._lm[key]
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   190
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   191
    def __len__(self):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   192
        return len(self._lm)
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   193
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   194
    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
   195
        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
   196
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   197
    def __contains__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   198
        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
   199
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   200
    def __delitem__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   201
        del self._lm[key]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   202
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   203
    def __iter__(self):
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   204
        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
   205
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   206
    def iterkeys(self):
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   207
        return self._lm.iterkeys()
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   208
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   209
    def keys(self):
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   210
        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
   211
24184
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   212
    def filesnotin(self, m2):
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   213
        '''Set of files in this manifest that are not in the other'''
29056
e2178f7d17c0 manifest: improve filesnotin performance by using lazymanifest diff
Tony Tung <tonytung@merly.org>
parents: 28240
diff changeset
   214
        diff = self.diff(m2)
e2178f7d17c0 manifest: improve filesnotin performance by using lazymanifest diff
Tony Tung <tonytung@merly.org>
parents: 28240
diff changeset
   215
        files = set(filepath
e2178f7d17c0 manifest: improve filesnotin performance by using lazymanifest diff
Tony Tung <tonytung@merly.org>
parents: 28240
diff changeset
   216
                    for filepath, hashflags in diff.iteritems()
e2178f7d17c0 manifest: improve filesnotin performance by using lazymanifest diff
Tony Tung <tonytung@merly.org>
parents: 28240
diff changeset
   217
                    if hashflags[1][0] is None)
24184
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   218
        return files
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   219
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   220
    @propertycache
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   221
    def _dirs(self):
24635
21e1ece30f8c util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents: 24600
diff changeset
   222
        return util.dirs(self)
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   223
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   224
    def dirs(self):
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   225
        return self._dirs
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   226
24324
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   227
    def hasdir(self, dir):
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   228
        return dir in self._dirs
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   229
24685
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   230
    def _filesfastpath(self, match):
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   231
        '''Checks whether we can correctly and quickly iterate over matcher
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   232
        files instead of over manifest files.'''
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   233
        files = match.files()
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   234
        return (len(files) < 100 and (match.isexact() or
25276
c436ba9d6ac0 manifest: use match.prefix() instead of 'not match.anypats()'
Martin von Zweigbergk <martinvonz@google.com>
parents: 25222
diff changeset
   235
            (match.prefix() and all(fn in self for fn in files))))
24685
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   236
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   237
    def walk(self, match):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   238
        '''Generates matching file names.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   239
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   240
        Equivalent to manifest.matches(match).iterkeys(), but without creating
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   241
        an entirely new manifest.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   242
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   243
        It also reports nonexistent files by marking them bad with match.bad().
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   244
        '''
24683
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   245
        if match.always():
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   246
            for f in iter(self):
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   247
                yield f
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   248
            return
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   249
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   250
        fset = set(match.files())
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   251
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   252
        # avoid the entire walk if we're only looking for specific files
24685
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   253
        if self._filesfastpath(match):
24667
19c5b0913960 manifest.walk: join nested if-conditions
Martin von Zweigbergk <martinvonz@google.com>
parents: 24666
diff changeset
   254
            for fn in sorted(fset):
19c5b0913960 manifest.walk: join nested if-conditions
Martin von Zweigbergk <martinvonz@google.com>
parents: 24666
diff changeset
   255
                yield fn
24682
aef3d1469773 manifest.walk: use return instead of StopIteration in generator
Martin von Zweigbergk <martinvonz@google.com>
parents: 24670
diff changeset
   256
            return
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   257
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   258
        for fn in self:
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   259
            if fn in fset:
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   260
                # specified pattern is the exact name
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   261
                fset.remove(fn)
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   262
            if match(fn):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   263
                yield fn
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   264
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   265
        # for dirstate.walk, files=['.'] means "walk the whole tree".
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   266
        # follow that here, too
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   267
        fset.discard('.')
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   268
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   269
        for fn in sorted(fset):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   270
            if not self.hasdir(fn):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   271
                match.bad(fn, None)
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   272
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   273
    def matches(self, match):
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   274
        '''generate a new manifest filtered by the match argument'''
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   275
        if match.always():
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   276
            return self.copy()
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   277
24685
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   278
        if self._filesfastpath(match):
24666
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   279
            m = manifestdict()
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   280
            lm = self._lm
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   281
            for fn in match.files():
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   282
                if fn in lm:
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   283
                    m._lm[fn] = lm[fn]
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   284
            return m
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   285
24700
32b268cbff00 manifestdict: drop empty-string argument when creating empty manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24685
diff changeset
   286
        m = manifestdict()
24664
ea4a7c8909ae manifestdict.matches: avoid name 'lm' for a not-lazymanifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24647
diff changeset
   287
        m._lm = self._lm.filtercopy(match)
ea4a7c8909ae manifestdict.matches: avoid name 'lm' for a not-lazymanifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24647
diff changeset
   288
        return m
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   289
23756
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   290
    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
   291
        '''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
   292
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   293
        Args:
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   294
          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
   295
          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
   296
                 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
   297
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   298
        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
   299
        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
   300
        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
   301
        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
   302
        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
   303
        string.
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   304
        '''
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   305
        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
   306
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   307
    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
   308
        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
   309
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   310
    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
   311
        try:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   312
            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
   313
        except KeyError:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   314
            return default
22965
b697fa74b475 manifest: for diff(), only iterate over files, not flags
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22964
diff changeset
   315
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   316
    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
   317
        try:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   318
            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
   319
        except KeyError:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   320
            return default
22965
b697fa74b475 manifest: for diff(), only iterate over files, not flags
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22964
diff changeset
   321
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   322
    def copy(self):
24700
32b268cbff00 manifestdict: drop empty-string argument when creating empty manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24685
diff changeset
   323
        c = manifestdict()
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   324
        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
   325
        return c
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   326
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   327
    def iteritems(self):
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   328
        return (x[:2] for x in self._lm.iterentries())
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
   329
28203
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
   330
    def iterentries(self):
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
   331
        return self._lm.iterentries()
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
   332
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   333
    def text(self, usemanifestv2=False):
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   334
        if usemanifestv2:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   335
            return _textv2(self._lm.iterentries())
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   336
        else:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   337
            # use (probably) native version for v1
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   338
            return self._lm.text()
22408
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   339
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   340
    def fastdelta(self, base, changes):
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   341
        """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
   342
        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
   343
        """
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   344
        delta = []
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   345
        dstart = None
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   346
        dend = None
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   347
        dline = [""]
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   348
        start = 0
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   349
        # zero copy representation of base as a buffer
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   350
        addbuf = util.buffer(base)
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   351
26871
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   352
        changes = list(changes)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   353
        if len(changes) < 1000:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   354
            # start with a readonly loop that finds the offset of
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   355
            # each line and creates the deltas
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   356
            for f, todelete in changes:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   357
                # bs will either be the index of the item or the insert point
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   358
                start, end = _msearch(addbuf, f, start)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   359
                if not todelete:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   360
                    h, fl = self._lm[f]
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   361
                    l = "%s\0%s%s\n" % (f, revlog.hex(h), fl)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   362
                else:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   363
                    if start == end:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   364
                        # item we want to delete was not found, error out
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   365
                        raise AssertionError(
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   366
                                _("failed to remove %s from manifest") % f)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   367
                    l = ""
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   368
                if dstart is not None and dstart <= start and dend >= start:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   369
                    if dend < end:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   370
                        dend = end
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   371
                    if l:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   372
                        dline.append(l)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   373
                else:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   374
                    if dstart is not None:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   375
                        delta.append([dstart, dend, "".join(dline)])
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   376
                    dstart = start
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   377
                    dend = end
26871
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   378
                    dline = [l]
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   379
26871
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   380
            if dstart is not None:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   381
                delta.append([dstart, dend, "".join(dline)])
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   382
            # apply the delta to the base, and get a delta for addrevision
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   383
            deltatext, arraytext = _addlistdelta(base, delta)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   384
        else:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   385
            # For large changes, it's much cheaper to just build the text and
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   386
            # diff it.
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   387
            arraytext = array.array('c', self.text())
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   388
            deltatext = mdiff.textdiff(base, arraytext)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   389
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   390
        return arraytext, deltatext
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   391
22930
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   392
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
   393
    '''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
   394
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   395
    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
   396
    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
   397
    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
   398
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   399
    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
   400
    s is a string'''
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   401
    def advance(i, c):
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   402
        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
   403
            i += 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   404
        return i
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   405
    if not s:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   406
        return (lo, lo)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   407
    lenm = len(m)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   408
    if not hi:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   409
        hi = lenm
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   410
    while lo < hi:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   411
        mid = (lo + hi) // 2
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   412
        start = mid
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   413
        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
   414
            start -= 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   415
        end = advance(start, '\0')
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   416
        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
   417
            # 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
   418
            # 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
   419
            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
   420
        else:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   421
            # 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
   422
            hi = start
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   423
    end = advance(lo, '\0')
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   424
    found = m[lo:end]
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   425
    if s == found:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   426
        # 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
   427
        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
   428
        return (lo, end + 1)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   429
    else:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   430
        return (lo, lo)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   431
22415
65ec6c5c0fb3 manifest: mark addlistdelta and checkforbidden as module-private
Augie Fackler <raf@durin42.com>
parents: 22409
diff changeset
   432
def _checkforbidden(l):
22408
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   433
    """Check filenames for illegal characters."""
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   434
    for f in l:
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   435
        if '\n' in f or '\r' in f:
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   436
            raise error.RevlogError(
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   437
                _("'\\n' and '\\r' disallowed in filenames: %r") % f)
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   438
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   439
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   440
# 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
   441
# 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
   442
def _addlistdelta(addlist, x):
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   443
    # 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
   444
    # than repeatedly modifying the existing one
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   445
    currentposition = 0
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   446
    newaddlist = array.array('c')
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   447
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   448
    for start, end, content in x:
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   449
        newaddlist += addlist[currentposition:start]
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   450
        if content:
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   451
            newaddlist += array.array('c', content)
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   452
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   453
        currentposition = end
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   454
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   455
    newaddlist += addlist[currentposition:]
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   456
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   457
    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
   458
                   + content for start, end, content in x)
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   459
    return deltatext, newaddlist
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   460
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   461
def _splittopdir(f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   462
    if '/' in f:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   463
        dir, subpath = f.split('/', 1)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   464
        return dir + '/', subpath
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   465
    else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   466
        return '', f
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   467
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   468
_noop = lambda s: None
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   469
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   470
class treemanifest(object):
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   471
    def __init__(self, dir='', text=''):
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   472
        self._dir = dir
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   473
        self._node = revlog.nullid
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   474
        self._loadfunc = _noop
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   475
        self._copyfunc = _noop
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   476
        self._dirty = False
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   477
        self._dirs = {}
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   478
        # 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
   479
        self._files = {}
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   480
        self._flags = {}
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   481
        if text:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   482
            def readsubtree(subdir, subm):
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   483
                raise AssertionError('treemanifest constructor only accepts '
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   484
                                     'flat manifests')
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   485
            self.parse(text, readsubtree)
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   486
            self._dirty = True # Mark flat manifest dirty after parsing
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   487
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   488
    def _subpath(self, path):
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   489
        return self._dir + path
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   490
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   491
    def __len__(self):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   492
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   493
        size = len(self._files)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   494
        for m in self._dirs.values():
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   495
            size += m.__len__()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   496
        return size
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   497
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   498
    def _isempty(self):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   499
        self._load() # for consistency; already loaded by all callers
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   500
        return (not self._files and (not self._dirs or
25151
6eb4bdad198f cleanup: use __builtins__.all instead of util.all
Augie Fackler <augie@google.com>
parents: 25119
diff changeset
   501
                all(m._isempty() for m in self._dirs.values())))
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   502
26400
6f9d9e2a661f manifest: add id(self) to treemanifest __repr__
Augie Fackler <augie@google.com>
parents: 26199
diff changeset
   503
    def __repr__(self):
6f9d9e2a661f manifest: add id(self) to treemanifest __repr__
Augie Fackler <augie@google.com>
parents: 26199
diff changeset
   504
        return ('<treemanifest dir=%s, node=%s, loaded=%s, dirty=%s at 0x%x>' %
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   505
                (self._dir, revlog.hex(self._node),
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   506
                 bool(self._loadfunc is _noop),
26400
6f9d9e2a661f manifest: add id(self) to treemanifest __repr__
Augie Fackler <augie@google.com>
parents: 26199
diff changeset
   507
                 self._dirty, id(self)))
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   508
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   509
    def dir(self):
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   510
        '''The directory that this tree manifest represents, including a
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   511
        trailing '/'. Empty string for the repo root directory.'''
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   512
        return self._dir
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   513
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   514
    def node(self):
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   515
        '''This node of this instance. nullid for unsaved instances. Should
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   516
        be updated when the instance is read or written from a revlog.
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   517
        '''
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   518
        assert not self._dirty
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   519
        return self._node
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   520
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   521
    def setnode(self, node):
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   522
        self._node = node
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   523
        self._dirty = False
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   524
28206
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   525
    def iterentries(self):
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   526
        self._load()
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   527
        for p, n in sorted(self._dirs.items() + self._files.items()):
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   528
            if p in self._files:
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   529
                yield self._subpath(p), n, self._flags.get(p, '')
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   530
            else:
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   531
                for x in n.iterentries():
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   532
                    yield x
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   533
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   534
    def iteritems(self):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   535
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   536
        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
   537
            if p in self._files:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   538
                yield self._subpath(p), n
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   539
            else:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   540
                for f, sn in n.iteritems():
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   541
                    yield f, sn
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   542
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   543
    def iterkeys(self):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   544
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   545
        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
   546
            if p in self._files:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   547
                yield self._subpath(p)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   548
            else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   549
                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
   550
                    yield f
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   551
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   552
    def keys(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   553
        return list(self.iterkeys())
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   554
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   555
    def __iter__(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   556
        return self.iterkeys()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   557
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   558
    def __contains__(self, f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   559
        if f is None:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   560
            return False
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   561
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   562
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   563
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   564
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   565
                return False
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   566
            return self._dirs[dir].__contains__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   567
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   568
            return f in self._files
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   569
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   570
    def get(self, f, default=None):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   571
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   572
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   573
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   574
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   575
                return default
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   576
            return self._dirs[dir].get(subpath, default)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   577
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   578
            return self._files.get(f, default)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   579
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   580
    def __getitem__(self, f):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   581
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   582
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   583
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   584
            return self._dirs[dir].__getitem__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   585
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   586
            return self._files[f]
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 flags(self, f):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   589
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   590
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   591
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   592
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   593
                return ''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   594
            return self._dirs[dir].flags(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   595
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   596
            if f in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   597
                return ''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   598
            return self._flags.get(f, '')
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   599
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   600
    def find(self, f):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   601
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   602
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   603
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   604
            return self._dirs[dir].find(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   605
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   606
            return self._files[f], self._flags.get(f, '')
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   607
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   608
    def __delitem__(self, f):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   609
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   610
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   611
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   612
            self._dirs[dir].__delitem__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   613
            # If the directory is now empty, remove it
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   614
            if self._dirs[dir]._isempty():
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   615
                del self._dirs[dir]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   616
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   617
            del self._files[f]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   618
            if f in self._flags:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   619
                del self._flags[f]
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   620
        self._dirty = True
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   621
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   622
    def __setitem__(self, f, n):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   623
        assert n is not None
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   624
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   625
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   626
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   627
            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
   628
                self._dirs[dir] = treemanifest(self._subpath(dir))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   629
            self._dirs[dir].__setitem__(subpath, n)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   630
        else:
24467
bfb754050ccd treemanifest: drop 22nd byte for consistency with manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24448
diff changeset
   631
            self._files[f] = n[:21] # to match manifestdict's behavior
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   632
        self._dirty = True
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   633
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   634
    def _load(self):
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   635
        if self._loadfunc is not _noop:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   636
            lf, self._loadfunc = self._loadfunc, _noop
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   637
            lf(self)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   638
        elif self._copyfunc is not _noop:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   639
            cf, self._copyfunc = self._copyfunc, _noop
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   640
            cf(self)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   641
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   642
    def setflag(self, f, flags):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   643
        """Set the flags (symlink, executable) for path f."""
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   644
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   645
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   646
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   647
            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
   648
                self._dirs[dir] = treemanifest(self._subpath(dir))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   649
            self._dirs[dir].setflag(subpath, flags)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   650
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   651
            self._flags[f] = flags
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   652
        self._dirty = True
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   653
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   654
    def copy(self):
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   655
        copy = treemanifest(self._dir)
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   656
        copy._node = self._node
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   657
        copy._dirty = self._dirty
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   658
        if self._copyfunc is _noop:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   659
            def _copyfunc(s):
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   660
                self._load()
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   661
                for d in self._dirs:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   662
                    s._dirs[d] = self._dirs[d].copy()
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   663
                s._files = dict.copy(self._files)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   664
                s._flags = dict.copy(self._flags)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   665
            if self._loadfunc is _noop:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   666
                _copyfunc(copy)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   667
            else:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   668
                copy._copyfunc = _copyfunc
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   669
        else:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   670
            copy._copyfunc = self._copyfunc
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   671
        return copy
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   672
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   673
    def filesnotin(self, m2):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   674
        '''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
   675
        files = set()
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   676
        def _filesnotin(t1, t2):
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   677
            if t1._node == t2._node and not t1._dirty and not t2._dirty:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   678
                return
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   679
            t1._load()
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   680
            t2._load()
24405
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   681
            for d, m1 in t1._dirs.iteritems():
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   682
                if d in t2._dirs:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   683
                    m2 = t2._dirs[d]
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   684
                    _filesnotin(m1, m2)
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   685
                else:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   686
                    files.update(m1.iterkeys())
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   687
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   688
            for fn in t1._files.iterkeys():
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   689
                if fn not in t2._files:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   690
                    files.add(t1._subpath(fn))
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   691
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   692
        _filesnotin(self, m2)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   693
        return files
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   694
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   695
    @propertycache
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   696
    def _alldirs(self):
24635
21e1ece30f8c util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents: 24600
diff changeset
   697
        return util.dirs(self)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   698
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   699
    def dirs(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   700
        return self._alldirs
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   701
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   702
    def hasdir(self, dir):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   703
        self._load()
24406
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   704
        topdir, subdir = _splittopdir(dir)
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   705
        if topdir:
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   706
            if topdir in self._dirs:
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   707
                return self._dirs[topdir].hasdir(subdir)
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   708
            return False
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   709
        return (dir + '/') in self._dirs
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   710
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   711
    def walk(self, match):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   712
        '''Generates matching file names.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   713
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   714
        Equivalent to manifest.matches(match).iterkeys(), but without creating
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   715
        an entirely new manifest.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   716
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   717
        It also reports nonexistent files by marking them bad with match.bad().
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   718
        '''
24683
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   719
        if match.always():
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   720
            for f in iter(self):
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   721
                yield f
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   722
            return
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   723
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   724
        fset = set(match.files())
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   725
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   726
        for fn in self._walk(match):
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   727
            if fn in fset:
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   728
                # specified pattern is the exact name
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   729
                fset.remove(fn)
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   730
            yield fn
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   731
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   732
        # for dirstate.walk, files=['.'] means "walk the whole tree".
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   733
        # follow that here, too
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   734
        fset.discard('.')
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   735
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   736
        for fn in sorted(fset):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   737
            if not self.hasdir(fn):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   738
                match.bad(fn, None)
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   739
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   740
    def _walk(self, match):
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   741
        '''Recursively generates matching file names for walk().'''
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   742
        if not match.visitdir(self._dir[:-1] or '.'):
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   743
            return
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   744
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   745
        # yield this dir's files and walk its submanifests
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   746
        self._load()
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   747
        for p in sorted(self._dirs.keys() + self._files.keys()):
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   748
            if p in self._files:
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   749
                fullp = self._subpath(p)
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   750
                if match(fullp):
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   751
                    yield fullp
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   752
            else:
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   753
                for f in self._dirs[p]._walk(match):
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   754
                    yield f
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   755
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   756
    def matches(self, match):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   757
        '''generate a new manifest filtered by the match argument'''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   758
        if match.always():
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   759
            return self.copy()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   760
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   761
        return self._matches(match)
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   762
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   763
    def _matches(self, match):
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   764
        '''recursively generate a new manifest filtered by the match argument.
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   765
        '''
27343
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27271
diff changeset
   766
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27271
diff changeset
   767
        visit = match.visitdir(self._dir[:-1] or '.')
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27271
diff changeset
   768
        if visit == 'all':
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27271
diff changeset
   769
            return self.copy()
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   770
        ret = treemanifest(self._dir)
27343
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27271
diff changeset
   771
        if not visit:
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   772
            return ret
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   773
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   774
        self._load()
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   775
        for fn in self._files:
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   776
            fullp = self._subpath(fn)
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   777
            if not match(fullp):
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   778
                continue
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   779
            ret._files[fn] = self._files[fn]
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   780
            if fn in self._flags:
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   781
                ret._flags[fn] = self._flags[fn]
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   782
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   783
        for dir, subm in self._dirs.iteritems():
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   784
            m = subm._matches(match)
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   785
            if not m._isempty():
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   786
                ret._dirs[dir] = m
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   787
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   788
        if not ret._isempty():
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   789
            ret._dirty = True
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   790
        return ret
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   791
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   792
    def diff(self, m2, clean=False):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   793
        '''Finds changes between the current manifest and m2.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   794
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   795
        Args:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   796
          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
   797
          clean: if true, include files unchanged between these manifests
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   798
                 with a None value in the returned dictionary.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   799
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   800
        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
   801
        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
   802
        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
   803
        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
   804
        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
   805
        string.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   806
        '''
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   807
        result = {}
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   808
        emptytree = treemanifest()
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   809
        def _diff(t1, t2):
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   810
            if t1._node == t2._node and not t1._dirty and not t2._dirty:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   811
                return
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   812
            t1._load()
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   813
            t2._load()
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   814
            for d, m1 in t1._dirs.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   815
                m2 = t2._dirs.get(d, emptytree)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   816
                _diff(m1, m2)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   817
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   818
            for d, m2 in t2._dirs.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   819
                if d not in t1._dirs:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   820
                    _diff(emptytree, m2)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   821
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   822
            for fn, n1 in t1._files.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   823
                fl1 = t1._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   824
                n2 = t2._files.get(fn, None)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   825
                fl2 = t2._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   826
                if n1 != n2 or fl1 != fl2:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   827
                    result[t1._subpath(fn)] = ((n1, fl1), (n2, fl2))
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   828
                elif clean:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   829
                    result[t1._subpath(fn)] = None
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   830
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   831
            for fn, n2 in t2._files.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   832
                if fn not in t1._files:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   833
                    fl2 = t2._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   834
                    result[t2._subpath(fn)] = ((None, ''), (n2, fl2))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   835
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   836
        _diff(self, m2)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
   837
        return result
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   838
25221
eafa06e9edde treemanifest: speed up commit using dirty flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 25220
diff changeset
   839
    def unmodifiedsince(self, m2):
eafa06e9edde treemanifest: speed up commit using dirty flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 25220
diff changeset
   840
        return not self._dirty and not m2._dirty and self._node == m2._node
eafa06e9edde treemanifest: speed up commit using dirty flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 25220
diff changeset
   841
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   842
    def parse(self, text, readsubtree):
24781
055b3cbe6c57 treemanifest: extract parse method from constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 24780
diff changeset
   843
        for f, n, fl in _parse(text):
27271
2a31433a59ba manifest: use 't' for tree manifest flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 26871
diff changeset
   844
            if fl == 't':
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   845
                f = f + '/'
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   846
                self._dirs[f] = readsubtree(self._subpath(f), n)
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   847
            elif '/' in f:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   848
                # This is a flat manifest, so use __setitem__ and setflag rather
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   849
                # than assigning directly to _files and _flags, so we can
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   850
                # assign a path in a subdirectory, and to mark dirty (compared
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   851
                # to nullid).
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   852
                self[f] = n
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   853
                if fl:
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   854
                    self.setflag(f, fl)
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   855
            else:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   856
                # Assigning to _files and _flags avoids marking as dirty,
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   857
                # and should be a little faster.
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   858
                self._files[f] = n
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   859
                if fl:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   860
                    self._flags[f] = fl
24781
055b3cbe6c57 treemanifest: extract parse method from constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 24780
diff changeset
   861
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   862
    def text(self, usemanifestv2=False):
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   863
        """Get the full data of this manifest as a bytestring."""
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   864
        self._load()
28207
43edd3003456 treemanifest: rewrite text() using iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28206
diff changeset
   865
        return _text(self.iterentries(), usemanifestv2)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   866
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   867
    def dirtext(self, usemanifestv2=False):
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   868
        """Get the full data of this directory as a bytestring. Make sure that
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   869
        any submanifests have been written first, so their nodeids are correct.
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   870
        """
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   871
        self._load()
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   872
        flags = self.flags
27271
2a31433a59ba manifest: use 't' for tree manifest flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 26871
diff changeset
   873
        dirs = [(d[:-1], self._dirs[d]._node, 't') for d in self._dirs]
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   874
        files = [(f, self._files[f], flags(f)) for f in self._files]
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   875
        return _text(sorted(dirs + files), usemanifestv2)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   876
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   877
    def read(self, gettext, readsubtree):
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   878
        def _load_for_read(s):
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   879
            s.parse(gettext(), readsubtree)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   880
            s._dirty = False
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   881
        self._loadfunc = _load_for_read
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   882
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   883
    def writesubtrees(self, m1, m2, writesubtree):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   884
        self._load() # for consistency; should never have any effect here
29888
8a84347b9907 manifest: call m1.load and m2.load before writing a subtree
Durham Goode <durham@fb.com>
parents: 29826
diff changeset
   885
        m1._load()
8a84347b9907 manifest: call m1.load and m2.load before writing a subtree
Durham Goode <durham@fb.com>
parents: 29826
diff changeset
   886
        m2._load()
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   887
        emptytree = treemanifest()
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   888
        for d, subm in self._dirs.iteritems():
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   889
            subp1 = m1._dirs.get(d, emptytree)._node
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   890
            subp2 = m2._dirs.get(d, emptytree)._node
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   891
            if subp1 == revlog.nullid:
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   892
                subp1, subp2 = subp2, subp1
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   893
            writesubtree(subm, subp1, subp2)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   894
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   895
class manifestrevlog(revlog.revlog):
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   896
    '''A revlog that stores manifest texts. This is responsible for caching the
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   897
    full-text manifest contents.
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   898
    '''
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   899
    def __init__(self, opener, dir=''):
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   900
        # During normal operations, we expect to deal with not more than four
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   901
        # revs at a time (such as during commit --amend). When rebasing large
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   902
        # stacks of commits, the number can go up, hence the config knob below.
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   903
        cachesize = 4
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   904
        usetreemanifest = False
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   905
        usemanifestv2 = False
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   906
        opts = getattr(opener, 'options', None)
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   907
        if opts is not None:
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   908
            cachesize = opts.get('manifestcachesize', cachesize)
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   909
            usetreemanifest = opts.get('treemanifest', usetreemanifest)
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   910
            usemanifestv2 = opts.get('manifestv2', usemanifestv2)
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   911
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   912
        self._treeondisk = usetreemanifest
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   913
        self._usemanifestv2 = usemanifestv2
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   914
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   915
        self._fulltextcache = util.lrucachedict(cachesize)
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   916
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   917
        indexfile = "00manifest.i"
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   918
        if dir:
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   919
            assert self._treeondisk, 'opts is %r' % opts
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   920
            if not dir.endswith('/'):
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   921
                dir = dir + '/'
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   922
            indexfile = "meta/" + dir + "00manifest.i"
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   923
        self._dir = dir
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   924
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   925
        super(manifestrevlog, self).__init__(opener, indexfile)
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
   926
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   927
    @property
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   928
    def fulltextcache(self):
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   929
        return self._fulltextcache
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   930
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   931
    def clearcaches(self):
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   932
        super(manifestrevlog, self).clearcaches()
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   933
        self._fulltextcache.clear()
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
   934
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   935
class manifestlog(object):
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   936
    """A collection class representing the collection of manifest snapshots
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   937
    referenced by commits in the repository.
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   938
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   939
    In this situation, 'manifest' refers to the abstract concept of a snapshot
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   940
    of the list of files in the given commit. Consumers of the output of this
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   941
    class do not care about the implementation details of the actual manifests
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   942
    they receive (i.e. tree or flat or lazily loaded, etc)."""
29826
93b44aa17691 manifest: use property instead of field for manifest revlog storage
Durham Goode <durham@fb.com>
parents: 29825
diff changeset
   943
    def __init__(self, opener, repo):
93b44aa17691 manifest: use property instead of field for manifest revlog storage
Durham Goode <durham@fb.com>
parents: 29825
diff changeset
   944
        self._repo = repo
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   945
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   946
        # We'll separate this into it's own cache once oldmanifest is no longer
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   947
        # used
29826
93b44aa17691 manifest: use property instead of field for manifest revlog storage
Durham Goode <durham@fb.com>
parents: 29825
diff changeset
   948
        self._mancache = repo.manifest._mancache
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   949
29826
93b44aa17691 manifest: use property instead of field for manifest revlog storage
Durham Goode <durham@fb.com>
parents: 29825
diff changeset
   950
    @property
93b44aa17691 manifest: use property instead of field for manifest revlog storage
Durham Goode <durham@fb.com>
parents: 29825
diff changeset
   951
    def _revlog(self):
93b44aa17691 manifest: use property instead of field for manifest revlog storage
Durham Goode <durham@fb.com>
parents: 29825
diff changeset
   952
        return self._repo.manifest
93b44aa17691 manifest: use property instead of field for manifest revlog storage
Durham Goode <durham@fb.com>
parents: 29825
diff changeset
   953
93b44aa17691 manifest: use property instead of field for manifest revlog storage
Durham Goode <durham@fb.com>
parents: 29825
diff changeset
   954
    @property
93b44aa17691 manifest: use property instead of field for manifest revlog storage
Durham Goode <durham@fb.com>
parents: 29825
diff changeset
   955
    def _oldmanifest(self):
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   956
        # _revlog is the same as _oldmanifest right now, but we eventually want
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   957
        # to delete _oldmanifest while still allowing manifestlog to access the
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   958
        # revlog specific apis.
29826
93b44aa17691 manifest: use property instead of field for manifest revlog storage
Durham Goode <durham@fb.com>
parents: 29825
diff changeset
   959
        return self._repo.manifest
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   960
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   961
    def __getitem__(self, node):
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   962
        """Retrieves the manifest instance for the given node. Throws a KeyError
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   963
        if not found.
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   964
        """
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   965
        if node in self._mancache:
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   966
            cachemf = self._mancache[node]
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   967
            # The old manifest may put non-ctx manifests in the cache, so skip
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   968
            # those since they don't implement the full api.
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   969
            if (isinstance(cachemf, manifestctx) or
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   970
                isinstance(cachemf, treemanifestctx)):
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   971
                return cachemf
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   972
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   973
        if self._oldmanifest._treeinmem:
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   974
            m = treemanifestctx(self._revlog, '', node)
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   975
        else:
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   976
            m = manifestctx(self._revlog, node)
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   977
        if node != revlog.nullid:
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   978
            self._mancache[node] = m
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   979
        return m
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   980
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
   981
class manifestctx(object):
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   982
    """A class representing a single revision of a manifest, including its
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   983
    contents, its parent revs, and its linkrev.
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   984
    """
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   985
    def __init__(self, revlog, node):
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   986
        self._revlog = revlog
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
   987
        self._data = None
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   988
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   989
        self._node = node
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   990
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   991
        # TODO: We eventually want p1, p2, and linkrev exposed on this class,
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   992
        # but let's add it later when something needs it and we can load it
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   993
        # lazily.
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   994
        #self.p1, self.p2 = revlog.parents(node)
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   995
        #rev = revlog.rev(node)
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
   996
        #self.linkrev = revlog.linkrev(rev)
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   997
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   998
    def node(self):
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
   999
        return self._node
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1000
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1001
    def read(self):
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1002
        if not self._data:
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1003
            if self._node == revlog.nullid:
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1004
                self._data = manifestdict()
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1005
            else:
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1006
                text = self._revlog.revision(self._node)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1007
                arraytext = array.array('c', text)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1008
                self._revlog._fulltextcache[self._node] = arraytext
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1009
                self._data = manifestdict(text)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1010
        return self._data
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1011
29939
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1012
    def readfast(self):
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1013
        rl = self._revlog
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1014
        r = rl.rev(self._node)
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1015
        deltaparent = rl.deltaparent(r)
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1016
        if deltaparent != revlog.nullrev and deltaparent in rl.parentrevs(r):
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1017
            return self.readdelta()
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1018
        return self.read()
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1019
29938
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1020
    def readdelta(self):
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1021
        revlog = self._revlog
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1022
        if revlog._usemanifestv2:
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1023
            # Need to perform a slow delta
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1024
            r0 = revlog.deltaparent(revlog.rev(self._node))
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1025
            m0 = manifestctx(revlog, revlog.node(r0)).read()
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1026
            m1 = self.read()
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1027
            md = manifestdict()
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1028
            for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1029
                if n1:
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1030
                    md[f] = n1
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1031
                    if fl1:
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1032
                        md.setflag(f, fl1)
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1033
            return md
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1034
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1035
        r = revlog.rev(self._node)
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1036
        d = mdiff.patchtext(revlog.revdiff(revlog.deltaparent(r), r))
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1037
        return manifestdict(d)
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1038
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1039
class treemanifestctx(object):
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1040
    def __init__(self, revlog, dir, node):
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1041
        revlog = revlog.dirlog(dir)
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1042
        self._revlog = revlog
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1043
        self._dir = dir
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1044
        self._data = None
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1045
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1046
        self._node = node
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1047
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1048
        # TODO: Load p1/p2/linkrev lazily. They need to be lazily loaded so that
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1049
        # we can instantiate treemanifestctx objects for directories we don't
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1050
        # have on disk.
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1051
        #self.p1, self.p2 = revlog.parents(node)
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1052
        #rev = revlog.rev(node)
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1053
        #self.linkrev = revlog.linkrev(rev)
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1054
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1055
    def read(self):
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1056
        if not self._data:
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1057
            if self._node == revlog.nullid:
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1058
                self._data = treemanifest()
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1059
            elif self._revlog._treeondisk:
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1060
                m = treemanifest(dir=self._dir)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1061
                def gettext():
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1062
                    return self._revlog.revision(self._node)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1063
                def readsubtree(dir, subm):
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1064
                    return treemanifestctx(self._revlog, dir, subm).read()
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1065
                m.read(gettext, readsubtree)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1066
                m.setnode(self._node)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1067
                self._data = m
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1068
            else:
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1069
                text = self._revlog.revision(self._node)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1070
                arraytext = array.array('c', text)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1071
                self._revlog.fulltextcache[self._node] = arraytext
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1072
                self._data = treemanifest(dir=self._dir, text=text)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1073
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1074
        return self._data
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1075
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1076
    def node(self):
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1077
        return self._node
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1078
29938
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1079
    def readdelta(self):
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1080
        # Need to perform a slow delta
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1081
        revlog = self._revlog
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1082
        r0 = revlog.deltaparent(revlog.rev(self._node))
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1083
        m0 = treemanifestctx(revlog, revlog.node(r0), dir=self._dir).read()
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1084
        m1 = self.read()
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1085
        md = treemanifest(dir=self._dir)
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1086
        for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1087
            if n1:
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1088
                md[f] = n1
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1089
                if fl1:
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1090
                    md.setflag(f, fl1)
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1091
        return md
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1092
29939
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1093
    def readfast(self):
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1094
        rl = self._revlog
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1095
        r = rl.rev(self._node)
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1096
        deltaparent = rl.deltaparent(r)
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1097
        if deltaparent != revlog.nullrev and deltaparent in rl.parentrevs(r):
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1098
            return self.readdelta()
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1099
        return self.read()
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1100
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1101
class manifest(manifestrevlog):
25185
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1102
    def __init__(self, opener, dir='', dirlogcache=None):
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1103
        '''The 'dir' and 'dirlogcache' arguments are for internal use by
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1104
        manifest.manifest only. External users should create a root manifest
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1105
        log with manifest.manifest(opener) and call dirlog() on it.
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1106
        '''
24033
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
  1107
        # 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
  1108
        # 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
  1109
        # 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
  1110
        cachesize = 4
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
  1111
        usetreemanifest = False
24033
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
  1112
        opts = getattr(opener, 'options', None)
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
  1113
        if opts is not None:
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
  1114
            cachesize = opts.get('manifestcachesize', cachesize)
24956
48583a1e44f3 treemanifest: set requires at repo creation time, ignore config after
Martin von Zweigbergk <martinvonz@google.com>
parents: 24925
diff changeset
  1115
            usetreemanifest = opts.get('treemanifest', usetreemanifest)
24033
ed5e8a9598ce manifest: make lru size configurable
Durham Goode <durham@fb.com>
parents: 23758
diff changeset
  1116
        self._mancache = util.lrucachedict(cachesize)
24701
03ee576784e6 treemanifest: separate flags for trees in memory and trees on disk
Martin von Zweigbergk <martinvonz@google.com>
parents: 24700
diff changeset
  1117
        self._treeinmem = usetreemanifest
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1118
        super(manifest, self).__init__(opener, dir=dir)
25185
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1119
        # The dirlogcache is kept on the root manifest log
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1120
        if dir:
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1121
            self._dirlogcache = dirlogcache
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1122
        else:
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1123
            self._dirlogcache = {'': self}
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
  1124
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
  1125
    def _newmanifest(self, data=''):
24701
03ee576784e6 treemanifest: separate flags for trees in memory and trees on disk
Martin von Zweigbergk <martinvonz@google.com>
parents: 24700
diff changeset
  1126
        if self._treeinmem:
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1127
            return treemanifest(self._dir, data)
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
  1128
        return manifestdict(data)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1129
25185
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1130
    def dirlog(self, dir):
28203
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1131
        if dir:
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1132
            assert self._treeondisk
25185
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1133
        if dir not in self._dirlogcache:
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1134
            self._dirlogcache[dir] = manifest(self.opener, dir,
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1135
                                              self._dirlogcache)
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1136
        return self._dirlogcache[dir]
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1137
24528
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
  1138
    def _slowreaddelta(self, node):
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
  1139
        r0 = self.deltaparent(self.rev(node))
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
  1140
        m0 = self.read(self.node(r0))
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
  1141
        m1 = self.read(node)
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
  1142
        md = self._newmanifest()
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
  1143
        for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
  1144
            if n1:
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
  1145
                md[f] = n1
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
  1146
                if fl1:
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
  1147
                    md.setflag(f, fl1)
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
  1148
        return md
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
  1149
3196
f3b939444c72 Abstract manifest block parsing.
Brendan Cully <brendan@kublai.com>
parents: 3148
diff changeset
  1150
    def readdelta(self, node):
24701
03ee576784e6 treemanifest: separate flags for trees in memory and trees on disk
Martin von Zweigbergk <martinvonz@google.com>
parents: 24700
diff changeset
  1151
        if self._usemanifestv2 or self._treeondisk:
24528
b538ae24aa97 manifestv2: implement slow readdelta() without revdiff
Martin von Zweigbergk <martinvonz@google.com>
parents: 24527
diff changeset
  1152
            return self._slowreaddelta(node)
7362
6db4a2ccef3a revlog: remove delta function
Matt Mackall <mpm@selenic.com>
parents: 6765
diff changeset
  1153
        r = self.rev(node)
24224
d71837d06597 manifest: do parsing inside manifestdict contstructor
Augie Fackler <augie@google.com>
parents: 24223
diff changeset
  1154
        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
  1155
        return self._newmanifest(d)
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3196
diff changeset
  1156
28203
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1157
    def readshallowdelta(self, node):
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1158
        '''For flat manifests, this is the same as readdelta(). For
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1159
        treemanifests, this will read the delta for this revlog's directory,
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1160
        without recursively reading subdirectory manifests. Instead, any
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1161
        subdirectory entry will be reported as it appears in the manifests, i.e.
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1162
        the subdirectory will be reported among files and distinguished only by
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1163
        its 't' flag.'''
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1164
        if not self._treeondisk:
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1165
            return self.readdelta(node)
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1166
        if self._usemanifestv2:
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1167
            raise error.Abort(
29389
98e8313dcd9e i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents: 29056
diff changeset
  1168
                _("readshallowdelta() not implemented for manifestv2"))
28203
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1169
        r = self.rev(node)
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1170
        d = mdiff.patchtext(self.revdiff(self.deltaparent(r), r))
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1171
        return manifestdict(d)
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
  1172
28240
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1173
    def readshallowfast(self, node):
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1174
        '''like readfast(), but calls readshallowdelta() instead of readdelta()
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1175
        '''
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1176
        r = self.rev(node)
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1177
        deltaparent = self.deltaparent(r)
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1178
        if deltaparent != revlog.nullrev and deltaparent in self.parentrevs(r):
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1179
            return self.readshallowdelta(node)
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1180
        return self.readshallow(node)
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1181
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1182
    def read(self, node):
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
  1183
        if node == revlog.nullid:
24402
c2287f203ec4 treemanifest: add configuration for using treemanifest type
Martin von Zweigbergk <martinvonz@google.com>
parents: 24401
diff changeset
  1184
            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
  1185
        if node in self._mancache:
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1186
            cached = self._mancache[node]
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1187
            if (isinstance(cached, manifestctx) or
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1188
                isinstance(cached, treemanifestctx)):
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1189
                cached = cached.read()
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1190
            return cached
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1191
        if self._treeondisk:
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1192
            def gettext():
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1193
                return self.revision(node)
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1194
            def readsubtree(dir, subm):
25185
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1195
                return self.dirlog(dir).read(subm)
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1196
            m = self._newmanifest()
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1197
            m.read(gettext, readsubtree)
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1198
            m.setnode(node)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1199
            arraytext = None
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1200
        else:
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1201
            text = self.revision(node)
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1202
            m = self._newmanifest(text)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1203
            arraytext = array.array('c', text)
29823
27c0792e834c manifest: break mancache into two caches
Durham Goode <durham@fb.com>
parents: 29715
diff changeset
  1204
        self._mancache[node] = m
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1205
        self.fulltextcache[node] = arraytext
24147
ba4fcd80079d manifest: rename 'mf', 'map', and 'mapping' to 'm'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24146
diff changeset
  1206
        return m
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1207
28240
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1208
    def readshallow(self, node):
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1209
        '''Reads the manifest in this directory. When using flat manifests,
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1210
        this manifest will generally have files in subdirectories in it. Does
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1211
        not cache the manifest as the callers generally do not read the same
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1212
        version twice.'''
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1213
        return manifestdict(self.revision(node))
1ac8ce137377 changegroup: fix treemanifests on merges
Martin von Zweigbergk <martinvonz@google.com>
parents: 28215
diff changeset
  1214
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
  1215
    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
  1216
        '''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
  1217
        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
  1218
        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
  1219
        try:
24292
b7add2ebef9e manifest: rewrite find(node, f) in terms of read(node)
Martin von Zweigbergk <martinvonz@google.com>
parents: 24277
diff changeset
  1220
            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
  1221
        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
  1222
            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
  1223
24147
ba4fcd80079d manifest: rename 'mf', 'map', and 'mapping' to 'm'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24146
diff changeset
  1224
    def add(self, m, transaction, link, p1, p2, added, removed):
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1225
        if (p1 in self.fulltextcache and not self._treeinmem
24527
8aead3bc5ff8 manifestv2: disable fastdelta optimization
Martin von Zweigbergk <martinvonz@google.com>
parents: 24526
diff changeset
  1226
            and not self._usemanifestv2):
22788
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
  1227
            # 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
  1228
            # 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
  1229
            # 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
  1230
            # revlog layer.
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
  1231
22415
65ec6c5c0fb3 manifest: mark addlistdelta and checkforbidden as module-private
Augie Fackler <raf@durin42.com>
parents: 22409
diff changeset
  1232
            _checkforbidden(added)
26199
5411059d93f8 manifest: switch add() to heapq.merge (available in Py2.6+)
timeless@mozdev.org
parents: 25276
diff changeset
  1233
            # combine the changed lists into one sorted iterator
5411059d93f8 manifest: switch add() to heapq.merge (available in Py2.6+)
timeless@mozdev.org
parents: 25276
diff changeset
  1234
            work = heapq.merge([(x, False) for x in added],
5411059d93f8 manifest: switch add() to heapq.merge (available in Py2.6+)
timeless@mozdev.org
parents: 25276
diff changeset
  1235
                               [(x, True) for x in removed])
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
  1236
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1237
            arraytext, deltatext = m.fastdelta(self.fulltextcache[p1], work)
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
  1238
            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
  1239
            text = util.buffer(arraytext)
24780
4ea521b3c554 manifest: duplicate call to addrevision()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24701
diff changeset
  1240
            n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
22788
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
  1241
        else:
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
  1242
            # 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
  1243
            # 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
  1244
            # 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
  1245
            # process.
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1246
            if self._treeondisk:
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1247
                m1 = self.read(p1)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1248
                m2 = self.read(p2)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1249
                n = self._addtree(m, transaction, link, m1, m2)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1250
                arraytext = None
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1251
            else:
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1252
                text = m.text(self._usemanifestv2)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1253
                n = self.addrevision(text, transaction, link, p1, p2)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1254
                arraytext = array.array('c', text)
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
  1255
29823
27c0792e834c manifest: break mancache into two caches
Durham Goode <durham@fb.com>
parents: 29715
diff changeset
  1256
        self._mancache[n] = m
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1257
        self.fulltextcache[n] = arraytext
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1258
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1259
        return n
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1260
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1261
    def _addtree(self, m, transaction, link, m1, m2):
25221
eafa06e9edde treemanifest: speed up commit using dirty flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 25220
diff changeset
  1262
        # If the manifest is unchanged compared to one parent,
eafa06e9edde treemanifest: speed up commit using dirty flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 25220
diff changeset
  1263
        # don't write a new revision
eafa06e9edde treemanifest: speed up commit using dirty flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 25220
diff changeset
  1264
        if m.unmodifiedsince(m1) or m.unmodifiedsince(m2):
eafa06e9edde treemanifest: speed up commit using dirty flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 25220
diff changeset
  1265
            return m.node()
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1266
        def writesubtree(subm, subp1, subp2):
25185
bf6b476f3b36 treemanifest: cache directory logs and manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25151
diff changeset
  1267
            sublog = self.dirlog(subm.dir())
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1268
            sublog.add(subm, transaction, link, subp1, subp2, None, None)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1269
        m.writesubtrees(m1, m2, writesubtree)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1270
        text = m.dirtext(self._usemanifestv2)
25221
eafa06e9edde treemanifest: speed up commit using dirty flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 25220
diff changeset
  1271
        # Double-check whether contents are unchanged to one parent
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1272
        if text == m1.dirtext(self._usemanifestv2):
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1273
            n = m1.node()
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1274
        elif text == m2.dirtext(self._usemanifestv2):
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1275
            n = m2.node()
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1276
        else:
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1277
            n = self.addrevision(text, transaction, link, m1.node(), m2.node())
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1278
        # Save nodeid so parent manifest can calculate its nodeid
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1279
        m.setnode(n)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1280
        return n
27466
f888676a23d0 manifest: implement clearcaches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27343
diff changeset
  1281
f888676a23d0 manifest: implement clearcaches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27343
diff changeset
  1282
    def clearcaches(self):
f888676a23d0 manifest: implement clearcaches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27343
diff changeset
  1283
        super(manifest, self).clearcaches()
f888676a23d0 manifest: implement clearcaches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27343
diff changeset
  1284
        self._mancache.clear()
f888676a23d0 manifest: implement clearcaches()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27343
diff changeset
  1285
        self._dirlogcache = {'': self}