mercurial/store.py
changeset 47877 2174f54aab18
parent 47785 59bc92a7c60f
child 48875 6000f5b25c9b
equal deleted inserted replaced
47876:517a2c1cb788 47877:2174f54aab18
   470 
   470 
   471     def join(self, f):
   471     def join(self, f):
   472         return self.path + b'/' + encodedir(f)
   472         return self.path + b'/' + encodedir(f)
   473 
   473 
   474     def _walk(self, relpath, recurse):
   474     def _walk(self, relpath, recurse):
   475         '''yields (unencoded, encoded, size)'''
   475         '''yields (revlog_type, unencoded, size)'''
   476         path = self.path
   476         path = self.path
   477         if relpath:
   477         if relpath:
   478             path += b'/' + relpath
   478             path += b'/' + relpath
   479         striplen = len(self.path) + 1
   479         striplen = len(self.path) + 1
   480         l = []
   480         l = []
   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):