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: |