mercurial/upgrade.py
changeset 32031 11a2461fc9b1
parent 32030 e47223576b8d
child 32032 189778a06743
equal deleted inserted replaced
32030:e47223576b8d 32031:11a2461fc9b1
   138 
   138 
   139     def __hash__(self):
   139     def __hash__(self):
   140         return hash(self.name)
   140         return hash(self.name)
   141 
   141 
   142 class formatvariant(improvement):
   142 class formatvariant(improvement):
   143     """an improvement subclass dedicated to repository format
   143     """an improvement subclass dedicated to repository format"""
   144 
   144     type = deficiency
   145     extra attributes:
   145     ### The following attributes should be defined for each class:
   146 
   146 
   147     fromdefault (``deficiency`` types only)
   147     # machine-readable string uniquely identifying this improvement. it will be
   148        Boolean indicating whether the current (deficient) state deviates
   148     # mapped to an action later in the upgrade process.
   149        from Mercurial's default configuration.
   149     name = None
   150 
   150 
   151     fromconfig (``deficiency`` types only)
   151     # message intended for humans explaining the improvement in more detail,
   152        Boolean indicating whether the current (deficient) state deviates
   152     # including the implications of it ``deficiency`` types, should be worded
   153        from the current Mercurial configuration.
   153     # in the present tense.
   154     """
   154     description = None
   155 
   155 
   156     def __init__(self, name, description, upgrademessage, fromdefault,
   156     # message intended for humans explaining what an upgrade addressing this
   157                  fromconfig):
   157     # issue will do. should be worded in the future tense.
   158         super(formatvariant, self).__init__(name, deficiency, description,
   158     upgrademessage = None
   159                                             upgrademessage)
   159 
   160         self.fromdefault = fromdefault
   160     # value of current Mercurial default for new repository
   161         self.fromconfig = fromconfig
   161     default = None
       
   162 
       
   163     def __init__(self):
       
   164         raise NotImplementedError()
       
   165 
       
   166     @staticmethod
       
   167     def fromrepo(repo):
       
   168         """current value of the variant in the repository"""
       
   169         raise NotImplementedError()
       
   170 
       
   171     @staticmethod
       
   172     def fromconfig(repo):
       
   173         """current value of the variant in the configuration"""
       
   174         raise NotImplementedError()
       
   175 
       
   176 class requirementformatvariant(formatvariant):
       
   177     """formatvariant based on a 'requirement' name.
       
   178 
       
   179     Many format variant are controlled by a 'requirement'. We define a small
       
   180     subclass to factor the code.
       
   181     """
       
   182 
       
   183     # the requirement that control this format variant
       
   184     _requirement = None
       
   185 
       
   186     @staticmethod
       
   187     def _newreporequirements(repo):
       
   188         return localrepo.newreporequirements(repo)
       
   189 
       
   190     @classmethod
       
   191     def fromrepo(cls, repo):
       
   192         assert cls._requirement is not None
       
   193         return cls._requirement in repo.requirements
       
   194 
       
   195     @classmethod
       
   196     def fromconfig(cls, repo):
       
   197         assert cls._requirement is not None
       
   198         return cls._requirement in cls._newreporequirements(repo)
       
   199 
       
   200 class fncache(requirementformatvariant):
       
   201     name = 'fncache'
       
   202 
       
   203     _requirement = 'fncache'
       
   204 
       
   205     default = True
       
   206 
       
   207     description = _('long and reserved filenames may not work correctly; '
       
   208                     'repository performance is sub-optimal')
       
   209 
       
   210     upgrademessage = _('repository will be more resilient to storing '
       
   211                        'certain paths and performance of certain '
       
   212                        'operations should be improved')
       
   213 
       
   214 class dotencode(requirementformatvariant):
       
   215     name = 'dotencode'
       
   216 
       
   217     _requirement = 'dotencode'
       
   218 
       
   219     default = True
       
   220 
       
   221     description = _('storage of filenames beginning with a period or '
       
   222                     'space may not work correctly')
       
   223 
       
   224     upgrademessage = _('repository will be better able to store files '
       
   225                        'beginning with a space or period')
       
   226 
       
   227 class generaldelta(requirementformatvariant):
       
   228     name = 'generaldelta'
       
   229 
       
   230     _requirement = 'generaldelta'
       
   231 
       
   232     default = True
       
   233 
       
   234     description = _('deltas within internal storage are unable to '
       
   235                     'choose optimal revisions; repository is larger and '
       
   236                     'slower than it could be; interaction with other '
       
   237                     'repositories may require extra network and CPU '
       
   238                     'resources, making "hg push" and "hg pull" slower')
       
   239 
       
   240     upgrademessage = _('repository storage will be able to create '
       
   241                        'optimal deltas; new repository data will be '
       
   242                        'smaller and read times should decrease; '
       
   243                        'interacting with other repositories using this '
       
   244                        'storage model should require less network and '
       
   245                        'CPU resources, making "hg push" and "hg pull" '
       
   246                        'faster')
       
   247 
       
   248 class removecldeltachain(formatvariant):
       
   249     name = 'removecldeltachain'
       
   250 
       
   251     default = True
       
   252 
       
   253     description = _('changelog storage is using deltas instead of '
       
   254                     'raw entries; changelog reading and any '
       
   255                     'operation relying on changelog data are slower '
       
   256                     'than they could be')
       
   257 
       
   258     upgrademessage = _('changelog storage will be reformated to '
       
   259                        'store raw entries; changelog reading will be '
       
   260                        'faster; changelog size may be reduced')
       
   261 
       
   262     @staticmethod
       
   263     def fromrepo(repo):
       
   264         # Mercurial 4.0 changed changelogs to not use delta chains. Search for
       
   265         # changelogs with deltas.
       
   266         cl = repo.changelog
       
   267         chainbase = cl.chainbase
       
   268         return all(rev == chainbase(rev) for rev in cl)
       
   269 
       
   270     @staticmethod
       
   271     def fromconfig(repo):
       
   272         return True
   162 
   273 
   163 def finddeficiencies(repo):
   274 def finddeficiencies(repo):
   164     """returns a list of deficiencies that the repo suffer from"""
   275     """returns a list of deficiencies that the repo suffer from"""
   165     newreporeqs = localrepo.newreporequirements(repo)
       
   166 
       
   167     deficiencies = []
   276     deficiencies = []
   168 
   277 
   169     # We could detect lack of revlogv1 and store here, but they were added
   278     # We could detect lack of revlogv1 and store here, but they were added
   170     # in 0.9.2 and we don't support upgrading repos without these
   279     # in 0.9.2 and we don't support upgrading repos without these
   171     # requirements, so let's not bother.
   280     # requirements, so let's not bother.
   172 
   281 
   173     if 'fncache' not in repo.requirements:
   282     if not fncache.fromrepo(repo):
   174         deficiencies.append(formatvariant(
   283         deficiencies.append(fncache)
   175             name='fncache',
   284     if not dotencode.fromrepo(repo):
   176             description=_('long and reserved filenames may not work correctly; '
   285         deficiencies.append(dotencode)
   177                           'repository performance is sub-optimal'),
   286     if not generaldelta.fromrepo(repo):
   178             upgrademessage=_('repository will be more resilient to storing '
   287         deficiencies.append(generaldelta)
   179                              'certain paths and performance of certain '
   288     if not removecldeltachain.fromrepo(repo):
   180                              'operations should be improved'),
   289         deficiencies.append(removecldeltachain)
   181             fromdefault=True,
       
   182             fromconfig='fncache' in newreporeqs))
       
   183 
       
   184     if 'dotencode' not in repo.requirements:
       
   185         deficiencies.append(formatvariant(
       
   186             name='dotencode',
       
   187             description=_('storage of filenames beginning with a period or '
       
   188                           'space may not work correctly'),
       
   189             upgrademessage=_('repository will be better able to store files '
       
   190                              'beginning with a space or period'),
       
   191             fromdefault=True,
       
   192             fromconfig='dotencode' in newreporeqs))
       
   193 
       
   194     if 'generaldelta' not in repo.requirements:
       
   195         deficiencies.append(formatvariant(
       
   196             name='generaldelta',
       
   197             description=_('deltas within internal storage are unable to '
       
   198                           'choose optimal revisions; repository is larger and '
       
   199                           'slower than it could be; interaction with other '
       
   200                           'repositories may require extra network and CPU '
       
   201                           'resources, making "hg push" and "hg pull" slower'),
       
   202             upgrademessage=_('repository storage will be able to create '
       
   203                              'optimal deltas; new repository data will be '
       
   204                              'smaller and read times should decrease; '
       
   205                              'interacting with other repositories using this '
       
   206                              'storage model should require less network and '
       
   207                              'CPU resources, making "hg push" and "hg pull" '
       
   208                              'faster'),
       
   209             fromdefault=True,
       
   210             fromconfig='generaldelta' in newreporeqs))
       
   211 
       
   212     # Mercurial 4.0 changed changelogs to not use delta chains. Search for
       
   213     # changelogs with deltas.
       
   214     cl = repo.changelog
       
   215     for rev in cl:
       
   216         chainbase = cl.chainbase(rev)
       
   217         if chainbase != rev:
       
   218             deficiencies.append(formatvariant(
       
   219                 name='removecldeltachain',
       
   220                 description=_('changelog storage is using deltas instead of '
       
   221                               'raw entries; changelog reading and any '
       
   222                               'operation relying on changelog data are slower '
       
   223                               'than they could be'),
       
   224                 upgrademessage=_('changelog storage will be reformated to '
       
   225                                  'store raw entries; changelog reading will be '
       
   226                                  'faster; changelog size may be reduced'),
       
   227                 fromdefault=True,
       
   228                 fromconfig=True))
       
   229             break
       
   230 
   290 
   231     return deficiencies
   291     return deficiencies
   232 
   292 
   233 def findoptimizations(repo):
   293 def findoptimizations(repo):
   234     """Determine optimisation that could be used during upgrade"""
   294     """Determine optimisation that could be used during upgrade"""
   678     if not run:
   738     if not run:
   679         fromconfig = []
   739         fromconfig = []
   680         onlydefault = []
   740         onlydefault = []
   681 
   741 
   682         for d in deficiencies:
   742         for d in deficiencies:
   683             if d.fromconfig:
   743             if d.fromconfig(repo):
   684                 fromconfig.append(d)
   744                 fromconfig.append(d)
   685             elif d.fromdefault:
   745             elif d.default:
   686                 onlydefault.append(d)
   746                 onlydefault.append(d)
   687 
   747 
   688         if fromconfig or onlydefault:
   748         if fromconfig or onlydefault:
   689 
   749 
   690             if fromconfig:
   750             if fromconfig: