comparison mercurial/util.py @ 15709:a1f4bd47d18e

icasefs: retry directory scan once for already invalidated cache some hg operation (e.g.: qpush) create new files after first dirstate.walk()-ing, and it invalidates _fspathcache for fspath(). then, fspath() will fail to look up specified name in _fspathcache. this causes case preservation breaking, because parts of already normcase()-ed path are used as result at that time. in this case, file creation and writing out should be done before fspath() invocation, so the second invocation of os.listdir() has not so much impact on runtime performance.
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Fri, 16 Dec 2011 21:09:40 +0900
parents 7b7f03502b5a
children f63e40047372
comparison
equal deleted inserted replaced
15708:309e49491253 15709:a1f4bd47d18e
628 name = name[l:] 628 name = name[l:]
629 629
630 if not os.path.lexists(os.path.join(root, name)): 630 if not os.path.lexists(os.path.join(root, name)):
631 return None 631 return None
632 632
633 def find(p, contents):
634 lenp = len(p)
635 for n in contents:
636 if lenp == len(n) and normcase(n) == p:
637 return n
638 return None
639
633 seps = os.sep 640 seps = os.sep
634 if os.altsep: 641 if os.altsep:
635 seps = seps + os.altsep 642 seps = seps + os.altsep
636 # Protect backslashes. This gets silly very quickly. 643 # Protect backslashes. This gets silly very quickly.
637 seps.replace('\\','\\\\') 644 seps.replace('\\','\\\\')
641 for part, sep in pattern.findall(name): 648 for part, sep in pattern.findall(name):
642 if sep: 649 if sep:
643 result.append(sep) 650 result.append(sep)
644 continue 651 continue
645 652
646 if dir not in _fspathcache: 653 contents = _fspathcache.get(dir, None)
647 _fspathcache[dir] = os.listdir(dir) 654 if contents is None:
648 contents = _fspathcache[dir] 655 contents = os.listdir(dir)
649 656 _fspathcache[dir] = contents
650 lenp = len(part) 657
651 for n in contents: 658 found = find(part, contents)
652 if lenp == len(n) and normcase(n) == part: 659 if not found:
653 result.append(n) 660 # retry once for the corner case: add files after dir walking
654 break 661 contents = os.listdir(dir)
655 else: 662 _fspathcache[dir] = contents
656 # Cannot happen, as the file exists! 663 found = find(part, contents)
657 result.append(part) 664
665 result.append(found or part)
658 dir = os.path.join(dir, part) 666 dir = os.path.join(dir, part)
659 667
660 return ''.join(result) 668 return ''.join(result)
661 669
662 def checknlink(testfile): 670 def checknlink(testfile):