3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
4 # |
4 # |
5 # This software may be used and distributed according to the terms |
5 # This software may be used and distributed according to the terms |
6 # of the GNU General Public License, incorporated herein by reference. |
6 # of the GNU General Public License, incorporated herein by reference. |
7 |
7 |
8 from node import bin, hex, nullid |
|
9 from revlog import revlog |
|
10 from i18n import _ |
8 from i18n import _ |
11 import array, struct, mdiff, parsers, util, error |
9 import array, struct, mdiff, parsers, util, error, revlog |
12 |
10 |
13 class manifestdict(dict): |
11 class manifestdict(dict): |
14 def __init__(self, mapping=None, flags=None): |
12 def __init__(self, mapping=None, flags=None): |
15 if mapping is None: mapping = {} |
13 if mapping is None: mapping = {} |
16 if flags is None: flags = {} |
14 if flags is None: flags = {} |
21 def set(self, f, flags): |
19 def set(self, f, flags): |
22 self._flags[f] = flags |
20 self._flags[f] = flags |
23 def copy(self): |
21 def copy(self): |
24 return manifestdict(dict.copy(self), dict.copy(self._flags)) |
22 return manifestdict(dict.copy(self), dict.copy(self._flags)) |
25 |
23 |
26 class manifest(revlog): |
24 class manifest(revlog.revlog): |
27 def __init__(self, opener): |
25 def __init__(self, opener): |
28 self.mapcache = None |
26 self.mapcache = None |
29 self.listcache = None |
27 self.listcache = None |
30 revlog.__init__(self, opener, "00manifest.i") |
28 revlog.revlog.__init__(self, opener, "00manifest.i") |
31 |
29 |
32 def parse(self, lines): |
30 def parse(self, lines): |
33 mfdict = manifestdict() |
31 mfdict = manifestdict() |
34 parsers.parse_manifest(mfdict, mfdict._flags, lines) |
32 parsers.parse_manifest(mfdict, mfdict._flags, lines) |
35 return mfdict |
33 return mfdict |
37 def readdelta(self, node): |
35 def readdelta(self, node): |
38 r = self.rev(node) |
36 r = self.rev(node) |
39 return self.parse(mdiff.patchtext(self.revdiff(r - 1, r))) |
37 return self.parse(mdiff.patchtext(self.revdiff(r - 1, r))) |
40 |
38 |
41 def read(self, node): |
39 def read(self, node): |
42 if node == nullid: return manifestdict() # don't upset local cache |
40 if node == revlog.nullid: |
|
41 return manifestdict() # don't upset local cache |
43 if self.mapcache and self.mapcache[0] == node: |
42 if self.mapcache and self.mapcache[0] == node: |
44 return self.mapcache[1] |
43 return self.mapcache[1] |
45 text = self.revision(node) |
44 text = self.revision(node) |
46 self.listcache = array.array('c', text) |
45 self.listcache = array.array('c', text) |
47 mapping = self.parse(text) |
46 mapping = self.parse(text) |
99 start, end = self._search(text, f) |
98 start, end = self._search(text, f) |
100 if start == end: |
99 if start == end: |
101 return None, None |
100 return None, None |
102 l = text[start:end] |
101 l = text[start:end] |
103 f, n = l.split('\0') |
102 f, n = l.split('\0') |
104 return bin(n[:40]), n[40:-1] |
103 return revlog.bin(n[:40]), n[40:-1] |
105 |
104 |
106 def add(self, map, transaction, link, p1=None, p2=None, |
105 def add(self, map, transaction, link, p1=None, p2=None, |
107 changed=None): |
106 changed=None): |
108 # apply the changes collected during the bisect loop to our addlist |
107 # apply the changes collected during the bisect loop to our addlist |
109 # return a delta suitable for addrevision |
108 # return a delta suitable for addrevision |
134 files = util.sort(map) |
133 files = util.sort(map) |
135 checkforbidden(files) |
134 checkforbidden(files) |
136 |
135 |
137 # if this is changed to support newlines in filenames, |
136 # if this is changed to support newlines in filenames, |
138 # be sure to check the templates/ dir again (especially *-raw.tmpl) |
137 # be sure to check the templates/ dir again (especially *-raw.tmpl) |
139 text = ["%s\000%s%s\n" % (f, hex(map[f]), map.flags(f)) |
138 hex, flags = revlog.hex, map.flags |
|
139 text = ["%s\000%s%s\n" % (f, hex(map[f]), flags(f)) |
140 for f in files] |
140 for f in files] |
141 self.listcache = array.array('c', "".join(text)) |
141 self.listcache = array.array('c', "".join(text)) |
142 cachedelta = None |
142 cachedelta = None |
143 else: |
143 else: |
144 addlist = self.listcache |
144 addlist = self.listcache |
162 for w in work: |
162 for w in work: |
163 f = w[0] |
163 f = w[0] |
164 # bs will either be the index of the item or the insert point |
164 # bs will either be the index of the item or the insert point |
165 start, end = self._search(addbuf, f, start) |
165 start, end = self._search(addbuf, f, start) |
166 if w[1] == 0: |
166 if w[1] == 0: |
167 l = "%s\000%s%s\n" % (f, hex(map[f]), map.flags(f)) |
167 l = "%s\000%s%s\n" % (f, revlog.hex(map[f]), map.flags(f)) |
168 else: |
168 else: |
169 l = "" |
169 l = "" |
170 if start == end and w[1] == 1: |
170 if start == end and w[1] == 1: |
171 # item we want to delete was not found, error out |
171 # item we want to delete was not found, error out |
172 raise AssertionError( |
172 raise AssertionError( |