comparison mercurial/dirstate.py @ 1487:2bc6cd62a29c

fix handling of files of unsupported type in the walk code if a file was of unsupported type, it was considered as 'seen' while walking. this way it was possible to have file in the dirstate not yielded by the walk function.
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Wed, 02 Nov 2005 15:46:31 -0800
parents 17e8c70fb670
children 08c7851969cc
comparison
equal deleted inserted replaced
1486:d7809d6e9db2 1487:2bc6cd62a29c
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):
245 if stat.S_ISREG(st.st_mode):
246 return True
247 if verbose:
248 kind = 'unknown'
249 if stat.S_ISCHR(st.st_mode): kind = _('character device')
250 elif stat.S_ISBLK(st.st_mode): kind = _('block device')
251 elif stat.S_ISFIFO(st.st_mode): kind = _('fifo')
252 elif stat.S_ISLNK(st.st_mode): kind = _('symbolic link')
253 elif stat.S_ISSOCK(st.st_mode): kind = _('socket')
254 elif stat.S_ISDIR(st.st_mode): kind = _('directory')
255 self.ui.warn(_('%s: unsupported file type (type is %s)\n') % (
256 util.pathto(self.getcwd(), f),
257 kind))
258 return False
259
244 def statwalk(self, files=None, match=util.always, dc=None): 260 def statwalk(self, files=None, match=util.always, dc=None):
245 self.read() 261 self.read()
246 262
247 # walk all files by default 263 # walk all files by default
248 if not files: 264 if not files:
276 # 292 #
277 # dc is an optional arg for the current dirstate. dc is not modified 293 # dc is an optional arg for the current dirstate. dc is not modified
278 # 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.
279 # 295 #
280 def walkhelper(self, files, statmatch, dc): 296 def walkhelper(self, files, statmatch, dc):
281 def supported_type(f, st):
282 if stat.S_ISREG(st.st_mode):
283 return True
284 else:
285 kind = 'unknown'
286 if stat.S_ISCHR(st.st_mode): kind = _('character device')
287 elif stat.S_ISBLK(st.st_mode): kind = _('block device')
288 elif stat.S_ISFIFO(st.st_mode): kind = _('fifo')
289 elif stat.S_ISLNK(st.st_mode): kind = _('symbolic link')
290 elif stat.S_ISSOCK(st.st_mode): kind = _('socket')
291 elif stat.S_ISDIR(st.st_mode): kind = _('directory')
292 self.ui.warn(_('%s: unsupported file type (type is %s)\n') % (
293 util.pathto(self.getcwd(), f),
294 kind))
295 return False
296
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 = [] 299 retfiles = []
300 work = [s] 300 work = [s]
301 while work: 301 while work:
314 st = os.lstat(p) 314 st = os.lstat(p)
315 if stat.S_ISDIR(st.st_mode): 315 if stat.S_ISDIR(st.st_mode):
316 ds = os.path.join(nd, f +'/') 316 ds = os.path.join(nd, f +'/')
317 if statmatch(ds, st): 317 if statmatch(ds, st):
318 work.append(p) 318 work.append(p)
319 elif statmatch(np, st) and supported_type(np, st): 319 if statmatch(np, st) and np in dc:
320 yield util.pconvert(np), st 320 yield 'm', util.pconvert(np), st
321 321 elif statmatch(np, st):
322 if self.supported_type(np, st):
323 yield 'f', util.pconvert(np), st
324 elif np in dc:
325 yield 'm', util.pconvert(np), st
322 326
323 known = {'.hg': 1} 327 known = {'.hg': 1}
324 def seen(fn): 328 def seen(fn):
325 if fn in known: return True 329 if fn in known: return True
326 known[fn] = 1 330 known[fn] = 1
335 if ff not in dc: self.ui.warn('%s: %s\n' % ( 339 if ff not in dc: self.ui.warn('%s: %s\n' % (
336 util.pathto(self.getcwd(), ff), 340 util.pathto(self.getcwd(), ff),
337 inst.strerror)) 341 inst.strerror))
338 continue 342 continue
339 if stat.S_ISDIR(st.st_mode): 343 if stat.S_ISDIR(st.st_mode):
340 cmp0 = (lambda x, y: cmp(x[0], y[0])) 344 cmp1 = (lambda x, y: cmp(x[1], y[1]))
341 sorted = [ x for x in findfiles(f) ] 345 sorted = [ x for x in findfiles(f) ]
342 sorted.sort(cmp0) 346 sorted.sort(cmp1)
343 for fl, stl in sorted: 347 for e in sorted:
344 yield 'f', fl, stl 348 yield e
345 else: 349 else:
346 ff = util.normpath(ff) 350 ff = util.normpath(ff)
347 if seen(ff): 351 if seen(ff):
348 continue 352 continue
349 found = False
350 self.blockignore = True 353 self.blockignore = True
351 if statmatch(ff, st) and supported_type(ff, st): 354 if statmatch(ff, st):
352 found = True 355 if self.supported_type(ff, st):
356 yield 'f', ff, st
357 elif ff in dc:
358 yield 'm', ff, st
353 self.blockignore = False 359 self.blockignore = False
354 if found:
355 yield 'f', ff, st
356 360
357 # step two run through anything left in the dc hash and yield 361 # step two run through anything left in the dc hash and yield
358 # if we haven't already seen it 362 # if we haven't already seen it
359 ks = dc.keys() 363 ks = dc.keys()
360 ks.sort() 364 ks.sort()
371 type, mode, size, time = self[fn] 375 type, mode, size, time = self[fn]
372 except KeyError: 376 except KeyError:
373 unknown.append(fn) 377 unknown.append(fn)
374 continue 378 continue
375 if src == 'm': 379 if src == 'm':
376 try: 380 nonexistent = True
377 st = os.stat(fn) 381 if not st:
378 except OSError, inst: 382 try:
383 st = os.lstat(fn)
384 except OSError, inst:
385 if inst.errno != errno.ENOENT:
386 raise
387 st = None
388 # We need to re-check that it is a valid file
389 if st and self.supported_type(fn, st):
390 nonexistent = False
379 # XXX: what to do with file no longer present in the fs 391 # XXX: what to do with file no longer present in the fs
380 # who are not removed in the dirstate ? 392 # who are not removed in the dirstate ?
381 if inst.errno != errno.ENOENT: 393 if nonexistent:
382 raise
383 deleted.append(fn) 394 deleted.append(fn)
384 continue 395 continue
385 # check the common case first 396 # check the common case first
386 if type == 'n': 397 if type == 'n':
387 if not st: 398 if not st: