mercurial/store.py
changeset 50688 e324329fc97e
parent 50680 3b56395404a1
child 50706 0452af304808
equal deleted inserted replaced
50687:8f7e189af9dc 50688:e324329fc97e
     1 # store.py - repository store handling for Mercurial
     1 # store.py - repository store handling for Mercurial)
     2 #
     2 #
     3 # Copyright 2008 Olivia Mackall <olivia@selenic.com>
     3 # Copyright 2008 Olivia Mackall <olivia@selenic.com>
     4 #
     4 #
     5 # This software may be used and distributed according to the terms of the
     5 # This software may be used and distributed according to the terms of the
     6 # GNU General Public License version 2 or any later version.
     6 # GNU General Public License version 2 or any later version.
    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
    19 from .revlogutils.constants import (
    19 from .revlogutils.constants import (
    20     INDEX_HEADER,
    20     INDEX_HEADER,
       
    21     KIND_CHANGELOG,
       
    22     KIND_FILELOG,
       
    23     KIND_MANIFESTLOG,
    21 )
    24 )
    22 from . import (
    25 from . import (
    23     changelog,
    26     changelog,
    24     error,
    27     error,
    25     filelog,
    28     filelog,
   429     if f.endswith(REVLOG_FILES_EXT):
   432     if f.endswith(REVLOG_FILES_EXT):
   430         return True
   433         return True
   431     return False
   434     return False
   432 
   435 
   433 
   436 
   434 # the file is part of changelog data
       
   435 FILEFLAGS_CHANGELOG = 1 << 13
       
   436 # the file is part of manifest data
       
   437 FILEFLAGS_MANIFESTLOG = 1 << 12
       
   438 # the file is part of filelog data
       
   439 FILEFLAGS_FILELOG = 1 << 11
       
   440 # file that are not directly part of a revlog
       
   441 FILEFLAGS_OTHER = 1 << 10
       
   442 
       
   443 # the main entry point for a revlog
       
   444 FILEFLAGS_REVLOG_MAIN = 1 << 1
       
   445 # a secondary file for a revlog
       
   446 FILEFLAGS_REVLOG_OTHER = 1 << 0
       
   447 
       
   448 # files that are "volatile" and might change between listing and streaming
       
   449 FILEFLAGS_VOLATILE = 1 << 20
       
   450 
       
   451 FILETYPE_CHANGELOG_MAIN = FILEFLAGS_CHANGELOG | FILEFLAGS_REVLOG_MAIN
       
   452 FILETYPE_CHANGELOG_OTHER = FILEFLAGS_CHANGELOG | FILEFLAGS_REVLOG_OTHER
       
   453 FILETYPE_MANIFESTLOG_MAIN = FILEFLAGS_MANIFESTLOG | FILEFLAGS_REVLOG_MAIN
       
   454 FILETYPE_MANIFESTLOG_OTHER = FILEFLAGS_MANIFESTLOG | FILEFLAGS_REVLOG_OTHER
       
   455 FILETYPE_FILELOG_MAIN = FILEFLAGS_FILELOG | FILEFLAGS_REVLOG_MAIN
       
   456 FILETYPE_FILELOG_OTHER = FILEFLAGS_FILELOG | FILEFLAGS_REVLOG_OTHER
       
   457 FILETYPE_OTHER = FILEFLAGS_OTHER
       
   458 
       
   459 
       
   460 @attr.s(slots=True)
   437 @attr.s(slots=True)
   461 class StoreFile:
   438 class StoreFile:
   462     """a file matching a store entry"""
   439     """a file matching a store entry"""
   463 
   440 
   464     unencoded_path = attr.ib()
   441     unencoded_path = attr.ib()
   584         self._details = details
   561         self._details = details
   585         self._files = None
   562         self._files = None
   586 
   563 
   587     @property
   564     @property
   588     def is_changelog(self):
   565     def is_changelog(self):
   589         return self.revlog_type & FILEFLAGS_CHANGELOG
   566         return self.revlog_type == KIND_CHANGELOG
   590 
   567 
   591     @property
   568     @property
   592     def is_manifestlog(self):
   569     def is_manifestlog(self):
   593         return self.revlog_type & FILEFLAGS_MANIFESTLOG
   570         return self.revlog_type == KIND_MANIFESTLOG
   594 
   571 
   595     @property
   572     @property
   596     def is_filelog(self):
   573     def is_filelog(self):
   597         return self.revlog_type & FILEFLAGS_FILELOG
   574         return self.revlog_type == KIND_FILELOG
   598 
   575 
   599     def main_file_path(self):
   576     def main_file_path(self):
   600         """unencoded path of the main revlog file"""
   577         """unencoded path of the main revlog file"""
   601         return self._path_prefix + b'.i'
   578         return self._path_prefix + b'.i'
   602 
   579 
   810         When [undecodable] is None, revlogs names that can't be
   787         When [undecodable] is None, revlogs names that can't be
   811         decoded cause an exception. When it is provided, it should
   788         decoded cause an exception. When it is provided, it should
   812         be a list and the filenames that can't be decoded are added
   789         be a list and the filenames that can't be decoded are added
   813         to it instead. This is very rarely needed."""
   790         to it instead. This is very rarely needed."""
   814         dirs = [
   791         dirs = [
   815             (b'data', FILEFLAGS_FILELOG, False),
   792             (b'data', KIND_FILELOG, False),
   816             (b'meta', FILEFLAGS_MANIFESTLOG, True),
   793             (b'meta', KIND_MANIFESTLOG, True),
   817         ]
   794         ]
   818         for base_dir, rl_type, strip_filename in dirs:
   795         for base_dir, rl_type, strip_filename in dirs:
   819             files = self._walk(base_dir, True, undecodable=undecodable)
   796             files = self._walk(base_dir, True, undecodable=undecodable)
   820             for revlog, details in _gather_revlog(files):
   797             for revlog, details in _gather_revlog(files):
   821                 revlog_target_id = revlog.split(b'/', 1)[1]
   798                 revlog_target_id = revlog.split(b'/', 1)[1]
   863                     is_volatile=False,
   840                     is_volatile=False,
   864                     file_size=s,
   841                     file_size=s,
   865                 )
   842                 )
   866         # yield manifest before changelog
   843         # yield manifest before changelog
   867         top_rl = [
   844         top_rl = [
   868             (manifestlogs, FILEFLAGS_MANIFESTLOG),
   845             (manifestlogs, KIND_MANIFESTLOG),
   869             (changelogs, FILEFLAGS_CHANGELOG),
   846             (changelogs, KIND_CHANGELOG),
   870         ]
   847         ]
   871         assert len(manifestlogs) <= 1
   848         assert len(manifestlogs) <= 1
   872         assert len(changelogs) <= 1
   849         assert len(changelogs) <= 1
   873         for data, revlog_type in top_rl:
   850         for data, revlog_type in top_rl:
   874             for revlog, details in sorted(data.items()):
   851             for revlog, details in sorted(data.items()):
  1157         # Mercurial.
  1134         # Mercurial.
  1158         files = ((f, None) for f in self.fncache if is_revlog_file(f))
  1135         files = ((f, None) for f in self.fncache if is_revlog_file(f))
  1159         by_revlog = _gather_revlog(files)
  1136         by_revlog = _gather_revlog(files)
  1160         for revlog, details in by_revlog:
  1137         for revlog, details in by_revlog:
  1161             if revlog.startswith(b'data/'):
  1138             if revlog.startswith(b'data/'):
  1162                 rl_type = FILEFLAGS_FILELOG
  1139                 rl_type = KIND_FILELOG
  1163                 revlog_target_id = revlog.split(b'/', 1)[1]
  1140                 revlog_target_id = revlog.split(b'/', 1)[1]
  1164             elif revlog.startswith(b'meta/'):
  1141             elif revlog.startswith(b'meta/'):
  1165                 rl_type = FILEFLAGS_MANIFESTLOG
  1142                 rl_type = KIND_MANIFESTLOG
  1166                 # drop the initial directory and the `00manifest` file part
  1143                 # drop the initial directory and the `00manifest` file part
  1167                 tmp = revlog.split(b'/', 1)[1]
  1144                 tmp = revlog.split(b'/', 1)[1]
  1168                 revlog_target_id = tmp.rsplit(b'/', 1)[0] + b'/'
  1145                 revlog_target_id = tmp.rsplit(b'/', 1)[0] + b'/'
  1169             else:
  1146             else:
  1170                 # unreachable
  1147                 # unreachable