486 for f, kind, st in readdir(p, stat=True): |
486 for f, kind, st in readdir(p, stat=True): |
487 fp = p + b'/' + f |
487 fp = p + b'/' + f |
488 rl_type = is_revlog(f, kind, st) |
488 rl_type = is_revlog(f, kind, st) |
489 if rl_type is not None: |
489 if rl_type is not None: |
490 n = util.pconvert(fp[striplen:]) |
490 n = util.pconvert(fp[striplen:]) |
491 l.append((rl_type, decodedir(n), n, st.st_size)) |
491 l.append((rl_type, decodedir(n), st.st_size)) |
492 elif kind == stat.S_IFDIR and recurse: |
492 elif kind == stat.S_IFDIR and recurse: |
493 visit.append(fp) |
493 visit.append(fp) |
494 l.sort() |
494 l.sort() |
495 return l |
495 return l |
496 |
496 |
503 |
503 |
504 def manifestlog(self, repo, storenarrowmatch): |
504 def manifestlog(self, repo, storenarrowmatch): |
505 rootstore = manifest.manifestrevlog(repo.nodeconstants, self.vfs) |
505 rootstore = manifest.manifestrevlog(repo.nodeconstants, self.vfs) |
506 return manifest.manifestlog(self.vfs, repo, rootstore, storenarrowmatch) |
506 return manifest.manifestlog(self.vfs, repo, rootstore, storenarrowmatch) |
507 |
507 |
508 def datafiles(self, matcher=None): |
508 def datafiles(self, matcher=None, undecodable=None): |
|
509 """Like walk, but excluding the changelog and root manifest. |
|
510 |
|
511 When [undecodable] is None, revlogs names that can't be |
|
512 decoded cause an exception. When it is provided, it should |
|
513 be a list and the filenames that can't be decoded are added |
|
514 to it instead. This is very rarely needed.""" |
509 files = self._walk(b'data', True) + self._walk(b'meta', True) |
515 files = self._walk(b'data', True) + self._walk(b'meta', True) |
510 for (t, u, e, s) in files: |
516 for (t, u, s) in files: |
511 yield (FILEFLAGS_FILELOG | t, u, e, s) |
517 yield (FILEFLAGS_FILELOG | t, u, s) |
512 |
518 |
513 def topfiles(self): |
519 def topfiles(self): |
514 # yield manifest before changelog |
520 # yield manifest before changelog |
515 files = reversed(self._walk(b'', False)) |
521 files = reversed(self._walk(b'', False)) |
516 for (t, u, e, s) in files: |
522 for (t, u, s) in files: |
517 if u.startswith(b'00changelog'): |
523 if u.startswith(b'00changelog'): |
518 yield (FILEFLAGS_CHANGELOG | t, u, e, s) |
524 yield (FILEFLAGS_CHANGELOG | t, u, s) |
519 elif u.startswith(b'00manifest'): |
525 elif u.startswith(b'00manifest'): |
520 yield (FILEFLAGS_MANIFESTLOG | t, u, e, s) |
526 yield (FILEFLAGS_MANIFESTLOG | t, u, s) |
521 else: |
527 else: |
522 yield (FILETYPE_OTHER | t, u, e, s) |
528 yield (FILETYPE_OTHER | t, u, s) |
523 |
529 |
524 def walk(self, matcher=None): |
530 def walk(self, matcher=None): |
525 """return file related to data storage (ie: revlogs) |
531 """return file related to data storage (ie: revlogs) |
526 |
532 |
527 yields (file_type, unencoded, encoded, size) |
533 yields (file_type, unencoded, size) |
528 |
534 |
529 if a matcher is passed, storage files of only those tracked paths |
535 if a matcher is passed, storage files of only those tracked paths |
530 are passed with matches the matcher |
536 are passed with matches the matcher |
531 """ |
537 """ |
532 # yield data files first |
538 # yield data files first |
572 # note: topfiles would also need a decode phase. It is just that in |
578 # note: topfiles would also need a decode phase. It is just that in |
573 # practice we do not have any file outside of `data/` that needs encoding. |
579 # practice we do not have any file outside of `data/` that needs encoding. |
574 # However that might change so we should probably add a test and encoding |
580 # However that might change so we should probably add a test and encoding |
575 # decoding for it too. see issue6548 |
581 # decoding for it too. see issue6548 |
576 |
582 |
577 def datafiles(self, matcher=None): |
583 def datafiles(self, matcher=None, undecodable=None): |
578 for t, a, b, size in super(encodedstore, self).datafiles(): |
584 for t, f1, size in super(encodedstore, self).datafiles(): |
579 try: |
585 try: |
580 a = decodefilename(a) |
586 f2 = decodefilename(f1) |
581 except KeyError: |
587 except KeyError: |
582 a = None |
588 if undecodable is None: |
583 if a is not None and not _matchtrackedpath(a, matcher): |
589 msg = _(b'undecodable revlog name %s') % f1 |
|
590 raise error.StorageError(msg) |
|
591 else: |
|
592 undecodable.append(f1) |
|
593 continue |
|
594 if not _matchtrackedpath(f2, matcher): |
584 continue |
595 continue |
585 yield t, a, b, size |
596 yield t, f2, size |
586 |
597 |
587 def join(self, f): |
598 def join(self, f): |
588 return self.path + b'/' + encodefilename(f) |
599 return self.path + b'/' + encodefilename(f) |
589 |
600 |
590 def copylist(self): |
601 def copylist(self): |
768 return self.pathsep + self.encode(f) |
779 return self.pathsep + self.encode(f) |
769 |
780 |
770 def getsize(self, path): |
781 def getsize(self, path): |
771 return self.rawvfs.stat(path).st_size |
782 return self.rawvfs.stat(path).st_size |
772 |
783 |
773 def datafiles(self, matcher=None): |
784 def datafiles(self, matcher=None, undecodable=None): |
774 for f in sorted(self.fncache): |
785 for f in sorted(self.fncache): |
775 if not _matchtrackedpath(f, matcher): |
786 if not _matchtrackedpath(f, matcher): |
776 continue |
787 continue |
777 ef = self.encode(f) |
788 ef = self.encode(f) |
778 try: |
789 try: |
779 t = revlog_type(f) |
790 t = revlog_type(f) |
780 assert t is not None, f |
791 assert t is not None, f |
781 t |= FILEFLAGS_FILELOG |
792 t |= FILEFLAGS_FILELOG |
782 yield t, f, ef, self.getsize(ef) |
793 yield t, f, self.getsize(ef) |
783 except OSError as err: |
794 except OSError as err: |
784 if err.errno != errno.ENOENT: |
795 if err.errno != errno.ENOENT: |
785 raise |
796 raise |
786 |
797 |
787 def copylist(self): |
798 def copylist(self): |