mercurial/manifest.py
author Pulkit Goyal <pulkit@yandex-team.ru>
Mon, 27 Aug 2018 14:02:48 +0300
changeset 39357 2b8adb7ca39a
parent 39322 5886384d1ac5
child 39515 93486cc46125
permissions -rw-r--r--
narrow: update the narrowspecs to new ones after pulling when widening The ellipsis case updates the new narrowspecs at bundle2 handling code, and non-ellipsis widening didn't use to work and never set the new narrowpats. Previous pacth added server side logic for widening without ellipsis. This patch adds the missing repo.setnarrowpats() so that we set the new narrowpats after widening in non-ellipsis cases also. This makes widening with non-ellipsis case work but there are certain things which we can improve. Differential Revision: https://phab.mercurial-scm.org/D4384
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 heapq
32536
aa333c1982ab manifest: use itertools.chain() instead of + for Python 3 compat
Augie Fackler <raf@durin42.com>
parents: 32535
diff changeset
    11
import itertools
27502
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    12
import struct
38781
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
    13
import weakref
27502
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 _
31530
160e7ad941e9 manifest: use node.hex instead of .encode('hex')
Augie Fackler <augie@google.com>
parents: 31476
diff changeset
    16
from .node import (
160e7ad941e9 manifest: use node.hex instead of .encode('hex')
Augie Fackler <augie@google.com>
parents: 31476
diff changeset
    17
    bin,
160e7ad941e9 manifest: use node.hex instead of .encode('hex')
Augie Fackler <augie@google.com>
parents: 31476
diff changeset
    18
    hex,
39316
53363a8eff57 manifest: don't go through revlog to access node symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39315
diff changeset
    19
    nullid,
53363a8eff57 manifest: don't go through revlog to access node symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39315
diff changeset
    20
    nullrev,
31530
160e7ad941e9 manifest: use node.hex instead of .encode('hex')
Augie Fackler <augie@google.com>
parents: 31476
diff changeset
    21
)
27502
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    22
from . import (
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    23
    error,
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    24
    mdiff,
32372
df448de7cf3b parsers: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32252
diff changeset
    25
    policy,
38331
cf59de802883 py3: remove b'' from error message of disallowed filename
Yuya Nishihara <yuya@tcha.org>
parents: 37374
diff changeset
    26
    pycompat,
38530
c82ea938efbb repository: define manifest interfaces
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38510
diff changeset
    27
    repository,
27502
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    28
    revlog,
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    29
    util,
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    30
)
38530
c82ea938efbb repository: define manifest interfaces
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38510
diff changeset
    31
from .utils import (
c82ea938efbb repository: define manifest interfaces
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38510
diff changeset
    32
    interfaceutil,
c82ea938efbb repository: define manifest interfaces
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38510
diff changeset
    33
)
79
837d473d54d5 Add basic annotation support
mpm@selenic.com
parents: 78
diff changeset
    34
32372
df448de7cf3b parsers: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32252
diff changeset
    35
parsers = policy.importmod(r'parsers')
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
    36
propertycache = util.propertycache
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    37
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
    38
def _parse(data):
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    39
    # 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
    40
    # 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
    41
    # 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
    42
    # 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
    43
    # the pure version.
32535
260a6f715bd2 manifest: fix some pure-Python parser bits to work on Python 3
Augie Fackler <raf@durin42.com>
parents: 32372
diff changeset
    44
    if data and data[-1:] != '\n':
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    45
        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
    46
    prev = None
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    47
    for l in data.splitlines():
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    48
        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
    49
            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
    50
        prev = l
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    51
        f, n = l.split('\0')
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    52
        if len(n) > 40:
31366
45347d4a4f07 manifest: now that node.bin is available, use it directly
Augie Fackler <augie@google.com>
parents: 31365
diff changeset
    53
            yield f, bin(n[:40]), n[40:]
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    54
        else:
31366
45347d4a4f07 manifest: now that node.bin is available, use it directly
Augie Fackler <augie@google.com>
parents: 31365
diff changeset
    55
            yield f, bin(n), ''
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    56
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
    57
def _text(it):
24525
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    58
    files = []
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    59
    lines = []
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    60
    for f, n, fl in it:
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    61
        files.append(f)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    62
        # 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
    63
        # be sure to check the templates/ dir again (especially *-raw.tmpl)
39316
53363a8eff57 manifest: don't go through revlog to access node symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39315
diff changeset
    64
        lines.append("%s\0%s%s\n" % (f, hex(n), fl))
24525
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    65
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    66
    _checkforbidden(files)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    67
    return ''.join(lines)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    68
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    69
class lazymanifestiter(object):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    70
    def __init__(self, lm):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    71
        self.pos = 0
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    72
        self.lm = lm
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    73
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    74
    def __iter__(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    75
        return self
24223
b4df0d0c49e7 manifest: move parsing functions up in file
Augie Fackler <augie@google.com>
parents: 24215
diff changeset
    76
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    77
    def next(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    78
        try:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    79
            data, pos = self.lm._get(self.pos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    80
        except IndexError:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    81
            raise StopIteration
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    82
        if pos == -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    83
            self.pos += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    84
            return data[0]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    85
        self.pos += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    86
        zeropos = data.find('\x00', pos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    87
        return data[pos:zeropos]
24224
d71837d06597 manifest: do parsing inside manifestdict contstructor
Augie Fackler <augie@google.com>
parents: 24223
diff changeset
    88
31364
91874c247d61 manifest: add __next__ methods for Python 3
Augie Fackler <augie@google.com>
parents: 31352
diff changeset
    89
    __next__ = next
91874c247d61 manifest: add __next__ methods for Python 3
Augie Fackler <augie@google.com>
parents: 31352
diff changeset
    90
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    91
class lazymanifestiterentries(object):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    92
    def __init__(self, lm):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    93
        self.lm = lm
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    94
        self.pos = 0
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    95
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    96
    def __iter__(self):
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    97
        return self
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    98
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
    99
    def next(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   100
        try:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   101
            data, pos = self.lm._get(self.pos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   102
        except IndexError:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   103
            raise StopIteration
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   104
        if pos == -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   105
            self.pos += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   106
            return data
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   107
        zeropos = data.find('\x00', pos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   108
        hashval = unhexlify(data, self.lm.extrainfo[self.pos],
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   109
                            zeropos + 1, 40)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   110
        flags = self.lm._getflags(data, self.pos, zeropos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   111
        self.pos += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   112
        return (data[pos:zeropos], hashval, flags)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   113
31364
91874c247d61 manifest: add __next__ methods for Python 3
Augie Fackler <augie@google.com>
parents: 31352
diff changeset
   114
    __next__ = next
91874c247d61 manifest: add __next__ methods for Python 3
Augie Fackler <augie@google.com>
parents: 31352
diff changeset
   115
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   116
def unhexlify(data, extra, pos, length):
31365
28e3471a21ef manifest: use node.bin instead of .decode('hex')
Augie Fackler <augie@google.com>
parents: 31364
diff changeset
   117
    s = bin(data[pos:pos + length])
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   118
    if extra:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   119
        s += chr(extra & 0xff)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   120
    return s
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   121
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   122
def _cmp(a, b):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   123
    return (a > b) - (a < b)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   124
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   125
class _lazymanifest(object):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   126
    def __init__(self, data, positions=None, extrainfo=None, extradata=None):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   127
        if positions is None:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   128
            self.positions = self.findlines(data)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   129
            self.extrainfo = [0] * len(self.positions)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   130
            self.data = data
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   131
            self.extradata = []
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   132
        else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   133
            self.positions = positions[:]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   134
            self.extrainfo = extrainfo[:]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   135
            self.extradata = extradata[:]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   136
            self.data = data
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   137
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   138
    def findlines(self, data):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   139
        if not data:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   140
            return []
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   141
        pos = data.find("\n")
31352
667e88568087 manifest: unbreak pure-python manifest parsing on Python 3
Augie Fackler <augie@google.com>
parents: 31346
diff changeset
   142
        if pos == -1 or data[-1:] != '\n':
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   143
            raise ValueError("Manifest did not end in a newline.")
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   144
        positions = [0]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   145
        prev = data[:data.find('\x00')]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   146
        while pos < len(data) - 1 and pos != -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   147
            positions.append(pos + 1)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   148
            nexts = data[pos + 1:data.find('\x00', pos + 1)]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   149
            if nexts < prev:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   150
                raise ValueError("Manifest lines not in sorted order.")
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   151
            prev = nexts
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   152
            pos = data.find("\n", pos + 1)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   153
        return positions
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   154
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   155
    def _get(self, index):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   156
        # get the position encoded in pos:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   157
        #   positive number is an index in 'data'
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   158
        #   negative number is in extrapieces
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   159
        pos = self.positions[index]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   160
        if pos >= 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   161
            return self.data, pos
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   162
        return self.extradata[-pos - 1], -1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   163
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   164
    def _getkey(self, pos):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   165
        if pos >= 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   166
            return self.data[pos:self.data.find('\x00', pos + 1)]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   167
        return self.extradata[-pos - 1][0]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   168
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   169
    def bsearch(self, key):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   170
        first = 0
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   171
        last = len(self.positions) - 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   172
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   173
        while first <= last:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   174
            midpoint = (first + last)//2
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   175
            nextpos = self.positions[midpoint]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   176
            candidate = self._getkey(nextpos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   177
            r = _cmp(key, candidate)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   178
            if r == 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   179
                return midpoint
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   180
            else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   181
                if r < 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   182
                    last = midpoint - 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   183
                else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   184
                    first = midpoint + 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   185
        return -1
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   186
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   187
    def bsearch2(self, key):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   188
        # same as the above, but will always return the position
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   189
        # done for performance reasons
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   190
        first = 0
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   191
        last = len(self.positions) - 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   192
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   193
        while first <= last:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   194
            midpoint = (first + last)//2
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   195
            nextpos = self.positions[midpoint]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   196
            candidate = self._getkey(nextpos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   197
            r = _cmp(key, candidate)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   198
            if r == 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   199
                return (midpoint, True)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   200
            else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   201
                if r < 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   202
                    last = midpoint - 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   203
                else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   204
                    first = midpoint + 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   205
        return (first, False)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   206
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   207
    def __contains__(self, key):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   208
        return self.bsearch(key) != -1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   209
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   210
    def _getflags(self, data, needle, pos):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   211
        start = pos + 41
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   212
        end = data.find("\n", start)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   213
        if end == -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   214
            end = len(data) - 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   215
        if start == end:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   216
            return ''
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   217
        return self.data[start:end]
24297
0178f500d61e lazymanifest: fix pure hg iterkeys()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   218
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   219
    def __getitem__(self, key):
31367
ef50b491c17d manifest: ensure paths are bytes (not str) in pure parser
Augie Fackler <augie@google.com>
parents: 31366
diff changeset
   220
        if not isinstance(key, bytes):
ef50b491c17d manifest: ensure paths are bytes (not str) in pure parser
Augie Fackler <augie@google.com>
parents: 31366
diff changeset
   221
            raise TypeError("getitem: manifest keys must be a bytes.")
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   222
        needle = self.bsearch(key)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   223
        if needle == -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   224
            raise KeyError
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   225
        data, pos = self._get(needle)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   226
        if pos == -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   227
            return (data[1], data[2])
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   228
        zeropos = data.find('\x00', pos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   229
        assert 0 <= needle <= len(self.positions)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   230
        assert len(self.extrainfo) == len(self.positions)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   231
        hashval = unhexlify(data, self.extrainfo[needle], zeropos + 1, 40)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   232
        flags = self._getflags(data, needle, zeropos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   233
        return (hashval, flags)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   234
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   235
    def __delitem__(self, key):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   236
        needle, found = self.bsearch2(key)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   237
        if not found:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   238
            raise KeyError
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   239
        cur = self.positions[needle]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   240
        self.positions = self.positions[:needle] + self.positions[needle + 1:]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   241
        self.extrainfo = self.extrainfo[:needle] + self.extrainfo[needle + 1:]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   242
        if cur >= 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   243
            self.data = self.data[:cur] + '\x00' + self.data[cur + 1:]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   244
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   245
    def __setitem__(self, key, value):
31531
326bca5477d0 manifest: refer to bytestrings as bytes, not str
Augie Fackler <augie@google.com>
parents: 31530
diff changeset
   246
        if not isinstance(key, bytes):
326bca5477d0 manifest: refer to bytestrings as bytes, not str
Augie Fackler <augie@google.com>
parents: 31530
diff changeset
   247
            raise TypeError("setitem: manifest keys must be a byte string.")
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   248
        if not isinstance(value, tuple) or len(value) != 2:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   249
            raise TypeError("Manifest values must be a tuple of (node, flags).")
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   250
        hashval = value[0]
31531
326bca5477d0 manifest: refer to bytestrings as bytes, not str
Augie Fackler <augie@google.com>
parents: 31530
diff changeset
   251
        if not isinstance(hashval, bytes) or not 20 <= len(hashval) <= 22:
326bca5477d0 manifest: refer to bytestrings as bytes, not str
Augie Fackler <augie@google.com>
parents: 31530
diff changeset
   252
            raise TypeError("node must be a 20-byte byte string")
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   253
        flags = value[1]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   254
        if len(hashval) == 22:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   255
            hashval = hashval[:-1]
31531
326bca5477d0 manifest: refer to bytestrings as bytes, not str
Augie Fackler <augie@google.com>
parents: 31530
diff changeset
   256
        if not isinstance(flags, bytes) or len(flags) > 1:
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   257
            raise TypeError("flags must a 0 or 1 byte string, got %r", flags)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   258
        needle, found = self.bsearch2(key)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   259
        if found:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   260
            # put the item
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   261
            pos = self.positions[needle]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   262
            if pos < 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   263
                self.extradata[-pos - 1] = (key, hashval, value[1])
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   264
            else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   265
                # just don't bother
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   266
                self.extradata.append((key, hashval, value[1]))
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   267
                self.positions[needle] = -len(self.extradata)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   268
        else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   269
            # not found, put it in with extra positions
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   270
            self.extradata.append((key, hashval, value[1]))
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   271
            self.positions = (self.positions[:needle] + [-len(self.extradata)]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   272
                              + self.positions[needle:])
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   273
            self.extrainfo = (self.extrainfo[:needle] + [0] +
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   274
                              self.extrainfo[needle:])
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   275
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
   276
    def copy(self):
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   277
        # XXX call _compact like in C?
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   278
        return _lazymanifest(self.data, self.positions, self.extrainfo,
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   279
            self.extradata)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   280
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   281
    def _compact(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   282
        # hopefully not called TOO often
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   283
        if len(self.extradata) == 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   284
            return
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   285
        l = []
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   286
        last_cut = 0
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   287
        i = 0
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   288
        offset = 0
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   289
        self.extrainfo = [0] * len(self.positions)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   290
        while i < len(self.positions):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   291
            if self.positions[i] >= 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   292
                cur = self.positions[i]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   293
                last_cut = cur
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   294
                while True:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   295
                    self.positions[i] = offset
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   296
                    i += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   297
                    if i == len(self.positions) or self.positions[i] < 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   298
                        break
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   299
                    offset += self.positions[i] - cur
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   300
                    cur = self.positions[i]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   301
                end_cut = self.data.find('\n', cur)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   302
                if end_cut != -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   303
                    end_cut += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   304
                offset += end_cut - cur
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   305
                l.append(self.data[last_cut:end_cut])
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   306
            else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   307
                while i < len(self.positions) and self.positions[i] < 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   308
                    cur = self.positions[i]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   309
                    t = self.extradata[-cur - 1]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   310
                    l.append(self._pack(t))
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   311
                    self.positions[i] = offset
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   312
                    if len(t[1]) > 20:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   313
                        self.extrainfo[i] = ord(t[1][21])
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   314
                    offset += len(l[-1])
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   315
                    i += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   316
        self.data = ''.join(l)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   317
        self.extradata = []
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   318
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   319
    def _pack(self, d):
31530
160e7ad941e9 manifest: use node.hex instead of .encode('hex')
Augie Fackler <augie@google.com>
parents: 31476
diff changeset
   320
        return d[0] + '\x00' + hex(d[1][:20]) + d[2] + '\n'
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   321
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   322
    def text(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   323
        self._compact()
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   324
        return self.data
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   325
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   326
    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
   327
        '''Finds changes between the current manifest and m2.'''
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   328
        # XXX think whether efficiency matters here
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   329
        diff = {}
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   330
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   331
        for fn, e1, flags in self.iterentries():
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   332
            if fn not in m2:
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   333
                diff[fn] = (e1, flags), (None, '')
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   334
            else:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   335
                e2 = m2[fn]
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   336
                if (e1, flags) != e2:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   337
                    diff[fn] = (e1, flags), e2
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   338
                elif clean:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   339
                    diff[fn] = None
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   340
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   341
        for fn, e2, flags in m2.iterentries():
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   342
            if fn not in self:
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   343
                diff[fn] = (None, ''), (e2, flags)
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   344
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   345
        return diff
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   346
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   347
    def iterentries(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   348
        return lazymanifestiterentries(self)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   349
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   350
    def iterkeys(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   351
        return lazymanifestiter(self)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   352
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   353
    def __iter__(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   354
        return lazymanifestiter(self)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   355
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   356
    def __len__(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   357
        return len(self.positions)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   358
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   359
    def filtercopy(self, filterfn):
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   360
        # XXX should be optimized
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   361
        c = _lazymanifest('')
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   362
        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
   363
            if filterfn(f):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   364
                c[f] = n, fl
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   365
        return c
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   366
24226
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   367
try:
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   368
    _lazymanifest = parsers.lazymanifest
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   369
except AttributeError:
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   370
    pass
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   371
38530
c82ea938efbb repository: define manifest interfaces
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38510
diff changeset
   372
@interfaceutil.implementer(repository.imanifestdict)
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   373
class manifestdict(object):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   374
    def __init__(self, data=''):
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
   375
        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
   376
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   377
    def __getitem__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   378
        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
   379
24277
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   380
    def find(self, key):
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   381
        return self._lm[key]
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   382
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   383
    def __len__(self):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   384
        return len(self._lm)
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   385
30331
b19291e5d506 manifest: add __nonzero__ method
Durham Goode <durham@fb.com>
parents: 30295
diff changeset
   386
    def __nonzero__(self):
b19291e5d506 manifest: add __nonzero__ method
Durham Goode <durham@fb.com>
parents: 30295
diff changeset
   387
        # nonzero is covered by the __len__ function, but implementing it here
b19291e5d506 manifest: add __nonzero__ method
Durham Goode <durham@fb.com>
parents: 30295
diff changeset
   388
        # makes it easier for extensions to override.
b19291e5d506 manifest: add __nonzero__ method
Durham Goode <durham@fb.com>
parents: 30295
diff changeset
   389
        return len(self._lm) != 0
b19291e5d506 manifest: add __nonzero__ method
Durham Goode <durham@fb.com>
parents: 30295
diff changeset
   390
31476
413b44003462 py3: add __bool__ to every class defining __nonzero__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31367
diff changeset
   391
    __bool__ = __nonzero__
413b44003462 py3: add __bool__ to every class defining __nonzero__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31367
diff changeset
   392
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   393
    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
   394
        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
   395
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   396
    def __contains__(self, key):
34345
05167447f90d py3: return False early while checking whether None is a key in lazymanifest
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34296
diff changeset
   397
        if key is None:
05167447f90d py3: return False early while checking whether None is a key in lazymanifest
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34296
diff changeset
   398
            return False
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   399
        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
   400
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   401
    def __delitem__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   402
        del self._lm[key]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   403
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   404
    def __iter__(self):
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   405
        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
   406
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   407
    def iterkeys(self):
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   408
        return self._lm.iterkeys()
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   409
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   410
    def keys(self):
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   411
        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
   412
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   413
    def filesnotin(self, m2, match=None):
24184
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   414
        '''Set of files in this manifest that are not in the other'''
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   415
        if match:
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   416
            m1 = self.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   417
            m2 = m2.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   418
            return m1.filesnotin(m2)
29056
e2178f7d17c0 manifest: improve filesnotin performance by using lazymanifest diff
Tony Tung <tonytung@merly.org>
parents: 28240
diff changeset
   419
        diff = self.diff(m2)
e2178f7d17c0 manifest: improve filesnotin performance by using lazymanifest diff
Tony Tung <tonytung@merly.org>
parents: 28240
diff changeset
   420
        files = set(filepath
e2178f7d17c0 manifest: improve filesnotin performance by using lazymanifest diff
Tony Tung <tonytung@merly.org>
parents: 28240
diff changeset
   421
                    for filepath, hashflags in diff.iteritems()
e2178f7d17c0 manifest: improve filesnotin performance by using lazymanifest diff
Tony Tung <tonytung@merly.org>
parents: 28240
diff changeset
   422
                    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
   423
        return files
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   424
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   425
    @propertycache
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   426
    def _dirs(self):
24635
21e1ece30f8c util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents: 24600
diff changeset
   427
        return util.dirs(self)
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   428
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   429
    def dirs(self):
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   430
        return self._dirs
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   431
24324
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   432
    def hasdir(self, dir):
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   433
        return dir in self._dirs
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   434
24685
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   435
    def _filesfastpath(self, match):
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   436
        '''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
   437
        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
   438
        files = match.files()
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   439
        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
   440
            (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
   441
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   442
    def walk(self, match):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   443
        '''Generates matching file names.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   444
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   445
        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
   446
        an entirely new manifest.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   447
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   448
        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
   449
        '''
24683
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   450
        if match.always():
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   451
            for f in iter(self):
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   452
                yield f
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   453
            return
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   454
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   455
        fset = set(match.files())
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   456
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   457
        # 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
   458
        if self._filesfastpath(match):
24667
19c5b0913960 manifest.walk: join nested if-conditions
Martin von Zweigbergk <martinvonz@google.com>
parents: 24666
diff changeset
   459
            for fn in sorted(fset):
19c5b0913960 manifest.walk: join nested if-conditions
Martin von Zweigbergk <martinvonz@google.com>
parents: 24666
diff changeset
   460
                yield fn
24682
aef3d1469773 manifest.walk: use return instead of StopIteration in generator
Martin von Zweigbergk <martinvonz@google.com>
parents: 24670
diff changeset
   461
            return
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   462
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   463
        for fn in self:
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   464
            if fn in fset:
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   465
                # specified pattern is the exact name
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   466
                fset.remove(fn)
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   467
            if match(fn):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   468
                yield fn
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   469
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   470
        # 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
   471
        # follow that here, too
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   472
        fset.discard('.')
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   473
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   474
        for fn in sorted(fset):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   475
            if not self.hasdir(fn):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   476
                match.bad(fn, None)
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   477
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   478
    def matches(self, match):
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   479
        '''generate a new manifest filtered by the match argument'''
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   480
        if match.always():
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   481
            return self.copy()
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   482
24685
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   483
        if self._filesfastpath(match):
24666
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   484
            m = manifestdict()
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   485
            lm = self._lm
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   486
            for fn in match.files():
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   487
                if fn in lm:
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   488
                    m._lm[fn] = lm[fn]
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   489
            return m
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   490
24700
32b268cbff00 manifestdict: drop empty-string argument when creating empty manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24685
diff changeset
   491
        m = manifestdict()
24664
ea4a7c8909ae manifestdict.matches: avoid name 'lm' for a not-lazymanifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24647
diff changeset
   492
        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
   493
        return m
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   494
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   495
    def diff(self, m2, match=None, clean=False):
23756
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   496
        '''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
   497
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   498
        Args:
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   499
          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
   500
          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
   501
                 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
   502
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   503
        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
   504
        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
   505
        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
   506
        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
   507
        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
   508
        string.
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   509
        '''
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   510
        if match:
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   511
            m1 = self.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   512
            m2 = m2.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   513
            return m1.diff(m2, clean=clean)
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   514
        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
   515
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   516
    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
   517
        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
   518
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   519
    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
   520
        try:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   521
            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
   522
        except KeyError:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   523
            return default
22965
b697fa74b475 manifest: for diff(), only iterate over files, not flags
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22964
diff changeset
   524
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   525
    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
   526
        try:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   527
            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
   528
        except KeyError:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   529
            return default
22965
b697fa74b475 manifest: for diff(), only iterate over files, not flags
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22964
diff changeset
   530
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   531
    def copy(self):
24700
32b268cbff00 manifestdict: drop empty-string argument when creating empty manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24685
diff changeset
   532
        c = manifestdict()
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   533
        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
   534
        return c
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   535
32550
b98199a5c3e1 cleanup: rename all iteritems methods to items and add iteritems alias
Augie Fackler <raf@durin42.com>
parents: 32536
diff changeset
   536
    def items(self):
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   537
        return (x[:2] for x in self._lm.iterentries())
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
   538
38657
28c9d67d88ab manifest: just duplicate the definition of items as iteritems
Augie Fackler <augie@google.com>
parents: 38556
diff changeset
   539
    def iteritems(self):
28c9d67d88ab manifest: just duplicate the definition of items as iteritems
Augie Fackler <augie@google.com>
parents: 38556
diff changeset
   540
        return (x[:2] for x in self._lm.iterentries())
32550
b98199a5c3e1 cleanup: rename all iteritems methods to items and add iteritems alias
Augie Fackler <raf@durin42.com>
parents: 32536
diff changeset
   541
28203
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
   542
    def iterentries(self):
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
   543
        return self._lm.iterentries()
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
   544
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
   545
    def text(self):
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
   546
        # most likely uses native version
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
   547
        return self._lm.text()
22408
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   548
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   549
    def fastdelta(self, base, changes):
31787
6bfea18df609 manifest: update comment to be about bytearray
Martin von Zweigbergk <martinvonz@google.com>
parents: 31650
diff changeset
   550
        """Given a base manifest text as a bytearray and a list of changes
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   551
        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
   552
        """
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   553
        delta = []
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   554
        dstart = None
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   555
        dend = None
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   556
        dline = [""]
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   557
        start = 0
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   558
        # zero copy representation of base as a buffer
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   559
        addbuf = util.buffer(base)
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   560
26871
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   561
        changes = list(changes)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   562
        if len(changes) < 1000:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   563
            # 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
   564
            # each line and creates the deltas
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   565
            for f, todelete in changes:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   566
                # 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
   567
                start, end = _msearch(addbuf, f, start)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   568
                if not todelete:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   569
                    h, fl = self._lm[f]
39316
53363a8eff57 manifest: don't go through revlog to access node symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39315
diff changeset
   570
                    l = "%s\0%s%s\n" % (f, hex(h), fl)
26871
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   571
                else:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   572
                    if start == end:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   573
                        # 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
   574
                        raise AssertionError(
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   575
                                _("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
   576
                    l = ""
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   577
                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
   578
                    if dend < end:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   579
                        dend = end
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   580
                    if l:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   581
                        dline.append(l)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   582
                else:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   583
                    if dstart is not None:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   584
                        delta.append([dstart, dend, "".join(dline)])
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   585
                    dstart = start
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   586
                    dend = end
26871
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   587
                    dline = [l]
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   588
26871
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   589
            if dstart is not None:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   590
                delta.append([dstart, dend, "".join(dline)])
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   591
            # 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
   592
            deltatext, arraytext = _addlistdelta(base, delta)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   593
        else:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   594
            # 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
   595
            # diff it.
31346
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
   596
            arraytext = bytearray(self.text())
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
   597
            deltatext = mdiff.textdiff(
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
   598
                util.buffer(base), util.buffer(arraytext))
26871
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   599
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   600
        return arraytext, deltatext
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   601
22930
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   602
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
   603
    '''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
   604
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   605
    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
   606
    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
   607
    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
   608
31650
23391acfc421 py3: fix manifestdict.fastdelta() to be compatible with memoryview
Yuya Nishihara <yuya@tcha.org>
parents: 31531
diff changeset
   609
    m should be a buffer, a memoryview or a byte string.
23391acfc421 py3: fix manifestdict.fastdelta() to be compatible with memoryview
Yuya Nishihara <yuya@tcha.org>
parents: 31531
diff changeset
   610
    s is a byte string'''
22930
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   611
    def advance(i, c):
31650
23391acfc421 py3: fix manifestdict.fastdelta() to be compatible with memoryview
Yuya Nishihara <yuya@tcha.org>
parents: 31531
diff changeset
   612
        while i < lenm and m[i:i + 1] != c:
22930
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   613
            i += 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   614
        return i
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   615
    if not s:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   616
        return (lo, lo)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   617
    lenm = len(m)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   618
    if not hi:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   619
        hi = lenm
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   620
    while lo < hi:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   621
        mid = (lo + hi) // 2
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   622
        start = mid
31650
23391acfc421 py3: fix manifestdict.fastdelta() to be compatible with memoryview
Yuya Nishihara <yuya@tcha.org>
parents: 31531
diff changeset
   623
        while start > 0 and m[start - 1:start] != '\n':
22930
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   624
            start -= 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   625
        end = advance(start, '\0')
31650
23391acfc421 py3: fix manifestdict.fastdelta() to be compatible with memoryview
Yuya Nishihara <yuya@tcha.org>
parents: 31531
diff changeset
   626
        if bytes(m[start:end]) < s:
22930
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   627
            # 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
   628
            # 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
   629
            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
   630
        else:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   631
            # 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
   632
            hi = start
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   633
    end = advance(lo, '\0')
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   634
    found = m[lo:end]
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   635
    if s == found:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   636
        # 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
   637
        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
   638
        return (lo, end + 1)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   639
    else:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   640
        return (lo, lo)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   641
22415
65ec6c5c0fb3 manifest: mark addlistdelta and checkforbidden as module-private
Augie Fackler <raf@durin42.com>
parents: 22409
diff changeset
   642
def _checkforbidden(l):
22408
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   643
    """Check filenames for illegal characters."""
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   644
    for f in l:
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   645
        if '\n' in f or '\r' in f:
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   646
            raise error.RevlogError(
38331
cf59de802883 py3: remove b'' from error message of disallowed filename
Yuya Nishihara <yuya@tcha.org>
parents: 37374
diff changeset
   647
                _("'\\n' and '\\r' disallowed in filenames: %r")
cf59de802883 py3: remove b'' from error message of disallowed filename
Yuya Nishihara <yuya@tcha.org>
parents: 37374
diff changeset
   648
                % pycompat.bytestr(f))
22408
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   649
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   650
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   651
# 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
   652
# 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
   653
def _addlistdelta(addlist, x):
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   654
    # 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
   655
    # than repeatedly modifying the existing one
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   656
    currentposition = 0
31346
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
   657
    newaddlist = bytearray()
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   658
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   659
    for start, end, content in x:
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   660
        newaddlist += addlist[currentposition:start]
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   661
        if content:
31346
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
   662
            newaddlist += bytearray(content)
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   663
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   664
        currentposition = end
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   665
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   666
    newaddlist += addlist[currentposition:]
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   667
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   668
    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
   669
                   + content for start, end, content in x)
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   670
    return deltatext, newaddlist
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   671
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   672
def _splittopdir(f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   673
    if '/' in f:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   674
        dir, subpath = f.split('/', 1)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   675
        return dir + '/', subpath
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   676
    else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   677
        return '', f
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   678
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   679
_noop = lambda s: None
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   680
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   681
class treemanifest(object):
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   682
    def __init__(self, dir='', text=''):
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   683
        self._dir = dir
39316
53363a8eff57 manifest: don't go through revlog to access node symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39315
diff changeset
   684
        self._node = nullid
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   685
        self._loadfunc = _noop
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   686
        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
   687
        self._dirty = False
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   688
        self._dirs = {}
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   689
        # 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
   690
        self._files = {}
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   691
        self._flags = {}
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   692
        if text:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   693
            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
   694
                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
   695
                                     'flat manifests')
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   696
            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
   697
            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
   698
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   699
    def _subpath(self, path):
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   700
        return self._dir + path
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   701
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   702
    def __len__(self):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   703
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   704
        size = len(self._files)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   705
        for m in self._dirs.values():
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   706
            size += m.__len__()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   707
        return size
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   708
36174
b42c47b8c9d4 treemanifest: add an optimized __nonzero__()
Martin von Zweigbergk <martinvonz@google.com>
parents: 36095
diff changeset
   709
    def __nonzero__(self):
b42c47b8c9d4 treemanifest: add an optimized __nonzero__()
Martin von Zweigbergk <martinvonz@google.com>
parents: 36095
diff changeset
   710
        # Faster than "__len() != 0" since it avoids loading sub-manifests
b42c47b8c9d4 treemanifest: add an optimized __nonzero__()
Martin von Zweigbergk <martinvonz@google.com>
parents: 36095
diff changeset
   711
        return not self._isempty()
b42c47b8c9d4 treemanifest: add an optimized __nonzero__()
Martin von Zweigbergk <martinvonz@google.com>
parents: 36095
diff changeset
   712
b42c47b8c9d4 treemanifest: add an optimized __nonzero__()
Martin von Zweigbergk <martinvonz@google.com>
parents: 36095
diff changeset
   713
    __bool__ = __nonzero__
b42c47b8c9d4 treemanifest: add an optimized __nonzero__()
Martin von Zweigbergk <martinvonz@google.com>
parents: 36095
diff changeset
   714
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   715
    def _isempty(self):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   716
        self._load() # for consistency; already loaded by all callers
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   717
        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
   718
                all(m._isempty() for m in self._dirs.values())))
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   719
26400
6f9d9e2a661f manifest: add id(self) to treemanifest __repr__
Augie Fackler <augie@google.com>
parents: 26199
diff changeset
   720
    def __repr__(self):
6f9d9e2a661f manifest: add id(self) to treemanifest __repr__
Augie Fackler <augie@google.com>
parents: 26199
diff changeset
   721
        return ('<treemanifest dir=%s, node=%s, loaded=%s, dirty=%s at 0x%x>' %
39316
53363a8eff57 manifest: don't go through revlog to access node symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39315
diff changeset
   722
                (self._dir, hex(self._node),
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   723
                 bool(self._loadfunc is _noop),
26400
6f9d9e2a661f manifest: add id(self) to treemanifest __repr__
Augie Fackler <augie@google.com>
parents: 26199
diff changeset
   724
                 self._dirty, id(self)))
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   725
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   726
    def dir(self):
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   727
        '''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
   728
        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
   729
        return self._dir
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   730
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   731
    def node(self):
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   732
        '''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
   733
        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
   734
        '''
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   735
        assert not self._dirty
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   736
        return self._node
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   737
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   738
    def setnode(self, node):
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   739
        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
   740
        self._dirty = False
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   741
28206
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   742
    def iterentries(self):
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   743
        self._load()
32536
aa333c1982ab manifest: use itertools.chain() instead of + for Python 3 compat
Augie Fackler <raf@durin42.com>
parents: 32535
diff changeset
   744
        for p, n in sorted(itertools.chain(self._dirs.items(),
aa333c1982ab manifest: use itertools.chain() instead of + for Python 3 compat
Augie Fackler <raf@durin42.com>
parents: 32535
diff changeset
   745
                                           self._files.items())):
28206
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   746
            if p in self._files:
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   747
                yield self._subpath(p), n, self._flags.get(p, '')
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   748
            else:
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   749
                for x in n.iterentries():
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   750
                    yield x
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   751
32550
b98199a5c3e1 cleanup: rename all iteritems methods to items and add iteritems alias
Augie Fackler <raf@durin42.com>
parents: 32536
diff changeset
   752
    def items(self):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   753
        self._load()
32536
aa333c1982ab manifest: use itertools.chain() instead of + for Python 3 compat
Augie Fackler <raf@durin42.com>
parents: 32535
diff changeset
   754
        for p, n in sorted(itertools.chain(self._dirs.items(),
aa333c1982ab manifest: use itertools.chain() instead of + for Python 3 compat
Augie Fackler <raf@durin42.com>
parents: 32535
diff changeset
   755
                                           self._files.items())):
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   756
            if p in self._files:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   757
                yield self._subpath(p), n
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   758
            else:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   759
                for f, sn in n.iteritems():
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   760
                    yield f, sn
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   761
32550
b98199a5c3e1 cleanup: rename all iteritems methods to items and add iteritems alias
Augie Fackler <raf@durin42.com>
parents: 32536
diff changeset
   762
    iteritems = items
b98199a5c3e1 cleanup: rename all iteritems methods to items and add iteritems alias
Augie Fackler <raf@durin42.com>
parents: 32536
diff changeset
   763
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   764
    def iterkeys(self):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   765
        self._load()
32536
aa333c1982ab manifest: use itertools.chain() instead of + for Python 3 compat
Augie Fackler <raf@durin42.com>
parents: 32535
diff changeset
   766
        for p in sorted(itertools.chain(self._dirs, self._files)):
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   767
            if p in self._files:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   768
                yield self._subpath(p)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   769
            else:
35586
fbf1a5d680ea py3: don't use dict.iterkeys()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34345
diff changeset
   770
                for f in self._dirs[p]:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   771
                    yield f
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   772
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   773
    def keys(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   774
        return list(self.iterkeys())
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   775
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   776
    def __iter__(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   777
        return self.iterkeys()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   778
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   779
    def __contains__(self, f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   780
        if f is None:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   781
            return False
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   782
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   783
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   784
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   785
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   786
                return False
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   787
            return self._dirs[dir].__contains__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   788
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   789
            return f in self._files
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   790
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   791
    def get(self, f, default=None):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   792
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   793
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   794
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   795
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   796
                return default
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   797
            return self._dirs[dir].get(subpath, default)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   798
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   799
            return self._files.get(f, default)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   800
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   801
    def __getitem__(self, f):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   802
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   803
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   804
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   805
            return self._dirs[dir].__getitem__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   806
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   807
            return self._files[f]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   808
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   809
    def flags(self, f):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   810
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   811
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   812
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   813
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   814
                return ''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   815
            return self._dirs[dir].flags(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   816
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   817
            if f in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   818
                return ''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   819
            return self._flags.get(f, '')
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   820
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   821
    def find(self, f):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   822
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   823
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   824
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   825
            return self._dirs[dir].find(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   826
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   827
            return self._files[f], self._flags.get(f, '')
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   828
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   829
    def __delitem__(self, f):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   830
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   831
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   832
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   833
            self._dirs[dir].__delitem__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   834
            # If the directory is now empty, remove it
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   835
            if self._dirs[dir]._isempty():
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   836
                del self._dirs[dir]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   837
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   838
            del self._files[f]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   839
            if f in self._flags:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   840
                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
   841
        self._dirty = True
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   842
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   843
    def __setitem__(self, f, n):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   844
        assert n is not None
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   845
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   846
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   847
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   848
            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
   849
                self._dirs[dir] = treemanifest(self._subpath(dir))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   850
            self._dirs[dir].__setitem__(subpath, n)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   851
        else:
24467
bfb754050ccd treemanifest: drop 22nd byte for consistency with manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24448
diff changeset
   852
            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
   853
        self._dirty = True
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   854
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   855
    def _load(self):
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   856
        if self._loadfunc is not _noop:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   857
            lf, self._loadfunc = self._loadfunc, _noop
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   858
            lf(self)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   859
        elif self._copyfunc is not _noop:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   860
            cf, self._copyfunc = self._copyfunc, _noop
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   861
            cf(self)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   862
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   863
    def setflag(self, f, flags):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   864
        """Set the flags (symlink, executable) for path f."""
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   865
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   866
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   867
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   868
            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
   869
                self._dirs[dir] = treemanifest(self._subpath(dir))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   870
            self._dirs[dir].setflag(subpath, flags)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   871
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   872
            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
   873
        self._dirty = True
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   874
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   875
    def copy(self):
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   876
        copy = treemanifest(self._dir)
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   877
        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
   878
        copy._dirty = self._dirty
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   879
        if self._copyfunc is _noop:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   880
            def _copyfunc(s):
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   881
                self._load()
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   882
                for d in self._dirs:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   883
                    s._dirs[d] = self._dirs[d].copy()
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   884
                s._files = dict.copy(self._files)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   885
                s._flags = dict.copy(self._flags)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   886
            if self._loadfunc is _noop:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   887
                _copyfunc(copy)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   888
            else:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   889
                copy._copyfunc = _copyfunc
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   890
        else:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   891
            copy._copyfunc = self._copyfunc
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   892
        return copy
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   893
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   894
    def filesnotin(self, m2, match=None):
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   895
        '''Set of files in this manifest that are not in the other'''
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   896
        if match:
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   897
            m1 = self.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   898
            m2 = m2.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   899
            return m1.filesnotin(m2)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   900
24405
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   901
        files = set()
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   902
        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
   903
            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
   904
                return
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   905
            t1._load()
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   906
            t2._load()
24405
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   907
            for d, m1 in t1._dirs.iteritems():
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   908
                if d in t2._dirs:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   909
                    m2 = t2._dirs[d]
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   910
                    _filesnotin(m1, m2)
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   911
                else:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   912
                    files.update(m1.iterkeys())
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   913
36300
413c179cf7d5 manifest: correct the one use of iterkeys() on a dict
Augie Fackler <augie@google.com>
parents: 36174
diff changeset
   914
            for fn in t1._files:
24405
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   915
                if fn not in t2._files:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   916
                    files.add(t1._subpath(fn))
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   917
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   918
        _filesnotin(self, m2)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   919
        return files
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   920
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   921
    @propertycache
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   922
    def _alldirs(self):
24635
21e1ece30f8c util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents: 24600
diff changeset
   923
        return util.dirs(self)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   924
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   925
    def dirs(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   926
        return self._alldirs
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   927
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   928
    def hasdir(self, dir):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   929
        self._load()
24406
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   930
        topdir, subdir = _splittopdir(dir)
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   931
        if topdir:
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   932
            if topdir in self._dirs:
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   933
                return self._dirs[topdir].hasdir(subdir)
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   934
            return False
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   935
        return (dir + '/') in self._dirs
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   936
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   937
    def walk(self, match):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   938
        '''Generates matching file names.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   939
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   940
        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
   941
        an entirely new manifest.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   942
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   943
        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
   944
        '''
24683
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   945
        if match.always():
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   946
            for f in iter(self):
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   947
                yield f
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   948
            return
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   949
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   950
        fset = set(match.files())
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   951
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   952
        for fn in self._walk(match):
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   953
            if fn in fset:
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   954
                # specified pattern is the exact name
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   955
                fset.remove(fn)
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   956
            yield fn
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   957
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   958
        # 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
   959
        # follow that here, too
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   960
        fset.discard('.')
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   961
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   962
        for fn in sorted(fset):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   963
            if not self.hasdir(fn):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   964
                match.bad(fn, None)
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   965
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   966
    def _walk(self, match):
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   967
        '''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
   968
        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
   969
            return
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   970
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   971
        # 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
   972
        self._load()
36301
5245bac09e6a manifest: use list(dict) instead of dict.keys() to get a list of keys
Augie Fackler <augie@google.com>
parents: 36300
diff changeset
   973
        for p in sorted(list(self._dirs) + list(self._files)):
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   974
            if p in self._files:
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   975
                fullp = self._subpath(p)
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   976
                if match(fullp):
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   977
                    yield fullp
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   978
            else:
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   979
                for f in self._dirs[p]._walk(match):
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   980
                    yield f
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   981
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   982
    def matches(self, match):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   983
        '''generate a new manifest filtered by the match argument'''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   984
        if match.always():
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   985
            return self.copy()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   986
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   987
        return self._matches(match)
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   988
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   989
    def _matches(self, match):
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   990
        '''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
   991
        '''
27343
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27271
diff changeset
   992
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27271
diff changeset
   993
        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
   994
        if visit == 'all':
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27271
diff changeset
   995
            return self.copy()
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   996
        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
   997
        if not visit:
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   998
            return ret
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
   999
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1000
        self._load()
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1001
        for fn in self._files:
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1002
            fullp = self._subpath(fn)
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1003
            if not match(fullp):
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1004
                continue
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1005
            ret._files[fn] = self._files[fn]
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1006
            if fn in self._flags:
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1007
                ret._flags[fn] = self._flags[fn]
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1008
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1009
        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
  1010
            m = subm._matches(match)
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1011
            if not m._isempty():
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1012
                ret._dirs[dir] = m
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1013
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1014
        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
  1015
            ret._dirty = True
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1016
        return ret
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1017
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
  1018
    def diff(self, m2, match=None, clean=False):
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1019
        '''Finds changes between the current manifest and m2.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1020
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1021
        Args:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1022
          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
  1023
          clean: if true, include files unchanged between these manifests
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1024
                 with a None value in the returned dictionary.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1025
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1026
        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
  1027
        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
  1028
        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
  1029
        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
  1030
        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
  1031
        string.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1032
        '''
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
  1033
        if match:
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
  1034
            m1 = self.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
  1035
            m2 = m2.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
  1036
            return m1.diff(m2, clean=clean)
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1037
        result = {}
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1038
        emptytree = treemanifest()
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1039
        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
  1040
            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
  1041
                return
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1042
            t1._load()
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1043
            t2._load()
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1044
            for d, m1 in t1._dirs.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1045
                m2 = t2._dirs.get(d, emptytree)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1046
                _diff(m1, m2)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1047
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1048
            for d, m2 in t2._dirs.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1049
                if d not in t1._dirs:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1050
                    _diff(emptytree, m2)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1051
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1052
            for fn, n1 in t1._files.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1053
                fl1 = t1._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1054
                n2 = t2._files.get(fn, None)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1055
                fl2 = t2._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1056
                if n1 != n2 or fl1 != fl2:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1057
                    result[t1._subpath(fn)] = ((n1, fl1), (n2, fl2))
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1058
                elif clean:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1059
                    result[t1._subpath(fn)] = None
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1060
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1061
            for fn, n2 in t2._files.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1062
                if fn not in t1._files:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1063
                    fl2 = t2._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1064
                    result[t2._subpath(fn)] = ((None, ''), (n2, fl2))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1065
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1066
        _diff(self, m2)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1067
        return result
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1068
25221
eafa06e9edde treemanifest: speed up commit using dirty flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 25220
diff changeset
  1069
    def unmodifiedsince(self, m2):
eafa06e9edde treemanifest: speed up commit using dirty flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 25220
diff changeset
  1070
        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
  1071
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1072
    def parse(self, text, readsubtree):
24781
055b3cbe6c57 treemanifest: extract parse method from constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 24780
diff changeset
  1073
        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
  1074
            if fl == 't':
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1075
                f = f + '/'
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1076
                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
  1077
            elif '/' in f:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1078
                # 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
  1079
                # 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
  1080
                # 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
  1081
                # to nullid).
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1082
                self[f] = n
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1083
                if fl:
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1084
                    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
  1085
            else:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1086
                # 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
  1087
                # 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
  1088
                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
  1089
                if fl:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1090
                    self._flags[f] = fl
24781
055b3cbe6c57 treemanifest: extract parse method from constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 24780
diff changeset
  1091
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
  1092
    def text(self):
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1093
        """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
  1094
        self._load()
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
  1095
        return _text(self.iterentries())
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1096
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
  1097
    def dirtext(self):
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1098
        """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
  1099
        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
  1100
        """
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1101
        self._load()
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1102
        flags = self.flags
27271
2a31433a59ba manifest: use 't' for tree manifest flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 26871
diff changeset
  1103
        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
  1104
        files = [(f, self._files[f], flags(f)) for f in self._files]
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
  1105
        return _text(sorted(dirs + files))
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1106
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1107
    def read(self, gettext, readsubtree):
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
  1108
        def _load_for_read(s):
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
  1109
            s.parse(gettext(), readsubtree)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
  1110
            s._dirty = False
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
  1111
        self._loadfunc = _load_for_read
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1112
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1113
    def writesubtrees(self, m1, m2, writesubtree):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1114
        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
  1115
        m1._load()
8a84347b9907 manifest: call m1.load and m2.load before writing a subtree
Durham Goode <durham@fb.com>
parents: 29826
diff changeset
  1116
        m2._load()
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1117
        emptytree = treemanifest()
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1118
        for d, subm in self._dirs.iteritems():
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1119
            subp1 = m1._dirs.get(d, emptytree)._node
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1120
            subp2 = m2._dirs.get(d, emptytree)._node
39316
53363a8eff57 manifest: don't go through revlog to access node symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39315
diff changeset
  1121
            if subp1 == nullid:
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1122
                subp1, subp2 = subp2, subp1
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1123
            writesubtree(subm, subp1, subp2)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1124
31876
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1125
    def walksubtrees(self, matcher=None):
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1126
        """Returns an iterator of the subtrees of this manifest, including this
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1127
        manifest itself.
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1128
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1129
        If `matcher` is provided, it only returns subtrees that match.
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1130
        """
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1131
        if matcher and not matcher.visitdir(self._dir[:-1] or '.'):
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1132
            return
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1133
        if not matcher or matcher(self._dir[:-1]):
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1134
            yield self
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1135
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1136
        self._load()
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1137
        for d, subm in self._dirs.iteritems():
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1138
            for subtree in subm.walksubtrees(matcher=matcher):
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1139
                yield subtree
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1140
38781
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1141
class manifestfulltextcache(util.lrucachedict):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1142
    """File-backed LRU cache for the manifest cache
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1143
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1144
    File consists of entries, up to EOF:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1145
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1146
    - 20 bytes node, 4 bytes length, <length> manifest data
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1147
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1148
    These are written in reverse cache order (oldest to newest).
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1149
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1150
    """
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1151
    def __init__(self, max):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1152
        super(manifestfulltextcache, self).__init__(max)
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1153
        self._dirty = False
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1154
        self._read = False
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1155
        self._opener = None
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1156
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1157
    def read(self):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1158
        if self._read or self._opener is None:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1159
            return
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1160
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1161
        try:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1162
            with self._opener('manifestfulltextcache') as fp:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1163
                set = super(manifestfulltextcache, self).__setitem__
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1164
                # ignore trailing data, this is a cache, corruption is skipped
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1165
                while True:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1166
                    node = fp.read(20)
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1167
                    if len(node) < 20:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1168
                        break
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1169
                    try:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1170
                        size = struct.unpack('>L', fp.read(4))[0]
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1171
                    except struct.error:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1172
                        break
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1173
                    value = bytearray(fp.read(size))
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1174
                    if len(value) != size:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1175
                        break
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1176
                    set(node, value)
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1177
        except IOError:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1178
            # the file is allowed to be missing
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1179
            pass
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1180
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1181
        self._read = True
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1182
        self._dirty = False
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1183
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1184
    def write(self):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1185
        if not self._dirty or self._opener is None:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1186
            return
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1187
        # rotate backwards to the first used node
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1188
        with self._opener(
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1189
                'manifestfulltextcache', 'w', atomictemp=True, checkambig=True
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1190
            ) as fp:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1191
            node = self._head.prev
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1192
            while True:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1193
                if node.key in self._cache:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1194
                    fp.write(node.key)
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1195
                    fp.write(struct.pack('>L', len(node.value)))
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1196
                    fp.write(node.value)
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1197
                if node is self._head:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1198
                    break
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1199
                node = node.prev
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1200
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1201
    def __len__(self):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1202
        if not self._read:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1203
            self.read()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1204
        return super(manifestfulltextcache, self).__len__()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1205
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1206
    def __contains__(self, k):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1207
        if not self._read:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1208
            self.read()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1209
        return super(manifestfulltextcache, self).__contains__(k)
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1210
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1211
    def __iter__(self):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1212
        if not self._read:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1213
            self.read()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1214
        return super(manifestfulltextcache, self).__iter__()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1215
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1216
    def __getitem__(self, k):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1217
        if not self._read:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1218
            self.read()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1219
        # the cache lru order can change on read
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1220
        setdirty = self._cache.get(k) is not self._head
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1221
        value = super(manifestfulltextcache, self).__getitem__(k)
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1222
        if setdirty:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1223
            self._dirty = True
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1224
        return value
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1225
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1226
    def __setitem__(self, k, v):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1227
        if not self._read:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1228
            self.read()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1229
        super(manifestfulltextcache, self).__setitem__(k, v)
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1230
        self._dirty = True
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1231
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1232
    def __delitem__(self, k):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1233
        if not self._read:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1234
            self.read()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1235
        super(manifestfulltextcache, self).__delitem__(k)
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1236
        self._dirty = True
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1237
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1238
    def get(self, k, default=None):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1239
        if not self._read:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1240
            self.read()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1241
        return super(manifestfulltextcache, self).get(k, default=default)
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1242
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1243
    def clear(self, clear_persisted_data=False):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1244
        super(manifestfulltextcache, self).clear()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1245
        if clear_persisted_data:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1246
            self._dirty = True
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1247
            self.write()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1248
        self._read = False
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1249
39314
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1250
@interfaceutil.implementer(repository.imanifeststorage)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1251
class manifestrevlog(object):
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1252
    '''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
  1253
    full-text manifest contents.
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1254
    '''
39243
0d97530eb535 manifest: rename dir argument and attribute to tree
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39242
diff changeset
  1255
    def __init__(self, opener, tree='', dirlogcache=None, indexfile=None,
32252
d67991c4fefe treemanifest: allow manifestrevlog to take an explicit treemanifest arg
Durham Goode <durham@fb.com>
parents: 32195
diff changeset
  1256
                 treemanifest=False):
31151
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1257
        """Constructs a new manifest revlog
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1258
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1259
        `indexfile` - used by extensions to have two manifests at once, like
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1260
        when transitioning between flatmanifeset and treemanifests.
32252
d67991c4fefe treemanifest: allow manifestrevlog to take an explicit treemanifest arg
Durham Goode <durham@fb.com>
parents: 32195
diff changeset
  1261
d67991c4fefe treemanifest: allow manifestrevlog to take an explicit treemanifest arg
Durham Goode <durham@fb.com>
parents: 32195
diff changeset
  1262
        `treemanifest` - used to indicate this is a tree manifest revlog. Opener
d67991c4fefe treemanifest: allow manifestrevlog to take an explicit treemanifest arg
Durham Goode <durham@fb.com>
parents: 32195
diff changeset
  1263
        options can also be used to make this a tree manifest revlog. The opener
d67991c4fefe treemanifest: allow manifestrevlog to take an explicit treemanifest arg
Durham Goode <durham@fb.com>
parents: 32195
diff changeset
  1264
        option takes precedence, so if it is set to True, we ignore whatever
d67991c4fefe treemanifest: allow manifestrevlog to take an explicit treemanifest arg
Durham Goode <durham@fb.com>
parents: 32195
diff changeset
  1265
        value is passed in to the constructor.
31151
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1266
        """
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1267
        # 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
  1268
        # 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
  1269
        # 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
  1270
        cachesize = 4
32252
d67991c4fefe treemanifest: allow manifestrevlog to take an explicit treemanifest arg
Durham Goode <durham@fb.com>
parents: 32195
diff changeset
  1271
        optiontreemanifest = False
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1272
        opts = getattr(opener, 'options', None)
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1273
        if opts is not None:
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1274
            cachesize = opts.get('manifestcachesize', cachesize)
32252
d67991c4fefe treemanifest: allow manifestrevlog to take an explicit treemanifest arg
Durham Goode <durham@fb.com>
parents: 32195
diff changeset
  1275
            optiontreemanifest = opts.get('treemanifest', False)
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1276
32252
d67991c4fefe treemanifest: allow manifestrevlog to take an explicit treemanifest arg
Durham Goode <durham@fb.com>
parents: 32195
diff changeset
  1277
        self._treeondisk = optiontreemanifest or treemanifest
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1278
38781
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1279
        self._fulltextcache = manifestfulltextcache(cachesize)
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1280
39243
0d97530eb535 manifest: rename dir argument and attribute to tree
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39242
diff changeset
  1281
        if tree:
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1282
            assert self._treeondisk, 'opts is %r' % opts
31151
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1283
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1284
        if indexfile is None:
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1285
            indexfile = '00manifest.i'
39243
0d97530eb535 manifest: rename dir argument and attribute to tree
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39242
diff changeset
  1286
            if tree:
0d97530eb535 manifest: rename dir argument and attribute to tree
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39242
diff changeset
  1287
                indexfile = "meta/" + tree + indexfile
31151
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1288
39315
57c3864f3aad manifest: make tree a public attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39314
diff changeset
  1289
        self.tree = tree
57c3864f3aad manifest: make tree a public attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39314
diff changeset
  1290
29941
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1291
        # The dirlogcache is kept on the root manifest log
39243
0d97530eb535 manifest: rename dir argument and attribute to tree
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39242
diff changeset
  1292
        if tree:
29941
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1293
            self._dirlogcache = dirlogcache
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1294
        else:
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1295
            self._dirlogcache = {'': self}
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1296
39314
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1297
        self._revlog = revlog.revlog(opener, indexfile,
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1298
                                     # only root indexfile is cached
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1299
                                     checkambig=not bool(tree),
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1300
                                     mmaplargeindex=True)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1301
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1302
        self.index = self._revlog.index
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1303
        self.version = self._revlog.version
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1304
        self._generaldelta = self._revlog._generaldelta
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1305
38781
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1306
    def _setupmanifestcachehooks(self, repo):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1307
        """Persist the manifestfulltextcache on lock release"""
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1308
        if not util.safehasattr(repo, '_lockref'):
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1309
            return
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1310
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1311
        self._fulltextcache._opener = repo.cachevfs
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1312
        reporef = weakref.ref(repo)
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1313
        manifestrevlogref = weakref.ref(self)
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1314
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1315
        def persistmanifestcache():
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1316
            repo = reporef()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1317
            self = manifestrevlogref()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1318
            if repo is None or self is None:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1319
                return
39320
57301ba47e66 manifest: use public API for obtaining storage object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39317
diff changeset
  1320
            if repo.manifestlog.getstorage(b'') is not self:
38781
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1321
                # there's a different manifest in play now, abort
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1322
                return
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1323
            self._fulltextcache.write()
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1324
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1325
        if repo._currentlock(repo._lockref) is not None:
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1326
            repo._afterlock(persistmanifestcache)
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1327
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1328
    @property
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1329
    def fulltextcache(self):
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1330
        return self._fulltextcache
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1331
38781
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1332
    def clearcaches(self, clear_persisted_data=False):
39314
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1333
        self._revlog.clearcaches()
38781
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1334
        self._fulltextcache.clear(clear_persisted_data=clear_persisted_data)
39315
57c3864f3aad manifest: make tree a public attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39314
diff changeset
  1335
        self._dirlogcache = {self.tree: self}
29941
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1336
36095
59adb3051718 manifest: clean up dirlog() to take a d parameter to avoid shadowing dir()
Augie Fackler <augie@google.com>
parents: 35586
diff changeset
  1337
    def dirlog(self, d):
59adb3051718 manifest: clean up dirlog() to take a d parameter to avoid shadowing dir()
Augie Fackler <augie@google.com>
parents: 35586
diff changeset
  1338
        if d:
29941
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1339
            assert self._treeondisk
36095
59adb3051718 manifest: clean up dirlog() to take a d parameter to avoid shadowing dir()
Augie Fackler <augie@google.com>
parents: 35586
diff changeset
  1340
        if d not in self._dirlogcache:
59adb3051718 manifest: clean up dirlog() to take a d parameter to avoid shadowing dir()
Augie Fackler <augie@google.com>
parents: 35586
diff changeset
  1341
            mfrevlog = manifestrevlog(self.opener, d,
32252
d67991c4fefe treemanifest: allow manifestrevlog to take an explicit treemanifest arg
Durham Goode <durham@fb.com>
parents: 32195
diff changeset
  1342
                                      self._dirlogcache,
d67991c4fefe treemanifest: allow manifestrevlog to take an explicit treemanifest arg
Durham Goode <durham@fb.com>
parents: 32195
diff changeset
  1343
                                      treemanifest=self._treeondisk)
36095
59adb3051718 manifest: clean up dirlog() to take a d parameter to avoid shadowing dir()
Augie Fackler <augie@google.com>
parents: 35586
diff changeset
  1344
            self._dirlogcache[d] = mfrevlog
59adb3051718 manifest: clean up dirlog() to take a d parameter to avoid shadowing dir()
Augie Fackler <augie@google.com>
parents: 35586
diff changeset
  1345
        return self._dirlogcache[d]
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1346
30368
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1347
    def add(self, m, transaction, link, p1, p2, added, removed, readtree=None):
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
  1348
        if p1 in self.fulltextcache and util.safehasattr(m, 'fastdelta'):
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1349
            # If our first parent is in the manifest cache, we can
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1350
            # compute a delta here using properties we know about the
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1351
            # manifest up-front, which may save time later for the
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1352
            # revlog layer.
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1353
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1354
            _checkforbidden(added)
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1355
            # combine the changed lists into one sorted iterator
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1356
            work = heapq.merge([(x, False) for x in added],
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1357
                               [(x, True) for x in removed])
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1358
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1359
            arraytext, deltatext = m.fastdelta(self.fulltextcache[p1], work)
39314
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1360
            cachedelta = self._revlog.rev(p1), deltatext
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1361
            text = util.buffer(arraytext)
39314
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1362
            n = self._revlog.addrevision(text, transaction, link, p1, p2,
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1363
                                         cachedelta)
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1364
        else:
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1365
            # The first parent manifest isn't already loaded, so we'll
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1366
            # just encode a fulltext of the manifest and pass that
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1367
            # through to the revlog layer, and let it handle the delta
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1368
            # process.
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1369
            if self._treeondisk:
30368
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1370
                assert readtree, "readtree must be set for treemanifest writes"
39315
57c3864f3aad manifest: make tree a public attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39314
diff changeset
  1371
                m1 = readtree(self.tree, p1)
57c3864f3aad manifest: make tree a public attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39314
diff changeset
  1372
                m2 = readtree(self.tree, p2)
30368
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1373
                n = self._addtree(m, transaction, link, m1, m2, readtree)
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1374
                arraytext = None
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1375
            else:
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
  1376
                text = m.text()
39314
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1377
                n = self._revlog.addrevision(text, transaction, link, p1, p2)
31346
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
  1378
                arraytext = bytearray(text)
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1379
30209
9d06b65c5df2 manifest: don't store None in fulltextcache
Martin von Zweigbergk <martinvonz@google.com>
parents: 30207
diff changeset
  1380
        if arraytext is not None:
9d06b65c5df2 manifest: don't store None in fulltextcache
Martin von Zweigbergk <martinvonz@google.com>
parents: 30207
diff changeset
  1381
            self.fulltextcache[n] = arraytext
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1382
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1383
        return n
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1384
30368
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1385
    def _addtree(self, m, transaction, link, m1, m2, readtree):
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1386
        # If the manifest is unchanged compared to one parent,
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1387
        # don't write a new revision
39315
57c3864f3aad manifest: make tree a public attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39314
diff changeset
  1388
        if self.tree != '' and (m.unmodifiedsince(m1) or m.unmodifiedsince(
39243
0d97530eb535 manifest: rename dir argument and attribute to tree
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39242
diff changeset
  1389
            m2)):
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1390
            return m.node()
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1391
        def writesubtree(subm, subp1, subp2):
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1392
            sublog = self.dirlog(subm.dir())
30368
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1393
            sublog.add(subm, transaction, link, subp1, subp2, None, None,
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1394
                       readtree=readtree)
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1395
        m.writesubtrees(m1, m2, writesubtree)
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
  1396
        text = m.dirtext()
31294
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1397
        n = None
39315
57c3864f3aad manifest: make tree a public attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39314
diff changeset
  1398
        if self.tree != '':
31294
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1399
            # Double-check whether contents are unchanged to one parent
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
  1400
            if text == m1.dirtext():
31294
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1401
                n = m1.node()
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
  1402
            elif text == m2.dirtext():
31294
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1403
                n = m2.node()
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1404
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1405
        if not n:
39314
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1406
            n = self._revlog.addrevision(text, transaction, link, m1.node(),
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1407
                                         m2.node())
31294
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1408
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1409
        # Save nodeid so parent manifest can calculate its nodeid
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1410
        m.setnode(n)
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1411
        return n
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1412
39314
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1413
    def __len__(self):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1414
        return len(self._revlog)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1415
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1416
    def __iter__(self):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1417
        return self._revlog.__iter__()
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1418
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1419
    def rev(self, node):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1420
        return self._revlog.rev(node)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1421
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1422
    def node(self, rev):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1423
        return self._revlog.node(rev)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1424
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1425
    def lookup(self, value):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1426
        return self._revlog.lookup(value)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1427
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1428
    def parentrevs(self, rev):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1429
        return self._revlog.parentrevs(rev)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1430
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1431
    def parents(self, node):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1432
        return self._revlog.parents(node)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1433
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1434
    def linkrev(self, rev):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1435
        return self._revlog.linkrev(rev)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1436
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1437
    def checksize(self):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1438
        return self._revlog.checksize()
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1439
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1440
    def revision(self, node, _df=None, raw=False):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1441
        return self._revlog.revision(node, _df=_df, raw=raw)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1442
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1443
    def revdiff(self, rev1, rev2):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1444
        return self._revlog.revdiff(rev1, rev2)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1445
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1446
    def cmp(self, node, text):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1447
        return self._revlog.cmp(node, text)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1448
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1449
    def deltaparent(self, rev):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1450
        return self._revlog.deltaparent(rev)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1451
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1452
    def emitrevisiondeltas(self, requests):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1453
        return self._revlog.emitrevisiondeltas(requests)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1454
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1455
    def addgroup(self, deltas, linkmapper, transaction, addrevisioncb=None):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1456
        return self._revlog.addgroup(deltas, linkmapper, transaction,
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1457
                                     addrevisioncb=addrevisioncb)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1458
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1459
    def getstrippoint(self, minlink):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1460
        return self._revlog.getstrippoint(minlink)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1461
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1462
    def strip(self, minlink, transaction):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1463
        return self._revlog.strip(minlink, transaction)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1464
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1465
    def files(self):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1466
        return self._revlog.files()
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1467
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1468
    def clone(self, tr, destrevlog, **kwargs):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1469
        if not isinstance(destrevlog, manifestrevlog):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1470
            raise error.ProgrammingError('expected manifestrevlog to clone()')
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1471
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1472
        return self._revlog.clone(tr, destrevlog._revlog, **kwargs)
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1473
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1474
    @property
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1475
    def indexfile(self):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1476
        return self._revlog.indexfile
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1477
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1478
    @indexfile.setter
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1479
    def indexfile(self, value):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1480
        self._revlog.indexfile = value
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1481
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1482
    @property
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1483
    def opener(self):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1484
        return self._revlog.opener
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1485
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1486
    @opener.setter
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1487
    def opener(self, value):
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1488
        self._revlog.opener = value
7f5e6d3e9032 manifest: proxy to revlog instance instead of inheriting
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39246
diff changeset
  1489
38530
c82ea938efbb repository: define manifest interfaces
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38510
diff changeset
  1490
@interfaceutil.implementer(repository.imanifestlog)
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1491
class manifestlog(object):
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1492
    """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
  1493
    referenced by commits in the repository.
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1494
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1495
    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
  1496
    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
  1497
    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
  1498
    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
  1499
    def __init__(self, opener, repo):
29959
483003c27938 manifest: move treeinmem onto manifestlog
Durham Goode <durham@fb.com>
parents: 29941
diff changeset
  1500
        usetreemanifest = False
30372
7c7d845f8b64 manifest: make manifestlog use it's own cache
Durham Goode <durham@fb.com>
parents: 30371
diff changeset
  1501
        cachesize = 4
29959
483003c27938 manifest: move treeinmem onto manifestlog
Durham Goode <durham@fb.com>
parents: 29941
diff changeset
  1502
483003c27938 manifest: move treeinmem onto manifestlog
Durham Goode <durham@fb.com>
parents: 29941
diff changeset
  1503
        opts = getattr(opener, 'options', None)
483003c27938 manifest: move treeinmem onto manifestlog
Durham Goode <durham@fb.com>
parents: 29941
diff changeset
  1504
        if opts is not None:
483003c27938 manifest: move treeinmem onto manifestlog
Durham Goode <durham@fb.com>
parents: 29941
diff changeset
  1505
            usetreemanifest = opts.get('treemanifest', usetreemanifest)
30372
7c7d845f8b64 manifest: make manifestlog use it's own cache
Durham Goode <durham@fb.com>
parents: 30371
diff changeset
  1506
            cachesize = opts.get('manifestcachesize', cachesize)
39245
071f97d03acb manifest: rename manifestlog._treeinmem to ._treemanifests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39244
diff changeset
  1507
071f97d03acb manifest: rename manifestlog._treeinmem to ._treemanifests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39244
diff changeset
  1508
        self._treemanifests = usetreemanifest
29959
483003c27938 manifest: move treeinmem onto manifestlog
Durham Goode <durham@fb.com>
parents: 29941
diff changeset
  1509
39321
52860f52ed13 manifest: rename manifestlog._revlog to _rootstore
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39320
diff changeset
  1510
        self._rootstore = repo._constructmanifest()
52860f52ed13 manifest: rename manifestlog._revlog to _rootstore
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39320
diff changeset
  1511
        self._rootstore._setupmanifestcachehooks(repo)
37373
c50078fc32f3 narrow: move manifestrevlog overrides to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37372
diff changeset
  1512
        self._narrowmatch = repo.narrowmatch()
30219
3c8811efdddc manifest: make manifestlog a storecache
Durham Goode <durham@fb.com>
parents: 30209
diff changeset
  1513
30292
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1514
        # A cache of the manifestctx or treemanifestctx for each directory
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1515
        self._dirmancache = {}
30372
7c7d845f8b64 manifest: make manifestlog use it's own cache
Durham Goode <durham@fb.com>
parents: 30371
diff changeset
  1516
        self._dirmancache[''] = util.lrucachedict(cachesize)
30292
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1517
38510
561a450c7b64 manifest: make cachesize a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38331
diff changeset
  1518
        self._cachesize = cachesize
29826
93b44aa17691 manifest: use property instead of field for manifest revlog storage
Durham Goode <durham@fb.com>
parents: 29825
diff changeset
  1519
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1520
    def __getitem__(self, node):
30290
1a0c1ad57833 manifest: throw LookupError if node not in revlog
Durham Goode <durham@fb.com>
parents: 30221
diff changeset
  1521
        """Retrieves the manifest instance for the given node. Throws a
1a0c1ad57833 manifest: throw LookupError if node not in revlog
Durham Goode <durham@fb.com>
parents: 30221
diff changeset
  1522
        LookupError if not found.
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1523
        """
30291
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1524
        return self.get('', node)
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1525
39235
43387fd2aa1f manifest: rename dir to tree to avoid shadowing built-in
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38781
diff changeset
  1526
    def get(self, tree, node, verify=True):
30291
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1527
        """Retrieves the manifest instance for the given node. Throws a
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1528
        LookupError if not found.
30403
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1529
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1530
        `verify` - if True an exception will be thrown if the node is not in
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1531
                   the revlog
30291
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1532
        """
39235
43387fd2aa1f manifest: rename dir to tree to avoid shadowing built-in
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38781
diff changeset
  1533
        if node in self._dirmancache.get(tree, ()):
43387fd2aa1f manifest: rename dir to tree to avoid shadowing built-in
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38781
diff changeset
  1534
            return self._dirmancache[tree][node]
30292
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1535
37374
ac42e39b1b77 narrow: move manifestlog overrides to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37373
diff changeset
  1536
        if not self._narrowmatch.always():
39235
43387fd2aa1f manifest: rename dir to tree to avoid shadowing built-in
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38781
diff changeset
  1537
            if not self._narrowmatch.visitdir(tree[:-1] or '.'):
43387fd2aa1f manifest: rename dir to tree to avoid shadowing built-in
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38781
diff changeset
  1538
                return excludeddirmanifestctx(tree, node)
43387fd2aa1f manifest: rename dir to tree to avoid shadowing built-in
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38781
diff changeset
  1539
        if tree:
39321
52860f52ed13 manifest: rename manifestlog._revlog to _rootstore
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39320
diff changeset
  1540
            if self._rootstore._treeondisk:
30403
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1541
                if verify:
39246
61700d525a3b manifest: use rev() instead of nodemap.__contains__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39245
diff changeset
  1542
                    # Side-effect is LookupError is raised if node doesn't
61700d525a3b manifest: use rev() instead of nodemap.__contains__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39245
diff changeset
  1543
                    # exist.
61700d525a3b manifest: use rev() instead of nodemap.__contains__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39245
diff changeset
  1544
                    self.getstorage(tree).rev(node)
61700d525a3b manifest: use rev() instead of nodemap.__contains__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39245
diff changeset
  1545
39235
43387fd2aa1f manifest: rename dir to tree to avoid shadowing built-in
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38781
diff changeset
  1546
                m = treemanifestctx(self, tree, node)
30291
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1547
            else:
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1548
                raise error.Abort(
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1549
                        _("cannot ask for manifest directory '%s' in a flat "
39235
43387fd2aa1f manifest: rename dir to tree to avoid shadowing built-in
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38781
diff changeset
  1550
                          "manifest") % tree)
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1551
        else:
30403
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1552
            if verify:
39246
61700d525a3b manifest: use rev() instead of nodemap.__contains__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39245
diff changeset
  1553
                # Side-effect is LookupError is raised if node doesn't exist.
39321
52860f52ed13 manifest: rename manifestlog._revlog to _rootstore
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39320
diff changeset
  1554
                self._rootstore.rev(node)
39246
61700d525a3b manifest: use rev() instead of nodemap.__contains__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39245
diff changeset
  1555
39245
071f97d03acb manifest: rename manifestlog._treeinmem to ._treemanifests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39244
diff changeset
  1556
            if self._treemanifests:
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1557
                m = treemanifestctx(self, '', node)
30291
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1558
            else:
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1559
                m = manifestctx(self, node)
30292
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1560
39316
53363a8eff57 manifest: don't go through revlog to access node symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39315
diff changeset
  1561
        if node != nullid:
39235
43387fd2aa1f manifest: rename dir to tree to avoid shadowing built-in
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38781
diff changeset
  1562
            mancache = self._dirmancache.get(tree)
30292
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1563
            if not mancache:
38510
561a450c7b64 manifest: make cachesize a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38331
diff changeset
  1564
                mancache = util.lrucachedict(self._cachesize)
39235
43387fd2aa1f manifest: rename dir to tree to avoid shadowing built-in
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38781
diff changeset
  1565
                self._dirmancache[tree] = mancache
30292
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1566
            mancache[node] = m
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1567
        return m
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1568
39244
73cf21b2e8a6 manifest: add getstorage() to manifestlog and use it globally
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39243
diff changeset
  1569
    def getstorage(self, tree):
39321
52860f52ed13 manifest: rename manifestlog._revlog to _rootstore
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39320
diff changeset
  1570
        return self._rootstore.dirlog(tree)
39244
73cf21b2e8a6 manifest: add getstorage() to manifestlog and use it globally
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39243
diff changeset
  1571
38781
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1572
    def clearcaches(self, clear_persisted_data=False):
30370
10c924596e5c manifest: move clearcaches to manifestlog
Durham Goode <durham@fb.com>
parents: 30369
diff changeset
  1573
        self._dirmancache.clear()
39321
52860f52ed13 manifest: rename manifestlog._revlog to _rootstore
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39320
diff changeset
  1574
        self._rootstore.clearcaches(clear_persisted_data=clear_persisted_data)
30370
10c924596e5c manifest: move clearcaches to manifestlog
Durham Goode <durham@fb.com>
parents: 30369
diff changeset
  1575
38555
f2f9bacf0587 manifest: define and implement rev() on manifestlog
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38530
diff changeset
  1576
    def rev(self, node):
39321
52860f52ed13 manifest: rename manifestlog._revlog to _rootstore
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39320
diff changeset
  1577
        return self._rootstore.rev(node)
38555
f2f9bacf0587 manifest: define and implement rev() on manifestlog
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38530
diff changeset
  1578
38530
c82ea938efbb repository: define manifest interfaces
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38510
diff changeset
  1579
@interfaceutil.implementer(repository.imanifestrevisionwritable)
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1580
class memmanifestctx(object):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1581
    def __init__(self, manifestlog):
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1582
        self._manifestlog = manifestlog
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1583
        self._manifestdict = manifestdict()
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1584
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1585
    def _storage(self):
39320
57301ba47e66 manifest: use public API for obtaining storage object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39317
diff changeset
  1586
        return self._manifestlog.getstorage(b'')
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1587
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1588
    def new(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1589
        return memmanifestctx(self._manifestlog)
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1590
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1591
    def copy(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1592
        memmf = memmanifestctx(self._manifestlog)
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1593
        memmf._manifestdict = self.read().copy()
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1594
        return memmf
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1595
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1596
    def read(self):
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1597
        return self._manifestdict
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1598
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1599
    def write(self, transaction, link, p1, p2, added, removed):
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1600
        return self._storage().add(self._manifestdict, transaction, link,
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1601
                                   p1, p2, added, removed)
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1602
38530
c82ea938efbb repository: define manifest interfaces
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38510
diff changeset
  1603
@interfaceutil.implementer(repository.imanifestrevisionstored)
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1604
class manifestctx(object):
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1605
    """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
  1606
    contents, its parent revs, and its linkrev.
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1607
    """
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1608
    def __init__(self, manifestlog, node):
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1609
        self._manifestlog = manifestlog
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1610
        self._data = None
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1611
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1612
        self._node = node
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1613
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1614
        # 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
  1615
        # 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
  1616
        # lazily.
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1617
        #self.p1, self.p2 = store.parents(node)
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1618
        #rev = store.rev(node)
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1619
        #self.linkrev = store.linkrev(rev)
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1620
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1621
    def _storage(self):
39320
57301ba47e66 manifest: use public API for obtaining storage object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39317
diff changeset
  1622
        return self._manifestlog.getstorage(b'')
30341
3dfb5a0171c9 manifestctx: add _revlog() function
Durham Goode <durham@fb.com>
parents: 30340
diff changeset
  1623
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1624
    def node(self):
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1625
        return self._node
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1626
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1627
    def new(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1628
        return memmanifestctx(self._manifestlog)
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1629
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1630
    def copy(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1631
        memmf = memmanifestctx(self._manifestlog)
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1632
        memmf._manifestdict = self.read().copy()
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1633
        return memmf
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1634
30565
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1635
    @propertycache
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1636
    def parents(self):
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1637
        return self._storage().parents(self._node)
30565
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1638
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1639
    def read(self):
31097
4a1486c73fdf manifest: check 'if x is None' instead of 'if not x'
Durham Goode <durham@fb.com>
parents: 30565
diff changeset
  1640
        if self._data is None:
39316
53363a8eff57 manifest: don't go through revlog to access node symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39315
diff changeset
  1641
            if self._node == nullid:
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1642
                self._data = manifestdict()
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1643
            else:
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1644
                store = self._storage()
39322
5886384d1ac5 manifest: use fulltextcache instead of _fulltextcache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39321
diff changeset
  1645
                if self._node in store.fulltextcache:
5886384d1ac5 manifest: use fulltextcache instead of _fulltextcache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39321
diff changeset
  1646
                    text = pycompat.bytestr(store.fulltextcache[self._node])
38781
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1647
                else:
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1648
                    text = store.revision(self._node)
38781
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1649
                    arraytext = bytearray(text)
39322
5886384d1ac5 manifest: use fulltextcache instead of _fulltextcache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39321
diff changeset
  1650
                    store.fulltextcache[self._node] = arraytext
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1651
                self._data = manifestdict(text)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1652
        return self._data
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1653
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1654
    def readfast(self, shallow=False):
30294
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1655
        '''Calls either readdelta or read, based on which would be less work.
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1656
        readdelta is called if the delta is against the p1, and therefore can be
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1657
        read quickly.
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1658
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1659
        If `shallow` is True, nothing changes since this is a flat manifest.
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1660
        '''
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1661
        store = self._storage()
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1662
        r = store.rev(self._node)
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1663
        deltaparent = store.deltaparent(r)
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1664
        if deltaparent != nullrev and deltaparent in store.parentrevs(r):
29939
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1665
            return self.readdelta()
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1666
        return self.read()
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1667
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1668
    def readdelta(self, shallow=False):
30295
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1669
        '''Returns a manifest containing just the entries that are present
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1670
        in this manifest, but not in its p1 manifest. This is efficient to read
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1671
        if the revlog delta is already p1.
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1672
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1673
        Changing the value of `shallow` has no effect on flat manifests.
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1674
        '''
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1675
        store = self._storage()
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1676
        r = store.rev(self._node)
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1677
        d = mdiff.patchtext(store.revdiff(store.deltaparent(r), r))
29938
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1678
        return manifestdict(d)
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1679
30340
608ba935e041 manifest: remove manifest.find
Durham Goode <durham@fb.com>
parents: 30338
diff changeset
  1680
    def find(self, key):
608ba935e041 manifest: remove manifest.find
Durham Goode <durham@fb.com>
parents: 30338
diff changeset
  1681
        return self.read().find(key)
608ba935e041 manifest: remove manifest.find
Durham Goode <durham@fb.com>
parents: 30338
diff changeset
  1682
38530
c82ea938efbb repository: define manifest interfaces
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38510
diff changeset
  1683
@interfaceutil.implementer(repository.imanifestrevisionwritable)
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1684
class memtreemanifestctx(object):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1685
    def __init__(self, manifestlog, dir=''):
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1686
        self._manifestlog = manifestlog
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1687
        self._dir = dir
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1688
        self._treemanifest = treemanifest()
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1689
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1690
    def _storage(self):
39320
57301ba47e66 manifest: use public API for obtaining storage object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39317
diff changeset
  1691
        return self._manifestlog.getstorage(b'')
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1692
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1693
    def new(self, dir=''):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1694
        return memtreemanifestctx(self._manifestlog, dir=dir)
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1695
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1696
    def copy(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1697
        memmf = memtreemanifestctx(self._manifestlog, dir=self._dir)
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1698
        memmf._treemanifest = self._treemanifest.copy()
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1699
        return memmf
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1700
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1701
    def read(self):
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1702
        return self._treemanifest
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1703
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1704
    def write(self, transaction, link, p1, p2, added, removed):
30368
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1705
        def readtree(dir, node):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1706
            return self._manifestlog.get(dir, node).read()
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1707
        return self._storage().add(self._treemanifest, transaction, link,
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1708
                                   p1, p2, added, removed, readtree=readtree)
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1709
38530
c82ea938efbb repository: define manifest interfaces
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38510
diff changeset
  1710
@interfaceutil.implementer(repository.imanifestrevisionstored)
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1711
class treemanifestctx(object):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1712
    def __init__(self, manifestlog, dir, node):
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1713
        self._manifestlog = manifestlog
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1714
        self._dir = dir
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1715
        self._data = None
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1716
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1717
        self._node = node
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1718
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1719
        # 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
  1720
        # we can instantiate treemanifestctx objects for directories we don't
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1721
        # have on disk.
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1722
        #self.p1, self.p2 = store.parents(node)
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1723
        #rev = store.rev(node)
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1724
        #self.linkrev = store.linkrev(rev)
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1725
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1726
    def _storage(self):
37373
c50078fc32f3 narrow: move manifestrevlog overrides to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37372
diff changeset
  1727
        narrowmatch = self._manifestlog._narrowmatch
c50078fc32f3 narrow: move manifestrevlog overrides to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37372
diff changeset
  1728
        if not narrowmatch.always():
c50078fc32f3 narrow: move manifestrevlog overrides to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37372
diff changeset
  1729
            if not narrowmatch.visitdir(self._dir[:-1] or '.'):
c50078fc32f3 narrow: move manifestrevlog overrides to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37372
diff changeset
  1730
                return excludedmanifestrevlog(self._dir)
39244
73cf21b2e8a6 manifest: add getstorage() to manifestlog and use it globally
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39243
diff changeset
  1731
        return self._manifestlog.getstorage(self._dir)
30221
f2c5b9d48b29 manifest: make treemanifestctx store the repo
Durham Goode <durham@fb.com>
parents: 30220
diff changeset
  1732
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1733
    def read(self):
31097
4a1486c73fdf manifest: check 'if x is None' instead of 'if not x'
Durham Goode <durham@fb.com>
parents: 30565
diff changeset
  1734
        if self._data is None:
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1735
            store = self._storage()
39316
53363a8eff57 manifest: don't go through revlog to access node symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39315
diff changeset
  1736
            if self._node == nullid:
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1737
                self._data = treemanifest()
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1738
            # TODO accessing non-public API
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1739
            elif store._treeondisk:
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1740
                m = treemanifest(dir=self._dir)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1741
                def gettext():
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1742
                    return store.revision(self._node)
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1743
                def readsubtree(dir, subm):
30404
a1beadaa4061 manifest: change treemanifestctx to construct subtrees from the manifestlog
Durham Goode <durham@fb.com>
parents: 30403
diff changeset
  1744
                    # Set verify to False since we need to be able to create
a1beadaa4061 manifest: change treemanifestctx to construct subtrees from the manifestlog
Durham Goode <durham@fb.com>
parents: 30403
diff changeset
  1745
                    # subtrees for trees that don't exist on disk.
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1746
                    return self._manifestlog.get(dir, subm, verify=False).read()
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1747
                m.read(gettext, readsubtree)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1748
                m.setnode(self._node)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1749
                self._data = m
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1750
            else:
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1751
                if self._node in store.fulltextcache:
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1752
                    text = pycompat.bytestr(store.fulltextcache[self._node])
38781
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1753
                else:
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1754
                    text = store.revision(self._node)
38781
0a57945aaf7f manifest: persist the manifestfulltext cache
Martijn Pieters <mj@zopatista.com>
parents: 38657
diff changeset
  1755
                    arraytext = bytearray(text)
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1756
                    store.fulltextcache[self._node] = arraytext
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1757
                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
  1758
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1759
        return self._data
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1760
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1761
    def node(self):
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1762
        return self._node
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1763
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1764
    def new(self, dir=''):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1765
        return memtreemanifestctx(self._manifestlog, dir=dir)
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1766
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1767
    def copy(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1768
        memmf = memtreemanifestctx(self._manifestlog, dir=self._dir)
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1769
        memmf._treemanifest = self.read().copy()
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1770
        return memmf
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1771
30565
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1772
    @propertycache
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1773
    def parents(self):
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1774
        return self._storage().parents(self._node)
30565
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1775
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1776
    def readdelta(self, shallow=False):
30295
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1777
        '''Returns a manifest containing just the entries that are present
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1778
        in this manifest, but not in its p1 manifest. This is efficient to read
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1779
        if the revlog delta is already p1.
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1780
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1781
        If `shallow` is True, this will read the delta for this directory,
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1782
        without recursively reading subdirectory manifests. Instead, any
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1783
        subdirectory entry will be reported as it appears in the manifest, i.e.
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1784
        the subdirectory will be reported among files and distinguished only by
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1785
        its 't' flag.
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1786
        '''
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1787
        store = self._storage()
36373
0147a4730420 cleanup: say goodbye to manifestv2 format
Augie Fackler <augie@google.com>
parents: 36301
diff changeset
  1788
        if shallow:
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1789
            r = store.rev(self._node)
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1790
            d = mdiff.patchtext(store.revdiff(store.deltaparent(r), r))
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1791
            return manifestdict(d)
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1792
        else:
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1793
            # Need to perform a slow delta
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1794
            r0 = store.deltaparent(store.rev(self._node))
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1795
            m0 = self._manifestlog.get(self._dir, store.node(r0)).read()
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1796
            m1 = self.read()
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1797
            md = treemanifest(dir=self._dir)
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1798
            for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1799
                if n1:
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1800
                    md[f] = n1
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1801
                    if fl1:
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1802
                        md.setflag(f, fl1)
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1803
            return md
29938
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1804
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1805
    def readfast(self, shallow=False):
30294
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1806
        '''Calls either readdelta or read, based on which would be less work.
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1807
        readdelta is called if the delta is against the p1, and therefore can be
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1808
        read quickly.
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1809
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1810
        If `shallow` is True, it only returns the entries from this manifest,
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1811
        and not any submanifests.
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1812
        '''
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1813
        store = self._storage()
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1814
        r = store.rev(self._node)
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1815
        deltaparent = store.deltaparent(r)
39316
53363a8eff57 manifest: don't go through revlog to access node symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39315
diff changeset
  1816
        if (deltaparent != nullrev and
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1817
            deltaparent in store.parentrevs(r)):
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1818
            return self.readdelta(shallow=shallow)
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1819
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1820
        if shallow:
39317
eb9b8679c852 manifest: change terminology for storage in context classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39316
diff changeset
  1821
            return manifestdict(store.revision(self._node))
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1822
        else:
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1823
            return self.read()
29939
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1824
30340
608ba935e041 manifest: remove manifest.find
Durham Goode <durham@fb.com>
parents: 30338
diff changeset
  1825
    def find(self, key):
608ba935e041 manifest: remove manifest.find
Durham Goode <durham@fb.com>
parents: 30338
diff changeset
  1826
        return self.read().find(key)
37372
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1827
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1828
class excludeddir(treemanifest):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1829
    """Stand-in for a directory that is excluded from the repository.
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1830
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1831
    With narrowing active on a repository that uses treemanifests,
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1832
    some of the directory revlogs will be excluded from the resulting
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1833
    clone. This is a huge storage win for clients, but means we need
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1834
    some sort of pseudo-manifest to surface to internals so we can
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1835
    detect a merge conflict outside the narrowspec. That's what this
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1836
    class is: it stands in for a directory whose node is known, but
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1837
    whose contents are unknown.
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1838
    """
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1839
    def __init__(self, dir, node):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1840
        super(excludeddir, self).__init__(dir)
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1841
        self._node = node
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1842
        # Add an empty file, which will be included by iterators and such,
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1843
        # appearing as the directory itself (i.e. something like "dir/")
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1844
        self._files[''] = node
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1845
        self._flags[''] = 't'
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1846
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1847
    # Manifests outside the narrowspec should never be modified, so avoid
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1848
    # copying. This makes a noticeable difference when there are very many
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1849
    # directories outside the narrowspec. Also, it makes sense for the copy to
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1850
    # be of the same type as the original, which would not happen with the
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1851
    # super type's copy().
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1852
    def copy(self):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1853
        return self
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1854
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1855
class excludeddirmanifestctx(treemanifestctx):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1856
    """context wrapper for excludeddir - see that docstring for rationale"""
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1857
    def __init__(self, dir, node):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1858
        self._dir = dir
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1859
        self._node = node
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1860
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1861
    def read(self):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1862
        return excludeddir(self._dir, self._node)
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1863
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1864
    def write(self, *args):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1865
        raise error.ProgrammingError(
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1866
            'attempt to write manifest from excluded dir %s' % self._dir)
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1867
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1868
class excludedmanifestrevlog(manifestrevlog):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1869
    """Stand-in for excluded treemanifest revlogs.
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1870
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1871
    When narrowing is active on a treemanifest repository, we'll have
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1872
    references to directories we can't see due to the revlog being
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1873
    skipped. This class exists to conform to the manifestrevlog
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1874
    interface for those directories and proactively prevent writes to
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1875
    outside the narrowspec.
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1876
    """
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1877
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1878
    def __init__(self, dir):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1879
        self._dir = dir
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1880
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1881
    def __len__(self):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1882
        raise error.ProgrammingError(
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1883
            'attempt to get length of excluded dir %s' % self._dir)
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1884
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1885
    def rev(self, node):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1886
        raise error.ProgrammingError(
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1887
            'attempt to get rev from excluded dir %s' % self._dir)
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1888
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1889
    def linkrev(self, node):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1890
        raise error.ProgrammingError(
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1891
            'attempt to get linkrev from excluded dir %s' % self._dir)
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1892
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1893
    def node(self, rev):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1894
        raise error.ProgrammingError(
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1895
            'attempt to get node from excluded dir %s' % self._dir)
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1896
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1897
    def add(self, *args, **kwargs):
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1898
        # We should never write entries in dirlogs outside the narrow clone.
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1899
        # However, the method still gets called from writesubtree() in
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1900
        # _addtree(), so we need to handle it. We should possibly make that
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1901
        # avoid calling add() with a clean manifest (_dirty is always False
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1902
        # in excludeddir instances).
1b2fa531fd7a narrow: move excludeddir and related classes to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 37270
diff changeset
  1903
        pass