mercurial/store.py
changeset 50638 8fc10bfd9887
parent 50632 786443bd3bc1
child 50639 5e60abf811f3
equal deleted inserted replaced
50637:32837c7e2e4b 50638:8fc10bfd9887
     8 import collections
     8 import collections
     9 import functools
     9 import functools
    10 import os
    10 import os
    11 import re
    11 import re
    12 import stat
    12 import stat
    13 from typing import Generator
    13 from typing import Generator, List
    14 
    14 
    15 from .i18n import _
    15 from .i18n import _
    16 from .pycompat import getattr
    16 from .pycompat import getattr
    17 from .thirdparty import attr
    17 from .thirdparty import attr
    18 from .node import hex
    18 from .node import hex
   457 FILETYPE_FILELOG_MAIN = FILEFLAGS_FILELOG | FILEFLAGS_REVLOG_MAIN
   457 FILETYPE_FILELOG_MAIN = FILEFLAGS_FILELOG | FILEFLAGS_REVLOG_MAIN
   458 FILETYPE_FILELOG_OTHER = FILEFLAGS_FILELOG | FILEFLAGS_REVLOG_OTHER
   458 FILETYPE_FILELOG_OTHER = FILEFLAGS_FILELOG | FILEFLAGS_REVLOG_OTHER
   459 FILETYPE_OTHER = FILEFLAGS_OTHER
   459 FILETYPE_OTHER = FILEFLAGS_OTHER
   460 
   460 
   461 
   461 
       
   462 @attr.s(slots=True)
       
   463 class StoreFile:
       
   464     """a file matching a store entry"""
       
   465 
       
   466     unencoded_path = attr.ib()
       
   467     _file_size = attr.ib(default=None)
       
   468     is_volatile = attr.ib(default=False)
       
   469 
       
   470     def file_size(self, vfs):
       
   471         if self._file_size is None:
       
   472             try:
       
   473                 self._file_size = vfs.stat(self.unencoded_path).st_size
       
   474             except FileNotFoundError:
       
   475                 self._file_size = 0
       
   476         return self._file_size
       
   477 
       
   478 
   462 @attr.s(slots=True, init=False)
   479 @attr.s(slots=True, init=False)
   463 class BaseStoreEntry:
   480 class BaseStoreEntry:
   464     """An entry in the store
   481     """An entry in the store
   465 
   482 
   466     This is returned by `store.walk` and represent some data in the store."""
   483     This is returned by `store.walk` and represent some data in the store."""
       
   484 
       
   485     def files(self) -> List[StoreFile]:
       
   486         raise NotImplementedError
   467 
   487 
   468 
   488 
   469 @attr.s(slots=True, init=False)
   489 @attr.s(slots=True, init=False)
   470 class SimpleStoreEntry(BaseStoreEntry):
   490 class SimpleStoreEntry(BaseStoreEntry):
   471     """A generic entry in the store"""
   491     """A generic entry in the store"""
   487         self._entry_path = entry_path
   507         self._entry_path = entry_path
   488         self._is_volatile = is_volatile
   508         self._is_volatile = is_volatile
   489         self._file_size = file_size
   509         self._file_size = file_size
   490         self._files = None
   510         self._files = None
   491 
   511 
   492     def files(self):
   512     def files(self) -> List[StoreFile]:
   493         if self._files is None:
   513         if self._files is None:
   494             self._files = [
   514             self._files = [
   495                 StoreFile(
   515                 StoreFile(
   496                     unencoded_path=self._entry_path,
   516                     unencoded_path=self._entry_path,
   497                     file_size=self._file_size,
   517                     file_size=self._file_size,
   542 
   562 
   543     def main_file_path(self):
   563     def main_file_path(self):
   544         """unencoded path of the main revlog file"""
   564         """unencoded path of the main revlog file"""
   545         return self._path_prefix + b'.i'
   565         return self._path_prefix + b'.i'
   546 
   566 
   547     def files(self):
   567     def files(self) -> List[StoreFile]:
   548         if self._files is None:
   568         if self._files is None:
   549             self._files = []
   569             self._files = []
   550             for ext in sorted(self._details, key=_ext_key):
   570             for ext in sorted(self._details, key=_ext_key):
   551                 path = self._path_prefix + ext
   571                 path = self._path_prefix + ext
   552                 data = self._details[ext]
   572                 data = self._details[ext]
   565             return manifest.manifestrevlog(
   585             return manifest.manifestrevlog(
   566                 repo.nodeconstants, repo.svfs, tree=mandir
   586                 repo.nodeconstants, repo.svfs, tree=mandir
   567             )
   587             )
   568         else:
   588         else:
   569             return filelog.filelog(repo.svfs, self.target_id)
   589             return filelog.filelog(repo.svfs, self.target_id)
   570 
       
   571 
       
   572 @attr.s(slots=True)
       
   573 class StoreFile:
       
   574     """a file matching an entry"""
       
   575 
       
   576     unencoded_path = attr.ib()
       
   577     _file_size = attr.ib(default=None)
       
   578     is_volatile = attr.ib(default=False)
       
   579 
       
   580     def file_size(self, vfs):
       
   581         if self._file_size is None:
       
   582             try:
       
   583                 self._file_size = vfs.stat(self.unencoded_path).st_size
       
   584             except FileNotFoundError:
       
   585                 self._file_size = 0
       
   586         return self._file_size
       
   587 
   590 
   588 
   591 
   589 def _gather_revlog(files_data):
   592 def _gather_revlog(files_data):
   590     """group files per revlog prefix
   593     """group files per revlog prefix
   591 
   594