Mercurial > hg
comparison mercurial/manifest.py @ 2956:6dddcba7596a
merge.
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Fri, 18 Aug 2006 21:17:28 -0700 |
parents | 345bac2bc4ec |
children | 1eb50c9d2649 |
comparison
equal
deleted
inserted
replaced
2955:9d1c3529ebbc | 2956:6dddcba7596a |
---|---|
1 # manifest.py - manifest revision class for mercurial | 1 # manifest.py - manifest revision class for mercurial |
2 # | 2 # |
3 # Copyright 2005 Matt Mackall <mpm@selenic.com> | 3 # Copyright 2005, 2006 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 revlog import * | 8 from revlog import * |
9 from i18n import gettext as _ | 9 from i18n import gettext as _ |
10 from demandload import * | 10 from demandload import * |
11 demandload(globals(), "array bisect struct") | 11 demandload(globals(), "array bisect struct") |
12 | |
13 class manifestdict(dict): | |
14 def __init__(self, mapping=None, flags=None): | |
15 if mapping is None: mapping = {} | |
16 if flags is None: flags = {} | |
17 dict.__init__(self, mapping) | |
18 self._flags = flags | |
19 def flags(self, f): | |
20 return self._flags.get(f, "") | |
21 def execf(self, f): | |
22 "test for executable in manifest flags" | |
23 return "x" in self.flags(f) | |
24 def linkf(self, f): | |
25 "test for symlink in manifest flags" | |
26 return "l" in self.flags(f) | |
27 def rawset(self, f, entry): | |
28 self[f] = bin(entry[:40]) | |
29 fl = entry[40:-1] | |
30 if fl: self._flags[f] = fl | |
31 def set(self, f, execf=False, linkf=False): | |
32 if linkf: self._flags[f] = "l" | |
33 elif execf: self._flags[f] = "x" | |
34 else: self._flags[f] = "" | |
35 def copy(self): | |
36 return manifestdict(dict.copy(self), dict.copy(self._flags)) | |
12 | 37 |
13 class manifest(revlog): | 38 class manifest(revlog): |
14 def __init__(self, opener, defversion=REVLOGV0): | 39 def __init__(self, opener, defversion=REVLOGV0): |
15 self.mapcache = None | 40 self.mapcache = None |
16 self.listcache = None | 41 self.listcache = None |
17 revlog.__init__(self, opener, "00manifest.i", "00manifest.d", | 42 revlog.__init__(self, opener, "00manifest.i", "00manifest.d", |
18 defversion) | 43 defversion) |
19 | 44 |
20 def read(self, node): | 45 def read(self, node): |
21 if node == nullid: return {} # don't upset local cache | 46 if node == nullid: return manifestdict() # don't upset local cache |
22 if self.mapcache and self.mapcache[0] == node: | 47 if self.mapcache and self.mapcache[0] == node: |
23 return self.mapcache[1] | 48 return self.mapcache[1] |
24 text = self.revision(node) | 49 text = self.revision(node) |
25 map = {} | |
26 flag = {} | |
27 self.listcache = array.array('c', text) | 50 self.listcache = array.array('c', text) |
28 lines = text.splitlines(1) | 51 lines = text.splitlines(1) |
52 mapping = manifestdict() | |
29 for l in lines: | 53 for l in lines: |
30 (f, n) = l.split('\0') | 54 (f, n) = l.split('\0') |
31 map[f] = bin(n[:40]) | 55 mapping.rawset(f, n) |
32 flag[f] = (n[40:-1] == "x") | 56 self.mapcache = (node, mapping) |
33 self.mapcache = (node, map, flag) | 57 return mapping |
34 return map | |
35 | |
36 def readflags(self, node): | |
37 if node == nullid: return {} # don't upset local cache | |
38 if not self.mapcache or self.mapcache[0] != node: | |
39 self.read(node) | |
40 return self.mapcache[2] | |
41 | 58 |
42 def diff(self, a, b): | 59 def diff(self, a, b): |
43 return mdiff.textdiff(str(a), str(b)) | 60 return mdiff.textdiff(str(a), str(b)) |
44 | 61 |
45 def _search(self, m, s, lo=0, hi=None): | 62 def _search(self, m, s, lo=0, hi=None): |
84 | 101 |
85 def find(self, node, f): | 102 def find(self, node, f): |
86 '''look up entry for a single file efficiently. | 103 '''look up entry for a single file efficiently. |
87 return (node, flag) pair if found, (None, None) if not.''' | 104 return (node, flag) pair if found, (None, None) if not.''' |
88 if self.mapcache and node == self.mapcache[0]: | 105 if self.mapcache and node == self.mapcache[0]: |
89 return self.mapcache[1].get(f), self.mapcache[2].get(f) | 106 return self.mapcache[1].get(f), self.mapcache[1].flags(f) |
90 text = self.revision(node) | 107 text = self.revision(node) |
91 start, end = self._search(text, f) | 108 start, end = self._search(text, f) |
92 if start == end: | 109 if start == end: |
93 return None, None | 110 return None, None |
94 l = text[start:end] | 111 l = text[start:end] |
95 f, n = l.split('\0') | 112 f, n = l.split('\0') |
96 return bin(n[:40]), n[40:-1] == 'x' | 113 return bin(n[:40]), n[40:-1] == 'x' |
97 | 114 |
98 def add(self, map, flags, transaction, link, p1=None, p2=None, | 115 def add(self, map, transaction, link, p1=None, p2=None, |
99 changed=None): | 116 changed=None): |
100 # apply the changes collected during the bisect loop to our addlist | 117 # apply the changes collected during the bisect loop to our addlist |
101 # return a delta suitable for addrevision | 118 # return a delta suitable for addrevision |
102 def addlistdelta(addlist, x): | 119 def addlistdelta(addlist, x): |
103 # start from the bottom up | 120 # start from the bottom up |
121 files = map.keys() | 138 files = map.keys() |
122 files.sort() | 139 files.sort() |
123 | 140 |
124 # if this is changed to support newlines in filenames, | 141 # if this is changed to support newlines in filenames, |
125 # be sure to check the templates/ dir again (especially *-raw.tmpl) | 142 # be sure to check the templates/ dir again (especially *-raw.tmpl) |
126 text = ["%s\000%s%s\n" % | 143 text = ["%s\000%s%s\n" % (f, hex(map[f]), map.flags(f)) for f in files] |
127 (f, hex(map[f]), flags[f] and "x" or '') | |
128 for f in files] | |
129 self.listcache = array.array('c', "".join(text)) | 144 self.listcache = array.array('c', "".join(text)) |
130 cachedelta = None | 145 cachedelta = None |
131 else: | 146 else: |
132 addlist = self.listcache | 147 addlist = self.listcache |
133 | 148 |
149 for w in work: | 164 for w in work: |
150 f = w[0] | 165 f = w[0] |
151 # bs will either be the index of the item or the insert point | 166 # bs will either be the index of the item or the insert point |
152 start, end = self._search(addbuf, f, start) | 167 start, end = self._search(addbuf, f, start) |
153 if w[1] == 0: | 168 if w[1] == 0: |
154 l = "%s\000%s%s\n" % (f, hex(map[f]), | 169 l = "%s\000%s%s\n" % (f, hex(map[f]), map.flags(f)) |
155 flags[f] and "x" or '') | |
156 else: | 170 else: |
157 l = "" | 171 l = "" |
158 if start == end and w[1] == 1: | 172 if start == end and w[1] == 1: |
159 # item we want to delete was not found, error out | 173 # item we want to delete was not found, error out |
160 raise AssertionError( | 174 raise AssertionError( |
181 cachedelta = None | 195 cachedelta = None |
182 self.listcache = addlist | 196 self.listcache = addlist |
183 | 197 |
184 n = self.addrevision(buffer(self.listcache), transaction, link, p1, \ | 198 n = self.addrevision(buffer(self.listcache), transaction, link, p1, \ |
185 p2, cachedelta) | 199 p2, cachedelta) |
186 self.mapcache = (n, map, flags) | 200 self.mapcache = (n, map) |
187 | 201 |
188 return n | 202 return n |