Mercurial > public > mercurial-scm > hg-stable
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: |