annotate mercurial/manifest.py @ 24666:3092885b5b32

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