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