comparison mercurial/dirstate.py @ 1584:b3e94785ab69

merge with crew
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Sun, 11 Dec 2005 15:38:42 -0800
parents 34579a67fa71
children 84e9b3484ff6
comparison
equal deleted inserted replaced
1583:32a4e6802864 1584:b3e94785ab69
11 from node import * 11 from node import *
12 from i18n import gettext as _ 12 from i18n import gettext as _
13 from demandload import * 13 from demandload import *
14 demandload(globals(), "time bisect stat util re errno") 14 demandload(globals(), "time bisect stat util re errno")
15 15
16 class dirstate: 16 class dirstate(object):
17 def __init__(self, opener, ui, root): 17 def __init__(self, opener, ui, root):
18 self.opener = opener 18 self.opener = opener
19 self.root = root 19 self.root = root
20 self.dirty = 0 20 self.dirty = 0
21 self.ui = ui 21 self.ui = ui
99 99
100 def __getitem__(self, key): 100 def __getitem__(self, key):
101 try: 101 try:
102 return self.map[key] 102 return self.map[key]
103 except TypeError: 103 except TypeError:
104 self.read() 104 self.lazyread()
105 return self[key] 105 return self[key]
106 106
107 def __contains__(self, key): 107 def __contains__(self, key):
108 if not self.map: self.read() 108 self.lazyread()
109 return key in self.map 109 return key in self.map
110 110
111 def parents(self): 111 def parents(self):
112 if not self.pl: 112 self.lazyread()
113 self.read()
114 return self.pl 113 return self.pl
115 114
116 def markdirty(self): 115 def markdirty(self):
117 if not self.dirty: 116 if not self.dirty:
118 self.dirty = 1 117 self.dirty = 1
119 118
120 def setparents(self, p1, p2=nullid): 119 def setparents(self, p1, p2=nullid):
121 if not self.pl: 120 self.lazyread()
122 self.read()
123 self.markdirty() 121 self.markdirty()
124 self.pl = p1, p2 122 self.pl = p1, p2
125 123
126 def state(self, key): 124 def state(self, key):
127 try: 125 try:
128 return self[key][0] 126 return self[key][0]
129 except KeyError: 127 except KeyError:
130 return "?" 128 return "?"
131 129
130 def lazyread(self):
131 if self.map is None:
132 self.read()
133
132 def read(self): 134 def read(self):
133 if self.map is not None: return self.map
134
135 self.map = {} 135 self.map = {}
136 self.pl = [nullid, nullid] 136 self.pl = [nullid, nullid]
137 try: 137 try:
138 st = self.opener("dirstate").read() 138 st = self.opener("dirstate").read()
139 if not st: return 139 if not st: return
152 self.copies[f] = c 152 self.copies[f] = c
153 self.map[f] = e[:4] 153 self.map[f] = e[:4]
154 pos += l 154 pos += l
155 155
156 def copy(self, source, dest): 156 def copy(self, source, dest):
157 self.read() 157 self.lazyread()
158 self.markdirty() 158 self.markdirty()
159 self.copies[dest] = source 159 self.copies[dest] = source
160 160
161 def copied(self, file): 161 def copied(self, file):
162 return self.copies.get(file, None) 162 return self.copies.get(file, None)
167 m needs merging 167 m needs merging
168 r marked for removal 168 r marked for removal
169 a marked for addition''' 169 a marked for addition'''
170 170
171 if not files: return 171 if not files: return
172 self.read() 172 self.lazyread()
173 self.markdirty() 173 self.markdirty()
174 for f in files: 174 for f in files:
175 if state == "r": 175 if state == "r":
176 self.map[f] = ('r', 0, 0, 0) 176 self.map[f] = ('r', 0, 0, 0)
177 else: 177 else:
178 s = os.lstat(os.path.join(self.root, f)) 178 s = os.lstat(self.wjoin(f))
179 st_size = kw.get('st_size', s.st_size) 179 st_size = kw.get('st_size', s.st_size)
180 st_mtime = kw.get('st_mtime', s.st_mtime) 180 st_mtime = kw.get('st_mtime', s.st_mtime)
181 self.map[f] = (state, s.st_mode, st_size, st_mtime) 181 self.map[f] = (state, s.st_mode, st_size, st_mtime)
182 if self.copies.has_key(f): 182 if self.copies.has_key(f):
183 del self.copies[f] 183 del self.copies[f]
184 184
185 def forget(self, files): 185 def forget(self, files):
186 if not files: return 186 if not files: return
187 self.read() 187 self.lazyread()
188 self.markdirty() 188 self.markdirty()
189 for f in files: 189 for f in files:
190 try: 190 try:
191 del self.map[f] 191 del self.map[f]
192 except KeyError: 192 except KeyError:
196 def clear(self): 196 def clear(self):
197 self.map = {} 197 self.map = {}
198 self.markdirty() 198 self.markdirty()
199 199
200 def write(self): 200 def write(self):
201 st = self.opener("dirstate", "w") 201 st = self.opener("dirstate", "w", atomic=True)
202 st.write("".join(self.pl)) 202 st.write("".join(self.pl))
203 for f, e in self.map.items(): 203 for f, e in self.map.items():
204 c = self.copied(f) 204 c = self.copied(f)
205 if c: 205 if c:
206 f = f + "\0" + c 206 f = f + "\0" + c
211 def filterfiles(self, files): 211 def filterfiles(self, files):
212 ret = {} 212 ret = {}
213 unknown = [] 213 unknown = []
214 214
215 for x in files: 215 for x in files:
216 if x is '.': 216 if x == '.':
217 return self.map.copy() 217 return self.map.copy()
218 if x not in self.map: 218 if x not in self.map:
219 unknown.append(x) 219 unknown.append(x)
220 else: 220 else:
221 ret[x] = self.map[x] 221 ret[x] = self.map[x]
239 else: 239 else:
240 break 240 break
241 bs += 1 241 bs += 1
242 return ret 242 return ret
243 243
244 def supported_type(self, f, st, verbose=True): 244 def supported_type(self, f, st, verbose=False):
245 if stat.S_ISREG(st.st_mode): 245 if stat.S_ISREG(st.st_mode):
246 return True 246 return True
247 if verbose: 247 if verbose:
248 kind = 'unknown' 248 kind = 'unknown'
249 if stat.S_ISCHR(st.st_mode): kind = _('character device') 249 if stat.S_ISCHR(st.st_mode): kind = _('character device')
256 util.pathto(self.getcwd(), f), 256 util.pathto(self.getcwd(), f),
257 kind)) 257 kind))
258 return False 258 return False
259 259
260 def statwalk(self, files=None, match=util.always, dc=None): 260 def statwalk(self, files=None, match=util.always, dc=None):
261 self.read() 261 self.lazyread()
262 262
263 # walk all files by default 263 # walk all files by default
264 if not files: 264 if not files:
265 files = [self.root] 265 files = [self.root]
266 if not dc: 266 if not dc:
294 # directly by this function, but might be modified by your statmatch call. 294 # directly by this function, but might be modified by your statmatch call.
295 # 295 #
296 def walkhelper(self, files, statmatch, dc): 296 def walkhelper(self, files, statmatch, dc):
297 # recursion free walker, faster than os.walk. 297 # recursion free walker, faster than os.walk.
298 def findfiles(s): 298 def findfiles(s):
299 retfiles = []
300 work = [s] 299 work = [s]
301 while work: 300 while work:
302 top = work.pop() 301 top = work.pop()
303 names = os.listdir(top) 302 names = os.listdir(top)
304 names.sort() 303 names.sort()
305 # nd is the top of the repository dir tree 304 # nd is the top of the repository dir tree
306 nd = util.normpath(top[len(self.root) + 1:]) 305 nd = util.normpath(top[len(self.root) + 1:])
307 if nd == '.': nd = '' 306 if nd == '.': nd = ''
308 for f in names: 307 for f in names:
309 np = os.path.join(nd, f) 308 np = util.pconvert(os.path.join(nd, f))
310 if seen(np): 309 if seen(np):
311 continue 310 continue
312 p = os.path.join(top, f) 311 p = os.path.join(top, f)
313 # don't trip over symlinks 312 # don't trip over symlinks
314 st = os.lstat(p) 313 st = os.lstat(p)
315 if stat.S_ISDIR(st.st_mode): 314 if stat.S_ISDIR(st.st_mode):
316 ds = os.path.join(nd, f +'/') 315 ds = os.path.join(nd, f +'/')
317 if statmatch(ds, st): 316 if statmatch(ds, st):
318 work.append(p) 317 work.append(p)
319 if statmatch(np, st) and np in dc: 318 if statmatch(np, st) and np in dc:
320 yield 'm', util.pconvert(np), st 319 yield 'm', np, st
321 elif statmatch(np, st): 320 elif statmatch(np, st):
322 if self.supported_type(np, st): 321 if self.supported_type(np, st):
323 yield 'f', util.pconvert(np), st 322 yield 'f', np, st
324 elif np in dc: 323 elif np in dc:
325 yield 'm', util.pconvert(np), st 324 yield 'm', np, st
326 325
327 known = {'.hg': 1} 326 known = {'.hg': 1}
328 def seen(fn): 327 def seen(fn):
329 if fn in known: return True 328 if fn in known: return True
330 known[fn] = 1 329 known[fn] = 1
331 330
332 # step one, find all files that match our criteria 331 # step one, find all files that match our criteria
333 files.sort() 332 files.sort()
334 for ff in util.unique(files): 333 for ff in util.unique(files):
335 f = os.path.join(self.root, ff) 334 f = self.wjoin(ff)
336 try: 335 try:
337 st = os.lstat(f) 336 st = os.lstat(f)
338 except OSError, inst: 337 except OSError, inst:
339 if ff not in dc: self.ui.warn('%s: %s\n' % ( 338 nf = util.normpath(ff)
340 util.pathto(self.getcwd(), ff), 339 found = False
341 inst.strerror)) 340 for fn in dc:
341 if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'):
342 found = True
343 break
344 if not found:
345 self.ui.warn('%s: %s\n' % (
346 util.pathto(self.getcwd(), ff),
347 inst.strerror))
342 continue 348 continue
343 if stat.S_ISDIR(st.st_mode): 349 if stat.S_ISDIR(st.st_mode):
344 cmp1 = (lambda x, y: cmp(x[1], y[1])) 350 cmp1 = (lambda x, y: cmp(x[1], y[1]))
345 sorted = [ x for x in findfiles(f) ] 351 sorted = [ x for x in findfiles(f) ]
346 sorted.sort(cmp1) 352 sorted.sort(cmp1)
350 ff = util.normpath(ff) 356 ff = util.normpath(ff)
351 if seen(ff): 357 if seen(ff):
352 continue 358 continue
353 self.blockignore = True 359 self.blockignore = True
354 if statmatch(ff, st): 360 if statmatch(ff, st):
355 if self.supported_type(ff, st): 361 if self.supported_type(ff, st, verbose=True):
356 yield 'f', ff, st 362 yield 'f', ff, st
357 elif ff in dc: 363 elif ff in dc:
358 yield 'm', ff, st 364 yield 'm', ff, st
359 self.blockignore = False 365 self.blockignore = False
360 366
378 continue 384 continue
379 if src == 'm': 385 if src == 'm':
380 nonexistent = True 386 nonexistent = True
381 if not st: 387 if not st:
382 try: 388 try:
383 f = os.path.join(self.root, fn) 389 f = self.wjoin(fn)
384 st = os.lstat(f) 390 st = os.lstat(f)
385 except OSError, inst: 391 except OSError, inst:
386 if inst.errno != errno.ENOENT: 392 if inst.errno != errno.ENOENT:
387 raise 393 raise
388 st = None 394 st = None