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