mercurial/upgrade_utils/actions.py
changeset 47319 e985a36c2aa3
parent 47277 ed0d54b20c5b
child 47320 a43d256c041a
equal deleted inserted replaced
47315:825d5a5907b4 47319:e985a36c2aa3
    42 FORMAT_VARIANT = b'deficiency'
    42 FORMAT_VARIANT = b'deficiency'
    43 OPTIMISATION = b'optimization'
    43 OPTIMISATION = b'optimization'
    44 
    44 
    45 
    45 
    46 class improvement(object):
    46 class improvement(object):
    47     """Represents an improvement that can be made as part of an upgrade.
    47     """Represents an improvement that can be made as part of an upgrade."""
    48 
    48 
    49     The following attributes are defined on each instance:
    49     ### The following attributes should be defined for each subclass:
    50 
    50 
    51     name
    51     # Either ``FORMAT_VARIANT`` or ``OPTIMISATION``.
    52        Machine-readable string uniquely identifying this improvement. It
    52     # A format variant is where we change the storage format. Not all format
    53        will be mapped to an action later in the upgrade process.
    53     # variant changes are an obvious problem.
    54 
    54     # An optimization is an action (sometimes optional) that
    55     type
    55     # can be taken to further improve the state of the repository.
    56        Either ``FORMAT_VARIANT`` or ``OPTIMISATION``.
    56     type = None
    57        A format variant is where we change the storage format. Not all format
       
    58        variant changes are an obvious problem.
       
    59        An optimization is an action (sometimes optional) that
       
    60        can be taken to further improve the state of the repository.
       
    61 
       
    62     description
       
    63        Message intended for humans explaining the improvement in more detail,
       
    64        including the implications of it. For ``FORMAT_VARIANT`` types, should be
       
    65        worded in the present tense. For ``OPTIMISATION`` types, should be
       
    66        worded in the future tense.
       
    67 
       
    68     upgrademessage
       
    69        Message intended for humans explaining what an upgrade addressing this
       
    70        issue will do. Should be worded in the future tense.
       
    71 
       
    72     postupgrademessage
       
    73        Message intended for humans which will be shown post an upgrade
       
    74        operation when the improvement will be added
       
    75 
       
    76     postdowngrademessage
       
    77        Message intended for humans which will be shown post an upgrade
       
    78        operation in which this improvement was removed
       
    79 
       
    80     touches_filelogs (bool)
       
    81         Whether this improvement touches filelogs
       
    82 
       
    83     touches_manifests (bool)
       
    84         Whether this improvement touches manifests
       
    85 
       
    86     touches_changelog (bool)
       
    87         Whether this improvement touches changelog
       
    88 
       
    89     touches_requirements (bool)
       
    90         Whether this improvement changes repository requirements
       
    91     """
       
    92 
       
    93     def __init__(self, name, type, description, upgrademessage):
       
    94         self.name = name
       
    95         self.type = type
       
    96         self.description = description
       
    97         self.upgrademessage = upgrademessage
       
    98         self.postupgrademessage = None
       
    99         self.postdowngrademessage = None
       
   100         # By default for now, we assume every improvement touches
       
   101         # all the things
       
   102         self.touches_filelogs = True
       
   103         self.touches_manifests = True
       
   104         self.touches_changelog = True
       
   105         self.touches_requirements = True
       
   106 
       
   107     def __eq__(self, other):
       
   108         if not isinstance(other, improvement):
       
   109             # This is what python tell use to do
       
   110             return NotImplemented
       
   111         return self.name == other.name
       
   112 
       
   113     def __ne__(self, other):
       
   114         return not (self == other)
       
   115 
       
   116     def __hash__(self):
       
   117         return hash(self.name)
       
   118 
       
   119 
       
   120 allformatvariant = []  # type: List[Type['formatvariant']]
       
   121 
       
   122 
       
   123 def registerformatvariant(cls):
       
   124     allformatvariant.append(cls)
       
   125     return cls
       
   126 
       
   127 
       
   128 class formatvariant(improvement):
       
   129     """an improvement subclass dedicated to repository format"""
       
   130 
       
   131     type = FORMAT_VARIANT
       
   132     ### The following attributes should be defined for each class:
       
   133 
    57 
   134     # machine-readable string uniquely identifying this improvement. it will be
    58     # machine-readable string uniquely identifying this improvement. it will be
   135     # mapped to an action later in the upgrade process.
    59     # mapped to an action later in the upgrade process.
   136     name = None
    60     name = None
   137 
    61 
   155     # Message intended for humans which will be shown post an upgrade
    79     # Message intended for humans which will be shown post an upgrade
   156     # operation in which this improvement was removed
    80     # operation in which this improvement was removed
   157     postdowngrademessage = None
    81     postdowngrademessage = None
   158 
    82 
   159     # By default for now, we assume every improvement touches all the things
    83     # By default for now, we assume every improvement touches all the things
       
    84 
       
    85     # Whether this improvement touches filelogs
   160     touches_filelogs = True
    86     touches_filelogs = True
       
    87 
       
    88     # Whether this improvement touches manifests
   161     touches_manifests = True
    89     touches_manifests = True
       
    90 
       
    91     # Whether this improvement touches changelog
   162     touches_changelog = True
    92     touches_changelog = True
       
    93 
       
    94     # Whether this improvement changes repository requirements
   163     touches_requirements = True
    95     touches_requirements = True
   164 
    96 
   165     def __init__(self):
    97 
   166         raise NotImplementedError()
    98 allformatvariant = []  # type: List[Type['formatvariant']]
       
    99 
       
   100 
       
   101 def registerformatvariant(cls):
       
   102     allformatvariant.append(cls)
       
   103     return cls
       
   104 
       
   105 
       
   106 class formatvariant(improvement):
       
   107     """an improvement subclass dedicated to repository format"""
       
   108 
       
   109     type = FORMAT_VARIANT
   167 
   110 
   168     @staticmethod
   111     @staticmethod
   169     def fromrepo(repo):
   112     def fromrepo(repo):
   170         """current value of the variant in the repository"""
   113         """current value of the variant in the repository"""
   171         raise NotImplementedError()
   114         raise NotImplementedError()
   543 def register_optimization(obj):
   486 def register_optimization(obj):
   544     ALL_OPTIMISATIONS.append(obj)
   487     ALL_OPTIMISATIONS.append(obj)
   545     return obj
   488     return obj
   546 
   489 
   547 
   490 
   548 register_optimization(
   491 class optimization(improvement):
   549     improvement(
   492     """an improvement subclass dedicated to optimizations"""
   550         name=b're-delta-parent',
   493 
   551         type=OPTIMISATION,
   494     type = OPTIMISATION
   552         description=_(
   495 
   553             b'deltas within internal storage will be recalculated to '
   496 
   554             b'choose an optimal base revision where this was not '
   497 @register_optimization
   555             b'already done; the size of the repository may shrink and '
   498 class redeltaparents(optimization):
   556             b'various operations may become faster; the first time '
   499     name = b're-delta-parent'
   557             b'this optimization is performed could slow down upgrade '
   500 
   558             b'execution considerably; subsequent invocations should '
   501     type = OPTIMISATION
   559             b'not run noticeably slower'
   502 
   560         ),
   503     description = _(
   561         upgrademessage=_(
   504         b'deltas within internal storage will be recalculated to '
   562             b'deltas within internal storage will choose a new '
   505         b'choose an optimal base revision where this was not '
   563             b'base revision if needed'
   506         b'already done; the size of the repository may shrink and '
   564         ),
   507         b'various operations may become faster; the first time '
   565     )
   508         b'this optimization is performed could slow down upgrade '
   566 )
   509         b'execution considerably; subsequent invocations should '
   567 
   510         b'not run noticeably slower'
   568 register_optimization(
   511     )
   569     improvement(
   512 
   570         name=b're-delta-multibase',
   513     upgrademessage = _(
   571         type=OPTIMISATION,
   514         b'deltas within internal storage will choose a new '
   572         description=_(
   515         b'base revision if needed'
   573             b'deltas within internal storage will be recalculated '
   516     )
   574             b'against multiple base revision and the smallest '
   517 
   575             b'difference will be used; the size of the repository may '
   518 
   576             b'shrink significantly when there are many merges; this '
   519 @register_optimization
   577             b'optimization will slow down execution in proportion to '
   520 class redeltamultibase(optimization):
   578             b'the number of merges in the repository and the amount '
   521     name = b're-delta-multibase'
   579             b'of files in the repository; this slow down should not '
   522 
   580             b'be significant unless there are tens of thousands of '
   523     type = OPTIMISATION
   581             b'files and thousands of merges'
   524 
   582         ),
   525     description = _(
   583         upgrademessage=_(
   526         b'deltas within internal storage will be recalculated '
   584             b'deltas within internal storage will choose an '
   527         b'against multiple base revision and the smallest '
   585             b'optimal delta by computing deltas against multiple '
   528         b'difference will be used; the size of the repository may '
   586             b'parents; may slow down execution time '
   529         b'shrink significantly when there are many merges; this '
   587             b'significantly'
   530         b'optimization will slow down execution in proportion to '
   588         ),
   531         b'the number of merges in the repository and the amount '
   589     )
   532         b'of files in the repository; this slow down should not '
   590 )
   533         b'be significant unless there are tens of thousands of '
   591 
   534         b'files and thousands of merges'
   592 register_optimization(
   535     )
   593     improvement(
   536 
   594         name=b're-delta-all',
   537     upgrademessage = _(
   595         type=OPTIMISATION,
   538         b'deltas within internal storage will choose an '
   596         description=_(
   539         b'optimal delta by computing deltas against multiple '
   597             b'deltas within internal storage will always be '
   540         b'parents; may slow down execution time '
   598             b'recalculated without reusing prior deltas; this will '
   541         b'significantly'
   599             b'likely make execution run several times slower; this '
   542     )
   600             b'optimization is typically not needed'
   543 
   601         ),
   544 
   602         upgrademessage=_(
   545 @register_optimization
   603             b'deltas within internal storage will be fully '
   546 class redeltaall(optimization):
   604             b'recomputed; this will likely drastically slow down '
   547     name = b're-delta-all'
   605             b'execution time'
   548 
   606         ),
   549     type = OPTIMISATION
   607     )
   550 
   608 )
   551     description = _(
   609 
   552         b'deltas within internal storage will always be '
   610 register_optimization(
   553         b'recalculated without reusing prior deltas; this will '
   611     improvement(
   554         b'likely make execution run several times slower; this '
   612         name=b're-delta-fulladd',
   555         b'optimization is typically not needed'
   613         type=OPTIMISATION,
   556     )
   614         description=_(
   557 
   615             b'every revision will be re-added as if it was new '
   558     upgrademessage = _(
   616             b'content. It will go through the full storage '
   559         b'deltas within internal storage will be fully '
   617             b'mechanism giving extensions a chance to process it '
   560         b'recomputed; this will likely drastically slow down '
   618             b'(eg. lfs). This is similar to "re-delta-all" but even '
   561         b'execution time'
   619             b'slower since more logic is involved.'
   562     )
   620         ),
   563 
   621         upgrademessage=_(
   564 
   622             b'each revision will be added as new content to the '
   565 @register_optimization
   623             b'internal storage; this will likely drastically slow '
   566 class redeltafulladd(optimization):
   624             b'down execution time, but some extensions might need '
   567     name = b're-delta-fulladd'
   625             b'it'
   568 
   626         ),
   569     type = OPTIMISATION
   627     )
   570 
   628 )
   571     description = _(
       
   572         b'every revision will be re-added as if it was new '
       
   573         b'content. It will go through the full storage '
       
   574         b'mechanism giving extensions a chance to process it '
       
   575         b'(eg. lfs). This is similar to "re-delta-all" but even '
       
   576         b'slower since more logic is involved.'
       
   577     )
       
   578 
       
   579     upgrademessage = _(
       
   580         b'each revision will be added as new content to the '
       
   581         b'internal storage; this will likely drastically slow '
       
   582         b'down execution time, but some extensions might need '
       
   583         b'it'
       
   584     )
   629 
   585 
   630 
   586 
   631 def findoptimizations(repo):
   587 def findoptimizations(repo):
   632     """Determine optimisation that could be used during upgrade"""
   588     """Determine optimisation that could be used during upgrade"""
   633     # These are unconditionally added. There is logic later that figures out
   589     # These are unconditionally added. There is logic later that figures out