##// END OF EJS Templates
upgrade: don't create store backup if `--no-backup` is passed...
Pulkit Goyal -
r47092:2e8a844d default
parent child Browse files
Show More
@@ -1,351 +1,346 b''
1 1 # upgrade.py - functions for in place upgrade of Mercurial repository
2 2 #
3 3 # Copyright (c) 2016-present, Gregory Szorc
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 from .i18n import _
11 11 from . import (
12 12 error,
13 13 hg,
14 14 localrepo,
15 15 lock as lockmod,
16 16 pycompat,
17 17 requirements as requirementsmod,
18 18 scmutil,
19 19 )
20 20
21 21 from .upgrade_utils import (
22 22 actions as upgrade_actions,
23 23 engine as upgrade_engine,
24 24 )
25 25
26 26 from .utils import (
27 27 stringutil,
28 28 )
29 29
30 30 allformatvariant = upgrade_actions.allformatvariant
31 31
32 32
33 33 def upgraderepo(
34 34 ui,
35 35 repo,
36 36 run=False,
37 37 optimize=None,
38 38 backup=True,
39 39 manifest=None,
40 40 changelog=None,
41 41 filelogs=None,
42 42 ):
43 43 """Upgrade a repository in place."""
44 44 if optimize is None:
45 45 optimize = {}
46 46 repo = repo.unfiltered()
47 47
48 48 revlogs = set(upgrade_engine.UPGRADE_ALL_REVLOGS)
49 49 specentries = (
50 50 (upgrade_engine.UPGRADE_CHANGELOG, changelog),
51 51 (upgrade_engine.UPGRADE_MANIFEST, manifest),
52 52 (upgrade_engine.UPGRADE_FILELOGS, filelogs),
53 53 )
54 54 specified = [(y, x) for (y, x) in specentries if x is not None]
55 55 if specified:
56 56 # we have some limitation on revlogs to be recloned
57 57 if any(x for y, x in specified):
58 58 revlogs = set()
59 59 for upgrade, enabled in specified:
60 60 if enabled:
61 61 revlogs.add(upgrade)
62 62 else:
63 63 # none are enabled
64 64 for upgrade, __ in specified:
65 65 revlogs.discard(upgrade)
66 66
67 67 # Ensure the repository can be upgraded.
68 68 upgrade_actions.check_source_requirements(repo)
69 69
70 70 default_options = localrepo.defaultcreateopts(repo.ui)
71 71 newreqs = localrepo.newreporequirements(repo.ui, default_options)
72 72 newreqs.update(upgrade_actions.preservedrequirements(repo))
73 73
74 74 upgrade_actions.check_requirements_changes(repo, newreqs)
75 75
76 76 # Find and validate all improvements that can be made.
77 77 alloptimizations = upgrade_actions.findoptimizations(repo)
78 78
79 79 # Apply and Validate arguments.
80 80 optimizations = []
81 81 for o in alloptimizations:
82 82 if o.name in optimize:
83 83 optimizations.append(o)
84 84 optimize.discard(o.name)
85 85
86 86 if optimize: # anything left is unknown
87 87 raise error.Abort(
88 88 _(b'unknown optimization action requested: %s')
89 89 % b', '.join(sorted(optimize)),
90 90 hint=_(b'run without arguments to see valid optimizations'),
91 91 )
92 92
93 93 format_upgrades = upgrade_actions.find_format_upgrades(repo)
94 94 up_actions = upgrade_actions.determine_upgrade_actions(
95 95 repo, format_upgrades, optimizations, repo.requirements, newreqs
96 96 )
97 97 removed_actions = upgrade_actions.find_format_downgrades(repo)
98 98
99 99 removedreqs = repo.requirements - newreqs
100 100 addedreqs = newreqs - repo.requirements
101 101
102 102 if revlogs != upgrade_engine.UPGRADE_ALL_REVLOGS:
103 103 incompatible = upgrade_actions.RECLONES_REQUIREMENTS & (
104 104 removedreqs | addedreqs
105 105 )
106 106 if incompatible:
107 107 msg = _(
108 108 b'ignoring revlogs selection flags, format requirements '
109 109 b'change: %s\n'
110 110 )
111 111 ui.warn(msg % b', '.join(sorted(incompatible)))
112 112 revlogs = upgrade_engine.UPGRADE_ALL_REVLOGS
113 113
114 114 upgrade_op = upgrade_actions.UpgradeOperation(
115 115 ui,
116 116 newreqs,
117 117 repo.requirements,
118 118 up_actions,
119 119 removed_actions,
120 120 revlogs,
121 backup,
121 122 )
122 123
123 124 if not run:
124 125 fromconfig = []
125 126 onlydefault = []
126 127
127 128 for d in format_upgrades:
128 129 if d.fromconfig(repo):
129 130 fromconfig.append(d)
130 131 elif d.default:
131 132 onlydefault.append(d)
132 133
133 134 if fromconfig or onlydefault:
134 135
135 136 if fromconfig:
136 137 ui.status(
137 138 _(
138 139 b'repository lacks features recommended by '
139 140 b'current config options:\n\n'
140 141 )
141 142 )
142 143 for i in fromconfig:
143 144 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
144 145
145 146 if onlydefault:
146 147 ui.status(
147 148 _(
148 149 b'repository lacks features used by the default '
149 150 b'config options:\n\n'
150 151 )
151 152 )
152 153 for i in onlydefault:
153 154 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
154 155
155 156 ui.status(b'\n')
156 157 else:
157 158 ui.status(_(b'(no format upgrades found in existing repository)\n'))
158 159
159 160 ui.status(
160 161 _(
161 162 b'performing an upgrade with "--run" will make the following '
162 163 b'changes:\n\n'
163 164 )
164 165 )
165 166
166 167 upgrade_op.print_requirements()
167 168 upgrade_op.print_optimisations()
168 169 upgrade_op.print_upgrade_actions()
169 170 upgrade_op.print_affected_revlogs()
170 171
171 172 if upgrade_op.unused_optimizations:
172 173 ui.status(
173 174 _(
174 175 b'additional optimizations are available by specifying '
175 176 b'"--optimize <name>":\n\n'
176 177 )
177 178 )
178 179 upgrade_op.print_unused_optimizations()
179 180 return
180 181
181 182 if not (upgrade_op.upgrade_actions or upgrade_op.removed_actions):
182 183 ui.status(_(b'nothing to do\n'))
183 184 return
184 185 # Else we're in the run=true case.
185 186 ui.write(_(b'upgrade will perform the following actions:\n\n'))
186 187 upgrade_op.print_requirements()
187 188 upgrade_op.print_optimisations()
188 189 upgrade_op.print_upgrade_actions()
189 190 upgrade_op.print_affected_revlogs()
190 191
191 192 ui.status(_(b'beginning upgrade...\n'))
192 193 with repo.wlock(), repo.lock():
193 194 ui.status(_(b'repository locked and read-only\n'))
194 195 # Our strategy for upgrading the repository is to create a new,
195 196 # temporary repository, write data to it, then do a swap of the
196 197 # data. There are less heavyweight ways to do this, but it is easier
197 198 # to create a new repo object than to instantiate all the components
198 199 # (like the store) separately.
199 200 tmppath = pycompat.mkdtemp(prefix=b'upgrade.', dir=repo.path)
200 201 backuppath = None
201 202 try:
202 203 ui.status(
203 204 _(
204 205 b'creating temporary repository to stage upgraded '
205 206 b'data: %s\n'
206 207 )
207 208 % tmppath
208 209 )
209 210
210 211 # clone ui without using ui.copy because repo.ui is protected
211 212 repoui = repo.ui.__class__(repo.ui)
212 213 dstrepo = hg.repository(repoui, path=tmppath, create=True)
213 214
214 215 with dstrepo.wlock(), dstrepo.lock():
215 216 backuppath = upgrade_engine.upgrade(
216 217 ui, repo, dstrepo, upgrade_op
217 218 )
218 if not backup:
219 ui.status(
220 _(b'removing old repository content %s\n') % backuppath
221 )
222 repo.vfs.rmtree(backuppath, forcibly=True)
223 backuppath = None
224 219
225 220 finally:
226 221 ui.status(_(b'removing temporary repository %s\n') % tmppath)
227 222 repo.vfs.rmtree(tmppath, forcibly=True)
228 223
229 224 if backuppath and not ui.quiet:
230 225 ui.warn(
231 226 _(b'copy of old repository backed up at %s\n') % backuppath
232 227 )
233 228 ui.warn(
234 229 _(
235 230 b'the old repository will not be deleted; remove '
236 231 b'it to free up disk space once the upgraded '
237 232 b'repository is verified\n'
238 233 )
239 234 )
240 235
241 236 upgrade_op.print_post_op_messages()
242 237
243 238
244 239 def upgrade_share_to_safe(
245 240 ui,
246 241 hgvfs,
247 242 storevfs,
248 243 current_requirements,
249 244 mismatch_config,
250 245 mismatch_warn,
251 246 ):
252 247 """Upgrades a share to use share-safe mechanism"""
253 248 wlock = None
254 249 store_requirements = localrepo._readrequires(storevfs, False)
255 250 original_crequirements = current_requirements.copy()
256 251 # after upgrade, store requires will be shared, so lets find
257 252 # the requirements which are not present in store and
258 253 # write them to share's .hg/requires
259 254 diffrequires = current_requirements - store_requirements
260 255 # add share-safe requirement as it will mark the share as share-safe
261 256 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
262 257 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
263 258 # in `allow` case, we don't try to upgrade, we just respect the source
264 259 # state, update requirements and continue
265 260 if mismatch_config == b'allow':
266 261 return
267 262 try:
268 263 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
269 264 # some process might change the requirement in between, re-read
270 265 # and update current_requirements
271 266 locked_requirements = localrepo._readrequires(hgvfs, True)
272 267 if locked_requirements != original_crequirements:
273 268 removed = current_requirements - locked_requirements
274 269 # update current_requirements in place because it's passed
275 270 # as reference
276 271 current_requirements -= removed
277 272 current_requirements |= locked_requirements
278 273 diffrequires = current_requirements - store_requirements
279 274 # add share-safe requirement as it will mark the share as share-safe
280 275 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
281 276 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
282 277 scmutil.writerequires(hgvfs, diffrequires)
283 278 ui.warn(_(b'repository upgraded to use share-safe mode\n'))
284 279 except error.LockError as e:
285 280 if mismatch_config == b'upgrade-abort':
286 281 raise error.Abort(
287 282 _(b'failed to upgrade share, got error: %s')
288 283 % stringutil.forcebytestr(e.strerror)
289 284 )
290 285 elif mismatch_warn:
291 286 ui.warn(
292 287 _(b'failed to upgrade share, got error: %s\n')
293 288 % stringutil.forcebytestr(e.strerror)
294 289 )
295 290 finally:
296 291 if wlock:
297 292 wlock.release()
298 293
299 294
300 295 def downgrade_share_to_non_safe(
301 296 ui,
302 297 hgvfs,
303 298 sharedvfs,
304 299 current_requirements,
305 300 mismatch_config,
306 301 mismatch_warn,
307 302 ):
308 303 """Downgrades a share which use share-safe to not use it"""
309 304 wlock = None
310 305 source_requirements = localrepo._readrequires(sharedvfs, True)
311 306 original_crequirements = current_requirements.copy()
312 307 # we cannot be 100% sure on which requirements were present in store when
313 308 # the source supported share-safe. However, we do know that working
314 309 # directory requirements were not there. Hence we remove them
315 310 source_requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS
316 311 current_requirements |= source_requirements
317 312 current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT)
318 313 if mismatch_config == b'allow':
319 314 return
320 315
321 316 try:
322 317 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
323 318 # some process might change the requirement in between, re-read
324 319 # and update current_requirements
325 320 locked_requirements = localrepo._readrequires(hgvfs, True)
326 321 if locked_requirements != original_crequirements:
327 322 removed = current_requirements - locked_requirements
328 323 # update current_requirements in place because it's passed
329 324 # as reference
330 325 current_requirements -= removed
331 326 current_requirements |= locked_requirements
332 327 current_requirements |= source_requirements
333 328 current_requirements -= set(requirementsmod.SHARESAFE_REQUIREMENT)
334 329 scmutil.writerequires(hgvfs, current_requirements)
335 330 ui.warn(_(b'repository downgraded to not use share-safe mode\n'))
336 331 except error.LockError as e:
337 332 # If upgrade-abort is set, abort when upgrade fails, else let the
338 333 # process continue as `upgrade-allow` is set
339 334 if mismatch_config == b'downgrade-abort':
340 335 raise error.Abort(
341 336 _(b'failed to downgrade share, got error: %s')
342 337 % stringutil.forcebytestr(e.strerror)
343 338 )
344 339 elif mismatch_warn:
345 340 ui.warn(
346 341 _(b'failed to downgrade share, got error: %s\n')
347 342 % stringutil.forcebytestr(e.strerror)
348 343 )
349 344 finally:
350 345 if wlock:
351 346 wlock.release()
@@ -1,911 +1,915 b''
1 1 # upgrade.py - functions for in place upgrade of Mercurial repository
2 2 #
3 3 # Copyright (c) 2016-present, Gregory Szorc
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 from ..i18n import _
11 11 from .. import (
12 12 error,
13 13 localrepo,
14 14 requirements,
15 15 revlog,
16 16 util,
17 17 )
18 18
19 19 from ..utils import compression
20 20
21 21 # list of requirements that request a clone of all revlog if added/removed
22 22 RECLONES_REQUIREMENTS = {
23 23 b'generaldelta',
24 24 requirements.SPARSEREVLOG_REQUIREMENT,
25 25 }
26 26
27 27
28 28 def preservedrequirements(repo):
29 29 return set()
30 30
31 31
32 32 FORMAT_VARIANT = b'deficiency'
33 33 OPTIMISATION = b'optimization'
34 34
35 35
36 36 class improvement(object):
37 37 """Represents an improvement that can be made as part of an upgrade.
38 38
39 39 The following attributes are defined on each instance:
40 40
41 41 name
42 42 Machine-readable string uniquely identifying this improvement. It
43 43 will be mapped to an action later in the upgrade process.
44 44
45 45 type
46 46 Either ``FORMAT_VARIANT`` or ``OPTIMISATION``.
47 47 A format variant is where we change the storage format. Not all format
48 48 variant changes are an obvious problem.
49 49 An optimization is an action (sometimes optional) that
50 50 can be taken to further improve the state of the repository.
51 51
52 52 description
53 53 Message intended for humans explaining the improvement in more detail,
54 54 including the implications of it. For ``FORMAT_VARIANT`` types, should be
55 55 worded in the present tense. For ``OPTIMISATION`` types, should be
56 56 worded in the future tense.
57 57
58 58 upgrademessage
59 59 Message intended for humans explaining what an upgrade addressing this
60 60 issue will do. Should be worded in the future tense.
61 61
62 62 postupgrademessage
63 63 Message intended for humans which will be shown post an upgrade
64 64 operation when the improvement will be added
65 65
66 66 postdowngrademessage
67 67 Message intended for humans which will be shown post an upgrade
68 68 operation in which this improvement was removed
69 69 """
70 70
71 71 def __init__(self, name, type, description, upgrademessage):
72 72 self.name = name
73 73 self.type = type
74 74 self.description = description
75 75 self.upgrademessage = upgrademessage
76 76 self.postupgrademessage = None
77 77 self.postdowngrademessage = None
78 78
79 79 def __eq__(self, other):
80 80 if not isinstance(other, improvement):
81 81 # This is what python tell use to do
82 82 return NotImplemented
83 83 return self.name == other.name
84 84
85 85 def __ne__(self, other):
86 86 return not (self == other)
87 87
88 88 def __hash__(self):
89 89 return hash(self.name)
90 90
91 91
92 92 allformatvariant = []
93 93
94 94
95 95 def registerformatvariant(cls):
96 96 allformatvariant.append(cls)
97 97 return cls
98 98
99 99
100 100 class formatvariant(improvement):
101 101 """an improvement subclass dedicated to repository format"""
102 102
103 103 type = FORMAT_VARIANT
104 104 ### The following attributes should be defined for each class:
105 105
106 106 # machine-readable string uniquely identifying this improvement. it will be
107 107 # mapped to an action later in the upgrade process.
108 108 name = None
109 109
110 110 # message intended for humans explaining the improvement in more detail,
111 111 # including the implications of it ``FORMAT_VARIANT`` types, should be
112 112 # worded
113 113 # in the present tense.
114 114 description = None
115 115
116 116 # message intended for humans explaining what an upgrade addressing this
117 117 # issue will do. should be worded in the future tense.
118 118 upgrademessage = None
119 119
120 120 # value of current Mercurial default for new repository
121 121 default = None
122 122
123 123 # Message intended for humans which will be shown post an upgrade
124 124 # operation when the improvement will be added
125 125 postupgrademessage = None
126 126
127 127 # Message intended for humans which will be shown post an upgrade
128 128 # operation in which this improvement was removed
129 129 postdowngrademessage = None
130 130
131 131 def __init__(self):
132 132 raise NotImplementedError()
133 133
134 134 @staticmethod
135 135 def fromrepo(repo):
136 136 """current value of the variant in the repository"""
137 137 raise NotImplementedError()
138 138
139 139 @staticmethod
140 140 def fromconfig(repo):
141 141 """current value of the variant in the configuration"""
142 142 raise NotImplementedError()
143 143
144 144
145 145 class requirementformatvariant(formatvariant):
146 146 """formatvariant based on a 'requirement' name.
147 147
148 148 Many format variant are controlled by a 'requirement'. We define a small
149 149 subclass to factor the code.
150 150 """
151 151
152 152 # the requirement that control this format variant
153 153 _requirement = None
154 154
155 155 @staticmethod
156 156 def _newreporequirements(ui):
157 157 return localrepo.newreporequirements(
158 158 ui, localrepo.defaultcreateopts(ui)
159 159 )
160 160
161 161 @classmethod
162 162 def fromrepo(cls, repo):
163 163 assert cls._requirement is not None
164 164 return cls._requirement in repo.requirements
165 165
166 166 @classmethod
167 167 def fromconfig(cls, repo):
168 168 assert cls._requirement is not None
169 169 return cls._requirement in cls._newreporequirements(repo.ui)
170 170
171 171
172 172 @registerformatvariant
173 173 class fncache(requirementformatvariant):
174 174 name = b'fncache'
175 175
176 176 _requirement = b'fncache'
177 177
178 178 default = True
179 179
180 180 description = _(
181 181 b'long and reserved filenames may not work correctly; '
182 182 b'repository performance is sub-optimal'
183 183 )
184 184
185 185 upgrademessage = _(
186 186 b'repository will be more resilient to storing '
187 187 b'certain paths and performance of certain '
188 188 b'operations should be improved'
189 189 )
190 190
191 191
192 192 @registerformatvariant
193 193 class dotencode(requirementformatvariant):
194 194 name = b'dotencode'
195 195
196 196 _requirement = b'dotencode'
197 197
198 198 default = True
199 199
200 200 description = _(
201 201 b'storage of filenames beginning with a period or '
202 202 b'space may not work correctly'
203 203 )
204 204
205 205 upgrademessage = _(
206 206 b'repository will be better able to store files '
207 207 b'beginning with a space or period'
208 208 )
209 209
210 210
211 211 @registerformatvariant
212 212 class generaldelta(requirementformatvariant):
213 213 name = b'generaldelta'
214 214
215 215 _requirement = b'generaldelta'
216 216
217 217 default = True
218 218
219 219 description = _(
220 220 b'deltas within internal storage are unable to '
221 221 b'choose optimal revisions; repository is larger and '
222 222 b'slower than it could be; interaction with other '
223 223 b'repositories may require extra network and CPU '
224 224 b'resources, making "hg push" and "hg pull" slower'
225 225 )
226 226
227 227 upgrademessage = _(
228 228 b'repository storage will be able to create '
229 229 b'optimal deltas; new repository data will be '
230 230 b'smaller and read times should decrease; '
231 231 b'interacting with other repositories using this '
232 232 b'storage model should require less network and '
233 233 b'CPU resources, making "hg push" and "hg pull" '
234 234 b'faster'
235 235 )
236 236
237 237
238 238 @registerformatvariant
239 239 class sharesafe(requirementformatvariant):
240 240 name = b'share-safe'
241 241 _requirement = requirements.SHARESAFE_REQUIREMENT
242 242
243 243 default = False
244 244
245 245 description = _(
246 246 b'old shared repositories do not share source repository '
247 247 b'requirements and config. This leads to various problems '
248 248 b'when the source repository format is upgraded or some new '
249 249 b'extensions are enabled.'
250 250 )
251 251
252 252 upgrademessage = _(
253 253 b'Upgrades a repository to share-safe format so that future '
254 254 b'shares of this repository share its requirements and configs.'
255 255 )
256 256
257 257 postdowngrademessage = _(
258 258 b'repository downgraded to not use share safe mode, '
259 259 b'existing shares will not work and needs to'
260 260 b' be reshared.'
261 261 )
262 262
263 263 postupgrademessage = _(
264 264 b'repository upgraded to share safe mode, existing'
265 265 b' shares will still work in old non-safe mode. '
266 266 b'Re-share existing shares to use them in safe mode'
267 267 b' New shares will be created in safe mode.'
268 268 )
269 269
270 270
271 271 @registerformatvariant
272 272 class sparserevlog(requirementformatvariant):
273 273 name = b'sparserevlog'
274 274
275 275 _requirement = requirements.SPARSEREVLOG_REQUIREMENT
276 276
277 277 default = True
278 278
279 279 description = _(
280 280 b'in order to limit disk reading and memory usage on older '
281 281 b'version, the span of a delta chain from its root to its '
282 282 b'end is limited, whatever the relevant data in this span. '
283 283 b'This can severly limit Mercurial ability to build good '
284 284 b'chain of delta resulting is much more storage space being '
285 285 b'taken and limit reusability of on disk delta during '
286 286 b'exchange.'
287 287 )
288 288
289 289 upgrademessage = _(
290 290 b'Revlog supports delta chain with more unused data '
291 291 b'between payload. These gaps will be skipped at read '
292 292 b'time. This allows for better delta chains, making a '
293 293 b'better compression and faster exchange with server.'
294 294 )
295 295
296 296
297 297 @registerformatvariant
298 298 class sidedata(requirementformatvariant):
299 299 name = b'sidedata'
300 300
301 301 _requirement = requirements.SIDEDATA_REQUIREMENT
302 302
303 303 default = False
304 304
305 305 description = _(
306 306 b'Allows storage of extra data alongside a revision, '
307 307 b'unlocking various caching options.'
308 308 )
309 309
310 310 upgrademessage = _(b'Allows storage of extra data alongside a revision.')
311 311
312 312
313 313 @registerformatvariant
314 314 class persistentnodemap(requirementformatvariant):
315 315 name = b'persistent-nodemap'
316 316
317 317 _requirement = requirements.NODEMAP_REQUIREMENT
318 318
319 319 default = False
320 320
321 321 description = _(
322 322 b'persist the node -> rev mapping on disk to speedup lookup'
323 323 )
324 324
325 325 upgrademessage = _(b'Speedup revision lookup by node id.')
326 326
327 327
328 328 @registerformatvariant
329 329 class copiessdc(requirementformatvariant):
330 330 name = b'copies-sdc'
331 331
332 332 _requirement = requirements.COPIESSDC_REQUIREMENT
333 333
334 334 default = False
335 335
336 336 description = _(b'Stores copies information alongside changesets.')
337 337
338 338 upgrademessage = _(
339 339 b'Allows to use more efficient algorithm to deal with ' b'copy tracing.'
340 340 )
341 341
342 342
343 343 @registerformatvariant
344 344 class removecldeltachain(formatvariant):
345 345 name = b'plain-cl-delta'
346 346
347 347 default = True
348 348
349 349 description = _(
350 350 b'changelog storage is using deltas instead of '
351 351 b'raw entries; changelog reading and any '
352 352 b'operation relying on changelog data are slower '
353 353 b'than they could be'
354 354 )
355 355
356 356 upgrademessage = _(
357 357 b'changelog storage will be reformated to '
358 358 b'store raw entries; changelog reading will be '
359 359 b'faster; changelog size may be reduced'
360 360 )
361 361
362 362 @staticmethod
363 363 def fromrepo(repo):
364 364 # Mercurial 4.0 changed changelogs to not use delta chains. Search for
365 365 # changelogs with deltas.
366 366 cl = repo.changelog
367 367 chainbase = cl.chainbase
368 368 return all(rev == chainbase(rev) for rev in cl)
369 369
370 370 @staticmethod
371 371 def fromconfig(repo):
372 372 return True
373 373
374 374
375 375 @registerformatvariant
376 376 class compressionengine(formatvariant):
377 377 name = b'compression'
378 378 default = b'zlib'
379 379
380 380 description = _(
381 381 b'Compresion algorithm used to compress data. '
382 382 b'Some engine are faster than other'
383 383 )
384 384
385 385 upgrademessage = _(
386 386 b'revlog content will be recompressed with the new algorithm.'
387 387 )
388 388
389 389 @classmethod
390 390 def fromrepo(cls, repo):
391 391 # we allow multiple compression engine requirement to co-exist because
392 392 # strickly speaking, revlog seems to support mixed compression style.
393 393 #
394 394 # The compression used for new entries will be "the last one"
395 395 compression = b'zlib'
396 396 for req in repo.requirements:
397 397 prefix = req.startswith
398 398 if prefix(b'revlog-compression-') or prefix(b'exp-compression-'):
399 399 compression = req.split(b'-', 2)[2]
400 400 return compression
401 401
402 402 @classmethod
403 403 def fromconfig(cls, repo):
404 404 compengines = repo.ui.configlist(b'format', b'revlog-compression')
405 405 # return the first valid value as the selection code would do
406 406 for comp in compengines:
407 407 if comp in util.compengines:
408 408 return comp
409 409
410 410 # no valide compression found lets display it all for clarity
411 411 return b','.join(compengines)
412 412
413 413
414 414 @registerformatvariant
415 415 class compressionlevel(formatvariant):
416 416 name = b'compression-level'
417 417 default = b'default'
418 418
419 419 description = _(b'compression level')
420 420
421 421 upgrademessage = _(b'revlog content will be recompressed')
422 422
423 423 @classmethod
424 424 def fromrepo(cls, repo):
425 425 comp = compressionengine.fromrepo(repo)
426 426 level = None
427 427 if comp == b'zlib':
428 428 level = repo.ui.configint(b'storage', b'revlog.zlib.level')
429 429 elif comp == b'zstd':
430 430 level = repo.ui.configint(b'storage', b'revlog.zstd.level')
431 431 if level is None:
432 432 return b'default'
433 433 return bytes(level)
434 434
435 435 @classmethod
436 436 def fromconfig(cls, repo):
437 437 comp = compressionengine.fromconfig(repo)
438 438 level = None
439 439 if comp == b'zlib':
440 440 level = repo.ui.configint(b'storage', b'revlog.zlib.level')
441 441 elif comp == b'zstd':
442 442 level = repo.ui.configint(b'storage', b'revlog.zstd.level')
443 443 if level is None:
444 444 return b'default'
445 445 return bytes(level)
446 446
447 447
448 448 def find_format_upgrades(repo):
449 449 """returns a list of format upgrades which can be perform on the repo"""
450 450 upgrades = []
451 451
452 452 # We could detect lack of revlogv1 and store here, but they were added
453 453 # in 0.9.2 and we don't support upgrading repos without these
454 454 # requirements, so let's not bother.
455 455
456 456 for fv in allformatvariant:
457 457 if not fv.fromrepo(repo):
458 458 upgrades.append(fv)
459 459
460 460 return upgrades
461 461
462 462
463 463 def find_format_downgrades(repo):
464 464 """returns a list of format downgrades which will be performed on the repo
465 465 because of disabled config option for them"""
466 466
467 467 downgrades = []
468 468
469 469 for fv in allformatvariant:
470 470 if fv.name == b'compression':
471 471 # If there is a compression change between repository
472 472 # and config, destination repository compression will change
473 473 # and current compression will be removed.
474 474 if fv.fromrepo(repo) != fv.fromconfig(repo):
475 475 downgrades.append(fv)
476 476 continue
477 477 # format variant exist in repo but does not exist in new repository
478 478 # config
479 479 if fv.fromrepo(repo) and not fv.fromconfig(repo):
480 480 downgrades.append(fv)
481 481
482 482 return downgrades
483 483
484 484
485 485 ALL_OPTIMISATIONS = []
486 486
487 487
488 488 def register_optimization(obj):
489 489 ALL_OPTIMISATIONS.append(obj)
490 490 return obj
491 491
492 492
493 493 register_optimization(
494 494 improvement(
495 495 name=b're-delta-parent',
496 496 type=OPTIMISATION,
497 497 description=_(
498 498 b'deltas within internal storage will be recalculated to '
499 499 b'choose an optimal base revision where this was not '
500 500 b'already done; the size of the repository may shrink and '
501 501 b'various operations may become faster; the first time '
502 502 b'this optimization is performed could slow down upgrade '
503 503 b'execution considerably; subsequent invocations should '
504 504 b'not run noticeably slower'
505 505 ),
506 506 upgrademessage=_(
507 507 b'deltas within internal storage will choose a new '
508 508 b'base revision if needed'
509 509 ),
510 510 )
511 511 )
512 512
513 513 register_optimization(
514 514 improvement(
515 515 name=b're-delta-multibase',
516 516 type=OPTIMISATION,
517 517 description=_(
518 518 b'deltas within internal storage will be recalculated '
519 519 b'against multiple base revision and the smallest '
520 520 b'difference will be used; the size of the repository may '
521 521 b'shrink significantly when there are many merges; this '
522 522 b'optimization will slow down execution in proportion to '
523 523 b'the number of merges in the repository and the amount '
524 524 b'of files in the repository; this slow down should not '
525 525 b'be significant unless there are tens of thousands of '
526 526 b'files and thousands of merges'
527 527 ),
528 528 upgrademessage=_(
529 529 b'deltas within internal storage will choose an '
530 530 b'optimal delta by computing deltas against multiple '
531 531 b'parents; may slow down execution time '
532 532 b'significantly'
533 533 ),
534 534 )
535 535 )
536 536
537 537 register_optimization(
538 538 improvement(
539 539 name=b're-delta-all',
540 540 type=OPTIMISATION,
541 541 description=_(
542 542 b'deltas within internal storage will always be '
543 543 b'recalculated without reusing prior deltas; this will '
544 544 b'likely make execution run several times slower; this '
545 545 b'optimization is typically not needed'
546 546 ),
547 547 upgrademessage=_(
548 548 b'deltas within internal storage will be fully '
549 549 b'recomputed; this will likely drastically slow down '
550 550 b'execution time'
551 551 ),
552 552 )
553 553 )
554 554
555 555 register_optimization(
556 556 improvement(
557 557 name=b're-delta-fulladd',
558 558 type=OPTIMISATION,
559 559 description=_(
560 560 b'every revision will be re-added as if it was new '
561 561 b'content. It will go through the full storage '
562 562 b'mechanism giving extensions a chance to process it '
563 563 b'(eg. lfs). This is similar to "re-delta-all" but even '
564 564 b'slower since more logic is involved.'
565 565 ),
566 566 upgrademessage=_(
567 567 b'each revision will be added as new content to the '
568 568 b'internal storage; this will likely drastically slow '
569 569 b'down execution time, but some extensions might need '
570 570 b'it'
571 571 ),
572 572 )
573 573 )
574 574
575 575
576 576 def findoptimizations(repo):
577 577 """Determine optimisation that could be used during upgrade"""
578 578 # These are unconditionally added. There is logic later that figures out
579 579 # which ones to apply.
580 580 return list(ALL_OPTIMISATIONS)
581 581
582 582
583 583 def determine_upgrade_actions(
584 584 repo, format_upgrades, optimizations, sourcereqs, destreqs
585 585 ):
586 586 """Determine upgrade actions that will be performed.
587 587
588 588 Given a list of improvements as returned by ``find_format_upgrades`` and
589 589 ``findoptimizations``, determine the list of upgrade actions that
590 590 will be performed.
591 591
592 592 The role of this function is to filter improvements if needed, apply
593 593 recommended optimizations from the improvements list that make sense,
594 594 etc.
595 595
596 596 Returns a list of action names.
597 597 """
598 598 newactions = []
599 599
600 600 for d in format_upgrades:
601 601 name = d._requirement
602 602
603 603 # If the action is a requirement that doesn't show up in the
604 604 # destination requirements, prune the action.
605 605 if name is not None and name not in destreqs:
606 606 continue
607 607
608 608 newactions.append(d)
609 609
610 610 newactions.extend(o for o in sorted(optimizations) if o not in newactions)
611 611
612 612 # FUTURE consider adding some optimizations here for certain transitions.
613 613 # e.g. adding generaldelta could schedule parent redeltas.
614 614
615 615 return newactions
616 616
617 617
618 618 class UpgradeOperation(object):
619 619 """represent the work to be done during an upgrade"""
620 620
621 621 def __init__(
622 622 self,
623 623 ui,
624 624 new_requirements,
625 625 current_requirements,
626 626 upgrade_actions,
627 627 removed_actions,
628 628 revlogs_to_process,
629 backup_store,
629 630 ):
630 631 self.ui = ui
631 632 self.new_requirements = new_requirements
632 633 self.current_requirements = current_requirements
633 634 # list of upgrade actions the operation will perform
634 635 self.upgrade_actions = upgrade_actions
635 636 self._upgrade_actions_names = set([a.name for a in upgrade_actions])
636 637 self.removed_actions = removed_actions
637 638 self.revlogs_to_process = revlogs_to_process
638 639 # requirements which will be added by the operation
639 640 self._added_requirements = (
640 641 self.new_requirements - self.current_requirements
641 642 )
642 643 # requirements which will be removed by the operation
643 644 self._removed_requirements = (
644 645 self.current_requirements - self.new_requirements
645 646 )
646 647 # requirements which will be preserved by the operation
647 648 self._preserved_requirements = (
648 649 self.current_requirements & self.new_requirements
649 650 )
650 651 # optimizations which are not used and it's recommended that they
651 652 # should use them
652 653 all_optimizations = findoptimizations(None)
653 654 self.unused_optimizations = [
654 655 i for i in all_optimizations if i not in self.upgrade_actions
655 656 ]
656 657
657 658 # delta reuse mode of this upgrade operation
658 659 self.delta_reuse_mode = revlog.revlog.DELTAREUSEALWAYS
659 660 if b're-delta-all' in self._upgrade_actions_names:
660 661 self.delta_reuse_mode = revlog.revlog.DELTAREUSENEVER
661 662 elif b're-delta-parent' in self._upgrade_actions_names:
662 663 self.delta_reuse_mode = revlog.revlog.DELTAREUSESAMEREVS
663 664 elif b're-delta-multibase' in self._upgrade_actions_names:
664 665 self.delta_reuse_mode = revlog.revlog.DELTAREUSESAMEREVS
665 666 elif b're-delta-fulladd' in self._upgrade_actions_names:
666 667 self.delta_reuse_mode = revlog.revlog.DELTAREUSEFULLADD
667 668
668 669 # should this operation force re-delta of both parents
669 670 self.force_re_delta_both_parents = (
670 671 b're-delta-multibase' in self._upgrade_actions_names
671 672 )
672 673
674 # should this operation create a backup of the store
675 self.backup_store = backup_store
676
673 677 def _write_labeled(self, l, label):
674 678 """
675 679 Utility function to aid writing of a list under one label
676 680 """
677 681 first = True
678 682 for r in sorted(l):
679 683 if not first:
680 684 self.ui.write(b', ')
681 685 self.ui.write(r, label=label)
682 686 first = False
683 687
684 688 def print_requirements(self):
685 689 self.ui.write(_(b'requirements\n'))
686 690 self.ui.write(_(b' preserved: '))
687 691 self._write_labeled(
688 692 self._preserved_requirements, "upgrade-repo.requirement.preserved"
689 693 )
690 694 self.ui.write((b'\n'))
691 695 if self._removed_requirements:
692 696 self.ui.write(_(b' removed: '))
693 697 self._write_labeled(
694 698 self._removed_requirements, "upgrade-repo.requirement.removed"
695 699 )
696 700 self.ui.write((b'\n'))
697 701 if self._added_requirements:
698 702 self.ui.write(_(b' added: '))
699 703 self._write_labeled(
700 704 self._added_requirements, "upgrade-repo.requirement.added"
701 705 )
702 706 self.ui.write((b'\n'))
703 707 self.ui.write(b'\n')
704 708
705 709 def print_optimisations(self):
706 710 optimisations = [
707 711 a for a in self.upgrade_actions if a.type == OPTIMISATION
708 712 ]
709 713 optimisations.sort(key=lambda a: a.name)
710 714 if optimisations:
711 715 self.ui.write(_(b'optimisations: '))
712 716 self._write_labeled(
713 717 [a.name for a in optimisations],
714 718 "upgrade-repo.optimisation.performed",
715 719 )
716 720 self.ui.write(b'\n\n')
717 721
718 722 def print_upgrade_actions(self):
719 723 for a in self.upgrade_actions:
720 724 self.ui.status(b'%s\n %s\n\n' % (a.name, a.upgrademessage))
721 725
722 726 def print_affected_revlogs(self):
723 727 if not self.revlogs_to_process:
724 728 self.ui.write((b'no revlogs to process\n'))
725 729 else:
726 730 self.ui.write((b'processed revlogs:\n'))
727 731 for r in sorted(self.revlogs_to_process):
728 732 self.ui.write((b' - %s\n' % r))
729 733 self.ui.write((b'\n'))
730 734
731 735 def print_unused_optimizations(self):
732 736 for i in self.unused_optimizations:
733 737 self.ui.status(_(b'%s\n %s\n\n') % (i.name, i.description))
734 738
735 739 def has_upgrade_action(self, name):
736 740 """ Check whether the upgrade operation will perform this action """
737 741 return name in self._upgrade_actions_names
738 742
739 743 def print_post_op_messages(self):
740 744 """ print post upgrade operation warning messages """
741 745 for a in self.upgrade_actions:
742 746 if a.postupgrademessage is not None:
743 747 self.ui.warn(b'%s\n' % a.postupgrademessage)
744 748 for a in self.removed_actions:
745 749 if a.postdowngrademessage is not None:
746 750 self.ui.warn(b'%s\n' % a.postdowngrademessage)
747 751
748 752
749 753 ### Code checking if a repository can got through the upgrade process at all. #
750 754
751 755
752 756 def requiredsourcerequirements(repo):
753 757 """Obtain requirements required to be present to upgrade a repo.
754 758
755 759 An upgrade will not be allowed if the repository doesn't have the
756 760 requirements returned by this function.
757 761 """
758 762 return {
759 763 # Introduced in Mercurial 0.9.2.
760 764 b'revlogv1',
761 765 # Introduced in Mercurial 0.9.2.
762 766 b'store',
763 767 }
764 768
765 769
766 770 def blocksourcerequirements(repo):
767 771 """Obtain requirements that will prevent an upgrade from occurring.
768 772
769 773 An upgrade cannot be performed if the source repository contains a
770 774 requirements in the returned set.
771 775 """
772 776 return {
773 777 # The upgrade code does not yet support these experimental features.
774 778 # This is an artificial limitation.
775 779 requirements.TREEMANIFEST_REQUIREMENT,
776 780 # This was a precursor to generaldelta and was never enabled by default.
777 781 # It should (hopefully) not exist in the wild.
778 782 b'parentdelta',
779 783 # Upgrade should operate on the actual store, not the shared link.
780 784 requirements.SHARED_REQUIREMENT,
781 785 }
782 786
783 787
784 788 def check_source_requirements(repo):
785 789 """Ensure that no existing requirements prevent the repository upgrade"""
786 790
787 791 required = requiredsourcerequirements(repo)
788 792 missingreqs = required - repo.requirements
789 793 if missingreqs:
790 794 msg = _(b'cannot upgrade repository; requirement missing: %s')
791 795 missingreqs = b', '.join(sorted(missingreqs))
792 796 raise error.Abort(msg % missingreqs)
793 797
794 798 blocking = blocksourcerequirements(repo)
795 799 blockingreqs = blocking & repo.requirements
796 800 if blockingreqs:
797 801 m = _(b'cannot upgrade repository; unsupported source requirement: %s')
798 802 blockingreqs = b', '.join(sorted(blockingreqs))
799 803 raise error.Abort(m % blockingreqs)
800 804
801 805
802 806 ### Verify the validity of the planned requirement changes ####################
803 807
804 808
805 809 def supportremovedrequirements(repo):
806 810 """Obtain requirements that can be removed during an upgrade.
807 811
808 812 If an upgrade were to create a repository that dropped a requirement,
809 813 the dropped requirement must appear in the returned set for the upgrade
810 814 to be allowed.
811 815 """
812 816 supported = {
813 817 requirements.SPARSEREVLOG_REQUIREMENT,
814 818 requirements.SIDEDATA_REQUIREMENT,
815 819 requirements.COPIESSDC_REQUIREMENT,
816 820 requirements.NODEMAP_REQUIREMENT,
817 821 requirements.SHARESAFE_REQUIREMENT,
818 822 }
819 823 for name in compression.compengines:
820 824 engine = compression.compengines[name]
821 825 if engine.available() and engine.revlogheader():
822 826 supported.add(b'exp-compression-%s' % name)
823 827 if engine.name() == b'zstd':
824 828 supported.add(b'revlog-compression-zstd')
825 829 return supported
826 830
827 831
828 832 def supporteddestrequirements(repo):
829 833 """Obtain requirements that upgrade supports in the destination.
830 834
831 835 If the result of the upgrade would create requirements not in this set,
832 836 the upgrade is disallowed.
833 837
834 838 Extensions should monkeypatch this to add their custom requirements.
835 839 """
836 840 supported = {
837 841 b'dotencode',
838 842 b'fncache',
839 843 b'generaldelta',
840 844 b'revlogv1',
841 845 b'store',
842 846 requirements.SPARSEREVLOG_REQUIREMENT,
843 847 requirements.SIDEDATA_REQUIREMENT,
844 848 requirements.COPIESSDC_REQUIREMENT,
845 849 requirements.NODEMAP_REQUIREMENT,
846 850 requirements.SHARESAFE_REQUIREMENT,
847 851 }
848 852 for name in compression.compengines:
849 853 engine = compression.compengines[name]
850 854 if engine.available() and engine.revlogheader():
851 855 supported.add(b'exp-compression-%s' % name)
852 856 if engine.name() == b'zstd':
853 857 supported.add(b'revlog-compression-zstd')
854 858 return supported
855 859
856 860
857 861 def allowednewrequirements(repo):
858 862 """Obtain requirements that can be added to a repository during upgrade.
859 863
860 864 This is used to disallow proposed requirements from being added when
861 865 they weren't present before.
862 866
863 867 We use a list of allowed requirement additions instead of a list of known
864 868 bad additions because the whitelist approach is safer and will prevent
865 869 future, unknown requirements from accidentally being added.
866 870 """
867 871 supported = {
868 872 b'dotencode',
869 873 b'fncache',
870 874 b'generaldelta',
871 875 requirements.SPARSEREVLOG_REQUIREMENT,
872 876 requirements.SIDEDATA_REQUIREMENT,
873 877 requirements.COPIESSDC_REQUIREMENT,
874 878 requirements.NODEMAP_REQUIREMENT,
875 879 requirements.SHARESAFE_REQUIREMENT,
876 880 }
877 881 for name in compression.compengines:
878 882 engine = compression.compengines[name]
879 883 if engine.available() and engine.revlogheader():
880 884 supported.add(b'exp-compression-%s' % name)
881 885 if engine.name() == b'zstd':
882 886 supported.add(b'revlog-compression-zstd')
883 887 return supported
884 888
885 889
886 890 def check_requirements_changes(repo, new_reqs):
887 891 old_reqs = repo.requirements
888 892
889 893 support_removal = supportremovedrequirements(repo)
890 894 no_remove_reqs = old_reqs - new_reqs - support_removal
891 895 if no_remove_reqs:
892 896 msg = _(b'cannot upgrade repository; requirement would be removed: %s')
893 897 no_remove_reqs = b', '.join(sorted(no_remove_reqs))
894 898 raise error.Abort(msg % no_remove_reqs)
895 899
896 900 support_addition = allowednewrequirements(repo)
897 901 no_add_reqs = new_reqs - old_reqs - support_addition
898 902 if no_add_reqs:
899 903 m = _(b'cannot upgrade repository; do not support adding requirement: ')
900 904 no_add_reqs = b', '.join(sorted(no_add_reqs))
901 905 raise error.Abort(m + no_add_reqs)
902 906
903 907 supported = supporteddestrequirements(repo)
904 908 unsupported_reqs = new_reqs - supported
905 909 if unsupported_reqs:
906 910 msg = _(
907 911 b'cannot upgrade repository; do not support destination '
908 912 b'requirement: %s'
909 913 )
910 914 unsupported_reqs = b', '.join(sorted(unsupported_reqs))
911 915 raise error.Abort(msg % unsupported_reqs)
@@ -1,521 +1,533 b''
1 1 # upgrade.py - functions for in place upgrade of Mercurial repository
2 2 #
3 3 # Copyright (c) 2016-present, Gregory Szorc
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import stat
11 11
12 12 from ..i18n import _
13 13 from ..pycompat import getattr
14 14 from .. import (
15 15 changelog,
16 16 error,
17 17 filelog,
18 18 manifest,
19 19 metadata,
20 20 pycompat,
21 21 requirements,
22 22 revlog,
23 23 scmutil,
24 24 util,
25 25 vfs as vfsmod,
26 26 )
27 27
28 28
29 29 def _revlogfrompath(repo, path):
30 30 """Obtain a revlog from a repo path.
31 31
32 32 An instance of the appropriate class is returned.
33 33 """
34 34 if path == b'00changelog.i':
35 35 return changelog.changelog(repo.svfs)
36 36 elif path.endswith(b'00manifest.i'):
37 37 mandir = path[: -len(b'00manifest.i')]
38 38 return manifest.manifestrevlog(repo.svfs, tree=mandir)
39 39 else:
40 40 # reverse of "/".join(("data", path + ".i"))
41 41 return filelog.filelog(repo.svfs, path[5:-2])
42 42
43 43
44 44 def _copyrevlog(tr, destrepo, oldrl, unencodedname):
45 45 """copy all relevant files for `oldrl` into `destrepo` store
46 46
47 47 Files are copied "as is" without any transformation. The copy is performed
48 48 without extra checks. Callers are responsible for making sure the copied
49 49 content is compatible with format of the destination repository.
50 50 """
51 51 oldrl = getattr(oldrl, '_revlog', oldrl)
52 52 newrl = _revlogfrompath(destrepo, unencodedname)
53 53 newrl = getattr(newrl, '_revlog', newrl)
54 54
55 55 oldvfs = oldrl.opener
56 56 newvfs = newrl.opener
57 57 oldindex = oldvfs.join(oldrl.indexfile)
58 58 newindex = newvfs.join(newrl.indexfile)
59 59 olddata = oldvfs.join(oldrl.datafile)
60 60 newdata = newvfs.join(newrl.datafile)
61 61
62 62 with newvfs(newrl.indexfile, b'w'):
63 63 pass # create all the directories
64 64
65 65 util.copyfile(oldindex, newindex)
66 66 copydata = oldrl.opener.exists(oldrl.datafile)
67 67 if copydata:
68 68 util.copyfile(olddata, newdata)
69 69
70 70 if not (
71 71 unencodedname.endswith(b'00changelog.i')
72 72 or unencodedname.endswith(b'00manifest.i')
73 73 ):
74 74 destrepo.svfs.fncache.add(unencodedname)
75 75 if copydata:
76 76 destrepo.svfs.fncache.add(unencodedname[:-2] + b'.d')
77 77
78 78
79 79 UPGRADE_CHANGELOG = b"changelog"
80 80 UPGRADE_MANIFEST = b"manifest"
81 81 UPGRADE_FILELOGS = b"all-filelogs"
82 82
83 83 UPGRADE_ALL_REVLOGS = frozenset(
84 84 [UPGRADE_CHANGELOG, UPGRADE_MANIFEST, UPGRADE_FILELOGS]
85 85 )
86 86
87 87
88 88 def getsidedatacompanion(srcrepo, dstrepo):
89 89 sidedatacompanion = None
90 90 removedreqs = srcrepo.requirements - dstrepo.requirements
91 91 addedreqs = dstrepo.requirements - srcrepo.requirements
92 92 if requirements.SIDEDATA_REQUIREMENT in removedreqs:
93 93
94 94 def sidedatacompanion(rl, rev):
95 95 rl = getattr(rl, '_revlog', rl)
96 96 if rl.flags(rev) & revlog.REVIDX_SIDEDATA:
97 97 return True, (), {}, 0, 0
98 98 return False, (), {}, 0, 0
99 99
100 100 elif requirements.COPIESSDC_REQUIREMENT in addedreqs:
101 101 sidedatacompanion = metadata.getsidedataadder(srcrepo, dstrepo)
102 102 elif requirements.COPIESSDC_REQUIREMENT in removedreqs:
103 103 sidedatacompanion = metadata.getsidedataremover(srcrepo, dstrepo)
104 104 return sidedatacompanion
105 105
106 106
107 107 def matchrevlog(revlogfilter, entry):
108 108 """check if a revlog is selected for cloning.
109 109
110 110 In other words, are there any updates which need to be done on revlog
111 111 or it can be blindly copied.
112 112
113 113 The store entry is checked against the passed filter"""
114 114 if entry.endswith(b'00changelog.i'):
115 115 return UPGRADE_CHANGELOG in revlogfilter
116 116 elif entry.endswith(b'00manifest.i'):
117 117 return UPGRADE_MANIFEST in revlogfilter
118 118 return UPGRADE_FILELOGS in revlogfilter
119 119
120 120
121 121 def _perform_clone(
122 122 ui,
123 123 dstrepo,
124 124 tr,
125 125 old_revlog,
126 126 unencoded,
127 127 upgrade_op,
128 128 sidedatacompanion,
129 129 oncopiedrevision,
130 130 ):
131 131 """ returns the new revlog object created"""
132 132 newrl = None
133 133 if matchrevlog(upgrade_op.revlogs_to_process, unencoded):
134 134 ui.note(
135 135 _(b'cloning %d revisions from %s\n') % (len(old_revlog), unencoded)
136 136 )
137 137 newrl = _revlogfrompath(dstrepo, unencoded)
138 138 old_revlog.clone(
139 139 tr,
140 140 newrl,
141 141 addrevisioncb=oncopiedrevision,
142 142 deltareuse=upgrade_op.delta_reuse_mode,
143 143 forcedeltabothparents=upgrade_op.force_re_delta_both_parents,
144 144 sidedatacompanion=sidedatacompanion,
145 145 )
146 146 else:
147 147 msg = _(b'blindly copying %s containing %i revisions\n')
148 148 ui.note(msg % (unencoded, len(old_revlog)))
149 149 _copyrevlog(tr, dstrepo, old_revlog, unencoded)
150 150
151 151 newrl = _revlogfrompath(dstrepo, unencoded)
152 152 return newrl
153 153
154 154
155 155 def _clonerevlogs(
156 156 ui,
157 157 srcrepo,
158 158 dstrepo,
159 159 tr,
160 160 upgrade_op,
161 161 ):
162 162 """Copy revlogs between 2 repos."""
163 163 revcount = 0
164 164 srcsize = 0
165 165 srcrawsize = 0
166 166 dstsize = 0
167 167 fcount = 0
168 168 frevcount = 0
169 169 fsrcsize = 0
170 170 frawsize = 0
171 171 fdstsize = 0
172 172 mcount = 0
173 173 mrevcount = 0
174 174 msrcsize = 0
175 175 mrawsize = 0
176 176 mdstsize = 0
177 177 crevcount = 0
178 178 csrcsize = 0
179 179 crawsize = 0
180 180 cdstsize = 0
181 181
182 182 alldatafiles = list(srcrepo.store.walk())
183 183 # mapping of data files which needs to be cloned
184 184 # key is unencoded filename
185 185 # value is revlog_object_from_srcrepo
186 186 manifests = {}
187 187 changelogs = {}
188 188 filelogs = {}
189 189
190 190 # Perform a pass to collect metadata. This validates we can open all
191 191 # source files and allows a unified progress bar to be displayed.
192 192 for unencoded, encoded, size in alldatafiles:
193 193 if not unencoded.endswith(b'.i'):
194 194 continue
195 195
196 196 rl = _revlogfrompath(srcrepo, unencoded)
197 197
198 198 info = rl.storageinfo(
199 199 exclusivefiles=True,
200 200 revisionscount=True,
201 201 trackedsize=True,
202 202 storedsize=True,
203 203 )
204 204
205 205 revcount += info[b'revisionscount'] or 0
206 206 datasize = info[b'storedsize'] or 0
207 207 rawsize = info[b'trackedsize'] or 0
208 208
209 209 srcsize += datasize
210 210 srcrawsize += rawsize
211 211
212 212 # This is for the separate progress bars.
213 213 if isinstance(rl, changelog.changelog):
214 214 changelogs[unencoded] = rl
215 215 crevcount += len(rl)
216 216 csrcsize += datasize
217 217 crawsize += rawsize
218 218 elif isinstance(rl, manifest.manifestrevlog):
219 219 manifests[unencoded] = rl
220 220 mcount += 1
221 221 mrevcount += len(rl)
222 222 msrcsize += datasize
223 223 mrawsize += rawsize
224 224 elif isinstance(rl, filelog.filelog):
225 225 filelogs[unencoded] = rl
226 226 fcount += 1
227 227 frevcount += len(rl)
228 228 fsrcsize += datasize
229 229 frawsize += rawsize
230 230 else:
231 231 error.ProgrammingError(b'unknown revlog type')
232 232
233 233 if not revcount:
234 234 return
235 235
236 236 ui.status(
237 237 _(
238 238 b'migrating %d total revisions (%d in filelogs, %d in manifests, '
239 239 b'%d in changelog)\n'
240 240 )
241 241 % (revcount, frevcount, mrevcount, crevcount)
242 242 )
243 243 ui.status(
244 244 _(b'migrating %s in store; %s tracked data\n')
245 245 % ((util.bytecount(srcsize), util.bytecount(srcrawsize)))
246 246 )
247 247
248 248 # Used to keep track of progress.
249 249 progress = None
250 250
251 251 def oncopiedrevision(rl, rev, node):
252 252 progress.increment()
253 253
254 254 sidedatacompanion = getsidedatacompanion(srcrepo, dstrepo)
255 255
256 256 # Migrating filelogs
257 257 ui.status(
258 258 _(
259 259 b'migrating %d filelogs containing %d revisions '
260 260 b'(%s in store; %s tracked data)\n'
261 261 )
262 262 % (
263 263 fcount,
264 264 frevcount,
265 265 util.bytecount(fsrcsize),
266 266 util.bytecount(frawsize),
267 267 )
268 268 )
269 269 progress = srcrepo.ui.makeprogress(_(b'file revisions'), total=frevcount)
270 270 for unencoded, oldrl in sorted(filelogs.items()):
271 271 newrl = _perform_clone(
272 272 ui,
273 273 dstrepo,
274 274 tr,
275 275 oldrl,
276 276 unencoded,
277 277 upgrade_op,
278 278 sidedatacompanion,
279 279 oncopiedrevision,
280 280 )
281 281 info = newrl.storageinfo(storedsize=True)
282 282 fdstsize += info[b'storedsize'] or 0
283 283 ui.status(
284 284 _(
285 285 b'finished migrating %d filelog revisions across %d '
286 286 b'filelogs; change in size: %s\n'
287 287 )
288 288 % (frevcount, fcount, util.bytecount(fdstsize - fsrcsize))
289 289 )
290 290
291 291 # Migrating manifests
292 292 ui.status(
293 293 _(
294 294 b'migrating %d manifests containing %d revisions '
295 295 b'(%s in store; %s tracked data)\n'
296 296 )
297 297 % (
298 298 mcount,
299 299 mrevcount,
300 300 util.bytecount(msrcsize),
301 301 util.bytecount(mrawsize),
302 302 )
303 303 )
304 304 if progress:
305 305 progress.complete()
306 306 progress = srcrepo.ui.makeprogress(
307 307 _(b'manifest revisions'), total=mrevcount
308 308 )
309 309 for unencoded, oldrl in sorted(manifests.items()):
310 310 newrl = _perform_clone(
311 311 ui,
312 312 dstrepo,
313 313 tr,
314 314 oldrl,
315 315 unencoded,
316 316 upgrade_op,
317 317 sidedatacompanion,
318 318 oncopiedrevision,
319 319 )
320 320 info = newrl.storageinfo(storedsize=True)
321 321 mdstsize += info[b'storedsize'] or 0
322 322 ui.status(
323 323 _(
324 324 b'finished migrating %d manifest revisions across %d '
325 325 b'manifests; change in size: %s\n'
326 326 )
327 327 % (mrevcount, mcount, util.bytecount(mdstsize - msrcsize))
328 328 )
329 329
330 330 # Migrating changelog
331 331 ui.status(
332 332 _(
333 333 b'migrating changelog containing %d revisions '
334 334 b'(%s in store; %s tracked data)\n'
335 335 )
336 336 % (
337 337 crevcount,
338 338 util.bytecount(csrcsize),
339 339 util.bytecount(crawsize),
340 340 )
341 341 )
342 342 if progress:
343 343 progress.complete()
344 344 progress = srcrepo.ui.makeprogress(
345 345 _(b'changelog revisions'), total=crevcount
346 346 )
347 347 for unencoded, oldrl in sorted(changelogs.items()):
348 348 newrl = _perform_clone(
349 349 ui,
350 350 dstrepo,
351 351 tr,
352 352 oldrl,
353 353 unencoded,
354 354 upgrade_op,
355 355 sidedatacompanion,
356 356 oncopiedrevision,
357 357 )
358 358 info = newrl.storageinfo(storedsize=True)
359 359 cdstsize += info[b'storedsize'] or 0
360 360 progress.complete()
361 361 ui.status(
362 362 _(
363 363 b'finished migrating %d changelog revisions; change in size: '
364 364 b'%s\n'
365 365 )
366 366 % (crevcount, util.bytecount(cdstsize - csrcsize))
367 367 )
368 368
369 369 dstsize = fdstsize + mdstsize + cdstsize
370 370 ui.status(
371 371 _(
372 372 b'finished migrating %d total revisions; total change in store '
373 373 b'size: %s\n'
374 374 )
375 375 % (revcount, util.bytecount(dstsize - srcsize))
376 376 )
377 377
378 378
379 379 def _files_to_copy_post_revlog_clone(srcrepo):
380 380 """yields files which should be copied to destination after revlogs
381 381 are cloned"""
382 382 for path, kind, st in sorted(srcrepo.store.vfs.readdir(b'', stat=True)):
383 383 # don't copy revlogs as they are already cloned
384 384 if path.endswith((b'.i', b'.d', b'.n', b'.nd')):
385 385 continue
386 386 # Skip transaction related files.
387 387 if path.startswith(b'undo'):
388 388 continue
389 389 # Only copy regular files.
390 390 if kind != stat.S_IFREG:
391 391 continue
392 392 # Skip other skipped files.
393 393 if path in (b'lock', b'fncache'):
394 394 continue
395 395 # TODO: should we skip cache too?
396 396
397 397 yield path
398 398
399 399
400 400 def _replacestores(currentrepo, upgradedrepo, backupvfs, upgrade_op):
401 401 """Replace the stores after current repository is upgraded
402 402
403 403 Creates a backup of current repository store at backup path
404 404 Replaces upgraded store files in current repo from upgraded one
405 405
406 406 Arguments:
407 407 currentrepo: repo object of current repository
408 408 upgradedrepo: repo object of the upgraded data
409 409 backupvfs: vfs object for the backup path
410 410 upgrade_op: upgrade operation object
411 411 to be used to decide what all is upgraded
412 412 """
413 413 # TODO: don't blindly rename everything in store
414 414 # There can be upgrades where store is not touched at all
415 if upgrade_op.backup_store:
415 416 util.rename(currentrepo.spath, backupvfs.join(b'store'))
417 else:
418 currentrepo.vfs.rmtree(b'store', forcibly=True)
416 419 util.rename(upgradedrepo.spath, currentrepo.spath)
417 420
418 421
419 422 def finishdatamigration(ui, srcrepo, dstrepo, requirements):
420 423 """Hook point for extensions to perform additional actions during upgrade.
421 424
422 425 This function is called after revlogs and store files have been copied but
423 426 before the new store is swapped into the original location.
424 427 """
425 428
426 429
427 430 def upgrade(ui, srcrepo, dstrepo, upgrade_op):
428 431 """Do the low-level work of upgrading a repository.
429 432
430 433 The upgrade is effectively performed as a copy between a source
431 434 repository and a temporary destination repository.
432 435
433 436 The source repository is unmodified for as long as possible so the
434 437 upgrade can abort at any time without causing loss of service for
435 438 readers and without corrupting the source repository.
436 439 """
437 440 assert srcrepo.currentwlock()
438 441 assert dstrepo.currentwlock()
442 backuppath = None
443 backupvfs = None
439 444
440 445 ui.status(
441 446 _(
442 447 b'(it is safe to interrupt this process any time before '
443 448 b'data migration completes)\n'
444 449 )
445 450 )
446 451
447 452 with dstrepo.transaction(b'upgrade') as tr:
448 453 _clonerevlogs(
449 454 ui,
450 455 srcrepo,
451 456 dstrepo,
452 457 tr,
453 458 upgrade_op,
454 459 )
455 460
456 461 # Now copy other files in the store directory.
457 462 for p in _files_to_copy_post_revlog_clone(srcrepo):
458 463 srcrepo.ui.status(_(b'copying %s\n') % p)
459 464 src = srcrepo.store.rawvfs.join(p)
460 465 dst = dstrepo.store.rawvfs.join(p)
461 466 util.copyfile(src, dst, copystat=True)
462 467
463 468 finishdatamigration(ui, srcrepo, dstrepo, requirements)
464 469
465 470 ui.status(_(b'data fully upgraded in a temporary repository\n'))
466 471
467 backuppath = pycompat.mkdtemp(prefix=b'upgradebackup.', dir=srcrepo.path)
472 if upgrade_op.backup_store:
473 backuppath = pycompat.mkdtemp(
474 prefix=b'upgradebackup.', dir=srcrepo.path
475 )
468 476 backupvfs = vfsmod.vfs(backuppath)
469 477
470 478 # Make a backup of requires file first, as it is the first to be modified.
471 util.copyfile(srcrepo.vfs.join(b'requires'), backupvfs.join(b'requires'))
479 util.copyfile(
480 srcrepo.vfs.join(b'requires'), backupvfs.join(b'requires')
481 )
472 482
473 483 # We install an arbitrary requirement that clients must not support
474 484 # as a mechanism to lock out new clients during the data swap. This is
475 485 # better than allowing a client to continue while the repository is in
476 486 # an inconsistent state.
477 487 ui.status(
478 488 _(
479 489 b'marking source repository as being upgraded; clients will be '
480 490 b'unable to read from repository\n'
481 491 )
482 492 )
483 493 scmutil.writereporequirements(
484 494 srcrepo, srcrepo.requirements | {b'upgradeinprogress'}
485 495 )
486 496
487 497 ui.status(_(b'starting in-place swap of repository data\n'))
498 if upgrade_op.backup_store:
488 499 ui.status(_(b'replaced files will be backed up at %s\n') % backuppath)
489 500
490 501 # Now swap in the new store directory. Doing it as a rename should make
491 502 # the operation nearly instantaneous and atomic (at least in well-behaved
492 503 # environments).
493 504 ui.status(_(b'replacing store...\n'))
494 505 tstart = util.timer()
495 506 _replacestores(srcrepo, dstrepo, backupvfs, upgrade_op)
496 507 elapsed = util.timer() - tstart
497 508 ui.status(
498 509 _(
499 510 b'store replacement complete; repository was inconsistent for '
500 511 b'%0.1fs\n'
501 512 )
502 513 % elapsed
503 514 )
504 515
505 516 # We first write the requirements file. Any new requirements will lock
506 517 # out legacy clients.
507 518 ui.status(
508 519 _(
509 520 b'finalizing requirements file and making repository readable '
510 521 b'again\n'
511 522 )
512 523 )
513 524 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
514 525
526 if upgrade_op.backup_store:
515 527 # The lock file from the old store won't be removed because nothing has a
516 528 # reference to its new location. So clean it up manually. Alternatively, we
517 529 # could update srcrepo.svfs and other variables to point to the new
518 530 # location. This is simpler.
519 531 backupvfs.unlink(b'store/lock')
520 532
521 533 return backuppath
@@ -1,1527 +1,1513 b''
1 1 #require no-reposimplestore
2 2
3 3 $ cat >> $HGRCPATH << EOF
4 4 > [extensions]
5 5 > share =
6 6 > EOF
7 7
8 8 store and revlogv1 are required in source
9 9
10 10 $ hg --config format.usestore=false init no-store
11 11 $ hg -R no-store debugupgraderepo
12 12 abort: cannot upgrade repository; requirement missing: store
13 13 [255]
14 14
15 15 $ hg init no-revlogv1
16 16 $ cat > no-revlogv1/.hg/requires << EOF
17 17 > dotencode
18 18 > fncache
19 19 > generaldelta
20 20 > store
21 21 > EOF
22 22
23 23 $ hg -R no-revlogv1 debugupgraderepo
24 24 abort: cannot upgrade repository; requirement missing: revlogv1
25 25 [255]
26 26
27 27 Cannot upgrade shared repositories
28 28
29 29 $ hg init share-parent
30 30 $ hg -q share share-parent share-child
31 31
32 32 $ hg -R share-child debugupgraderepo
33 33 abort: cannot upgrade repository; unsupported source requirement: shared
34 34 [255]
35 35
36 36 Do not yet support upgrading treemanifest repos
37 37
38 38 $ hg --config experimental.treemanifest=true init treemanifest
39 39 $ hg -R treemanifest debugupgraderepo
40 40 abort: cannot upgrade repository; unsupported source requirement: treemanifest
41 41 [255]
42 42
43 43 Cannot add treemanifest requirement during upgrade
44 44
45 45 $ hg init disallowaddedreq
46 46 $ hg -R disallowaddedreq --config experimental.treemanifest=true debugupgraderepo
47 47 abort: cannot upgrade repository; do not support adding requirement: treemanifest
48 48 [255]
49 49
50 50 An upgrade of a repository created with recommended settings only suggests optimizations
51 51
52 52 $ hg init empty
53 53 $ cd empty
54 54 $ hg debugformat
55 55 format-variant repo
56 56 fncache: yes
57 57 dotencode: yes
58 58 generaldelta: yes
59 59 share-safe: no
60 60 sparserevlog: yes
61 61 sidedata: no
62 62 persistent-nodemap: no
63 63 copies-sdc: no
64 64 plain-cl-delta: yes
65 65 compression: zlib
66 66 compression-level: default
67 67 $ hg debugformat --verbose
68 68 format-variant repo config default
69 69 fncache: yes yes yes
70 70 dotencode: yes yes yes
71 71 generaldelta: yes yes yes
72 72 share-safe: no no no
73 73 sparserevlog: yes yes yes
74 74 sidedata: no no no
75 75 persistent-nodemap: no no no
76 76 copies-sdc: no no no
77 77 plain-cl-delta: yes yes yes
78 78 compression: zlib zlib zlib
79 79 compression-level: default default default
80 80 $ hg debugformat --verbose --config format.usefncache=no
81 81 format-variant repo config default
82 82 fncache: yes no yes
83 83 dotencode: yes no yes
84 84 generaldelta: yes yes yes
85 85 share-safe: no no no
86 86 sparserevlog: yes yes yes
87 87 sidedata: no no no
88 88 persistent-nodemap: no no no
89 89 copies-sdc: no no no
90 90 plain-cl-delta: yes yes yes
91 91 compression: zlib zlib zlib
92 92 compression-level: default default default
93 93 $ hg debugformat --verbose --config format.usefncache=no --color=debug
94 94 format-variant repo config default
95 95 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
96 96 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| yes][formatvariant.config.special| no][formatvariant.default| yes]
97 97 [formatvariant.name.uptodate|generaldelta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
98 98 [formatvariant.name.uptodate|share-safe: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
99 99 [formatvariant.name.uptodate|sparserevlog: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
100 100 [formatvariant.name.uptodate|sidedata: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
101 101 [formatvariant.name.uptodate|persistent-nodemap:][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
102 102 [formatvariant.name.uptodate|copies-sdc: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
103 103 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
104 104 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib]
105 105 [formatvariant.name.uptodate|compression-level: ][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
106 106 $ hg debugformat -Tjson
107 107 [
108 108 {
109 109 "config": true,
110 110 "default": true,
111 111 "name": "fncache",
112 112 "repo": true
113 113 },
114 114 {
115 115 "config": true,
116 116 "default": true,
117 117 "name": "dotencode",
118 118 "repo": true
119 119 },
120 120 {
121 121 "config": true,
122 122 "default": true,
123 123 "name": "generaldelta",
124 124 "repo": true
125 125 },
126 126 {
127 127 "config": false,
128 128 "default": false,
129 129 "name": "share-safe",
130 130 "repo": false
131 131 },
132 132 {
133 133 "config": true,
134 134 "default": true,
135 135 "name": "sparserevlog",
136 136 "repo": true
137 137 },
138 138 {
139 139 "config": false,
140 140 "default": false,
141 141 "name": "sidedata",
142 142 "repo": false
143 143 },
144 144 {
145 145 "config": false,
146 146 "default": false,
147 147 "name": "persistent-nodemap",
148 148 "repo": false
149 149 },
150 150 {
151 151 "config": false,
152 152 "default": false,
153 153 "name": "copies-sdc",
154 154 "repo": false
155 155 },
156 156 {
157 157 "config": true,
158 158 "default": true,
159 159 "name": "plain-cl-delta",
160 160 "repo": true
161 161 },
162 162 {
163 163 "config": "zlib",
164 164 "default": "zlib",
165 165 "name": "compression",
166 166 "repo": "zlib"
167 167 },
168 168 {
169 169 "config": "default",
170 170 "default": "default",
171 171 "name": "compression-level",
172 172 "repo": "default"
173 173 }
174 174 ]
175 175 $ hg debugupgraderepo
176 176 (no format upgrades found in existing repository)
177 177 performing an upgrade with "--run" will make the following changes:
178 178
179 179 requirements
180 180 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
181 181
182 182 processed revlogs:
183 183 - all-filelogs
184 184 - changelog
185 185 - manifest
186 186
187 187 additional optimizations are available by specifying "--optimize <name>":
188 188
189 189 re-delta-parent
190 190 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
191 191
192 192 re-delta-multibase
193 193 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
194 194
195 195 re-delta-all
196 196 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
197 197
198 198 re-delta-fulladd
199 199 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
200 200
201 201
202 202 $ hg debugupgraderepo --quiet
203 203 requirements
204 204 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
205 205
206 206 processed revlogs:
207 207 - all-filelogs
208 208 - changelog
209 209 - manifest
210 210
211 211
212 212 --optimize can be used to add optimizations
213 213
214 214 $ hg debugupgrade --optimize 're-delta-parent'
215 215 (no format upgrades found in existing repository)
216 216 performing an upgrade with "--run" will make the following changes:
217 217
218 218 requirements
219 219 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
220 220
221 221 optimisations: re-delta-parent
222 222
223 223 re-delta-parent
224 224 deltas within internal storage will choose a new base revision if needed
225 225
226 226 processed revlogs:
227 227 - all-filelogs
228 228 - changelog
229 229 - manifest
230 230
231 231 additional optimizations are available by specifying "--optimize <name>":
232 232
233 233 re-delta-multibase
234 234 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
235 235
236 236 re-delta-all
237 237 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
238 238
239 239 re-delta-fulladd
240 240 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
241 241
242 242
243 243 modern form of the option
244 244
245 245 $ hg debugupgrade --optimize re-delta-parent
246 246 (no format upgrades found in existing repository)
247 247 performing an upgrade with "--run" will make the following changes:
248 248
249 249 requirements
250 250 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
251 251
252 252 optimisations: re-delta-parent
253 253
254 254 re-delta-parent
255 255 deltas within internal storage will choose a new base revision if needed
256 256
257 257 processed revlogs:
258 258 - all-filelogs
259 259 - changelog
260 260 - manifest
261 261
262 262 additional optimizations are available by specifying "--optimize <name>":
263 263
264 264 re-delta-multibase
265 265 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
266 266
267 267 re-delta-all
268 268 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
269 269
270 270 re-delta-fulladd
271 271 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
272 272
273 273 $ hg debugupgrade --optimize re-delta-parent --quiet
274 274 requirements
275 275 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
276 276
277 277 optimisations: re-delta-parent
278 278
279 279 processed revlogs:
280 280 - all-filelogs
281 281 - changelog
282 282 - manifest
283 283
284 284
285 285 unknown optimization:
286 286
287 287 $ hg debugupgrade --optimize foobar
288 288 abort: unknown optimization action requested: foobar
289 289 (run without arguments to see valid optimizations)
290 290 [255]
291 291
292 292 Various sub-optimal detections work
293 293
294 294 $ cat > .hg/requires << EOF
295 295 > revlogv1
296 296 > store
297 297 > EOF
298 298
299 299 $ hg debugformat
300 300 format-variant repo
301 301 fncache: no
302 302 dotencode: no
303 303 generaldelta: no
304 304 share-safe: no
305 305 sparserevlog: no
306 306 sidedata: no
307 307 persistent-nodemap: no
308 308 copies-sdc: no
309 309 plain-cl-delta: yes
310 310 compression: zlib
311 311 compression-level: default
312 312 $ hg debugformat --verbose
313 313 format-variant repo config default
314 314 fncache: no yes yes
315 315 dotencode: no yes yes
316 316 generaldelta: no yes yes
317 317 share-safe: no no no
318 318 sparserevlog: no yes yes
319 319 sidedata: no no no
320 320 persistent-nodemap: no no no
321 321 copies-sdc: no no no
322 322 plain-cl-delta: yes yes yes
323 323 compression: zlib zlib zlib
324 324 compression-level: default default default
325 325 $ hg debugformat --verbose --config format.usegeneraldelta=no
326 326 format-variant repo config default
327 327 fncache: no yes yes
328 328 dotencode: no yes yes
329 329 generaldelta: no no yes
330 330 share-safe: no no no
331 331 sparserevlog: no no yes
332 332 sidedata: no no no
333 333 persistent-nodemap: no no no
334 334 copies-sdc: no no no
335 335 plain-cl-delta: yes yes yes
336 336 compression: zlib zlib zlib
337 337 compression-level: default default default
338 338 $ hg debugformat --verbose --config format.usegeneraldelta=no --color=debug
339 339 format-variant repo config default
340 340 [formatvariant.name.mismatchconfig|fncache: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
341 341 [formatvariant.name.mismatchconfig|dotencode: ][formatvariant.repo.mismatchconfig| no][formatvariant.config.default| yes][formatvariant.default| yes]
342 342 [formatvariant.name.mismatchdefault|generaldelta: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
343 343 [formatvariant.name.uptodate|share-safe: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
344 344 [formatvariant.name.mismatchdefault|sparserevlog: ][formatvariant.repo.mismatchdefault| no][formatvariant.config.special| no][formatvariant.default| yes]
345 345 [formatvariant.name.uptodate|sidedata: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
346 346 [formatvariant.name.uptodate|persistent-nodemap:][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
347 347 [formatvariant.name.uptodate|copies-sdc: ][formatvariant.repo.uptodate| no][formatvariant.config.default| no][formatvariant.default| no]
348 348 [formatvariant.name.uptodate|plain-cl-delta: ][formatvariant.repo.uptodate| yes][formatvariant.config.default| yes][formatvariant.default| yes]
349 349 [formatvariant.name.uptodate|compression: ][formatvariant.repo.uptodate| zlib][formatvariant.config.default| zlib][formatvariant.default| zlib]
350 350 [formatvariant.name.uptodate|compression-level: ][formatvariant.repo.uptodate| default][formatvariant.config.default| default][formatvariant.default| default]
351 351 $ hg debugupgraderepo
352 352 repository lacks features recommended by current config options:
353 353
354 354 fncache
355 355 long and reserved filenames may not work correctly; repository performance is sub-optimal
356 356
357 357 dotencode
358 358 storage of filenames beginning with a period or space may not work correctly
359 359
360 360 generaldelta
361 361 deltas within internal storage are unable to choose optimal revisions; repository is larger and slower than it could be; interaction with other repositories may require extra network and CPU resources, making "hg push" and "hg pull" slower
362 362
363 363 sparserevlog
364 364 in order to limit disk reading and memory usage on older version, the span of a delta chain from its root to its end is limited, whatever the relevant data in this span. This can severly limit Mercurial ability to build good chain of delta resulting is much more storage space being taken and limit reusability of on disk delta during exchange.
365 365
366 366
367 367 performing an upgrade with "--run" will make the following changes:
368 368
369 369 requirements
370 370 preserved: revlogv1, store
371 371 added: dotencode, fncache, generaldelta, sparserevlog
372 372
373 373 fncache
374 374 repository will be more resilient to storing certain paths and performance of certain operations should be improved
375 375
376 376 dotencode
377 377 repository will be better able to store files beginning with a space or period
378 378
379 379 generaldelta
380 380 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
381 381
382 382 sparserevlog
383 383 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
384 384
385 385 processed revlogs:
386 386 - all-filelogs
387 387 - changelog
388 388 - manifest
389 389
390 390 additional optimizations are available by specifying "--optimize <name>":
391 391
392 392 re-delta-parent
393 393 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
394 394
395 395 re-delta-multibase
396 396 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
397 397
398 398 re-delta-all
399 399 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
400 400
401 401 re-delta-fulladd
402 402 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
403 403
404 404 $ hg debugupgraderepo --quiet
405 405 requirements
406 406 preserved: revlogv1, store
407 407 added: dotencode, fncache, generaldelta, sparserevlog
408 408
409 409 processed revlogs:
410 410 - all-filelogs
411 411 - changelog
412 412 - manifest
413 413
414 414
415 415 $ hg --config format.dotencode=false debugupgraderepo
416 416 repository lacks features recommended by current config options:
417 417
418 418 fncache
419 419 long and reserved filenames may not work correctly; repository performance is sub-optimal
420 420
421 421 generaldelta
422 422 deltas within internal storage are unable to choose optimal revisions; repository is larger and slower than it could be; interaction with other repositories may require extra network and CPU resources, making "hg push" and "hg pull" slower
423 423
424 424 sparserevlog
425 425 in order to limit disk reading and memory usage on older version, the span of a delta chain from its root to its end is limited, whatever the relevant data in this span. This can severly limit Mercurial ability to build good chain of delta resulting is much more storage space being taken and limit reusability of on disk delta during exchange.
426 426
427 427 repository lacks features used by the default config options:
428 428
429 429 dotencode
430 430 storage of filenames beginning with a period or space may not work correctly
431 431
432 432
433 433 performing an upgrade with "--run" will make the following changes:
434 434
435 435 requirements
436 436 preserved: revlogv1, store
437 437 added: fncache, generaldelta, sparserevlog
438 438
439 439 fncache
440 440 repository will be more resilient to storing certain paths and performance of certain operations should be improved
441 441
442 442 generaldelta
443 443 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
444 444
445 445 sparserevlog
446 446 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
447 447
448 448 processed revlogs:
449 449 - all-filelogs
450 450 - changelog
451 451 - manifest
452 452
453 453 additional optimizations are available by specifying "--optimize <name>":
454 454
455 455 re-delta-parent
456 456 deltas within internal storage will be recalculated to choose an optimal base revision where this was not already done; the size of the repository may shrink and various operations may become faster; the first time this optimization is performed could slow down upgrade execution considerably; subsequent invocations should not run noticeably slower
457 457
458 458 re-delta-multibase
459 459 deltas within internal storage will be recalculated against multiple base revision and the smallest difference will be used; the size of the repository may shrink significantly when there are many merges; this optimization will slow down execution in proportion to the number of merges in the repository and the amount of files in the repository; this slow down should not be significant unless there are tens of thousands of files and thousands of merges
460 460
461 461 re-delta-all
462 462 deltas within internal storage will always be recalculated without reusing prior deltas; this will likely make execution run several times slower; this optimization is typically not needed
463 463
464 464 re-delta-fulladd
465 465 every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
466 466
467 467
468 468 $ cd ..
469 469
470 470 Upgrading a repository that is already modern essentially no-ops
471 471
472 472 $ hg init modern
473 473 $ hg -R modern debugupgraderepo --run
474 474 nothing to do
475 475
476 476 Upgrading a repository to generaldelta works
477 477
478 478 $ hg --config format.usegeneraldelta=false init upgradegd
479 479 $ cd upgradegd
480 480 $ touch f0
481 481 $ hg -q commit -A -m initial
482 482 $ mkdir FooBarDirectory.d
483 483 $ touch FooBarDirectory.d/f1
484 484 $ hg -q commit -A -m 'add f1'
485 485 $ hg -q up -r 0
486 486 >>> from __future__ import absolute_import, print_function
487 487 >>> import random
488 488 >>> random.seed(0) # have a reproducible content
489 489 >>> with open("f2", "wb") as f:
490 490 ... for i in range(100000):
491 491 ... f.write(b"%d\n" % random.randint(1000000000, 9999999999)) and None
492 492 $ hg -q commit -A -m 'add f2'
493 493
494 494 make sure we have a .d file
495 495
496 496 $ ls -d .hg/store/data/*
497 497 .hg/store/data/_foo_bar_directory.d.hg
498 498 .hg/store/data/f0.i
499 499 .hg/store/data/f2.d
500 500 .hg/store/data/f2.i
501 501
502 502 $ hg debugupgraderepo --run --config format.sparse-revlog=false
503 503 upgrade will perform the following actions:
504 504
505 505 requirements
506 506 preserved: dotencode, fncache, revlogv1, store
507 507 added: generaldelta
508 508
509 509 generaldelta
510 510 repository storage will be able to create optimal deltas; new repository data will be smaller and read times should decrease; interacting with other repositories using this storage model should require less network and CPU resources, making "hg push" and "hg pull" faster
511 511
512 512 processed revlogs:
513 513 - all-filelogs
514 514 - changelog
515 515 - manifest
516 516
517 517 beginning upgrade...
518 518 repository locked and read-only
519 519 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
520 520 (it is safe to interrupt this process any time before data migration completes)
521 521 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
522 522 migrating 519 KB in store; 1.05 MB tracked data
523 523 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
524 524 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
525 525 migrating 1 manifests containing 3 revisions (384 bytes in store; 238 bytes tracked data)
526 526 finished migrating 3 manifest revisions across 1 manifests; change in size: -17 bytes
527 527 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
528 528 finished migrating 3 changelog revisions; change in size: 0 bytes
529 529 finished migrating 9 total revisions; total change in store size: -17 bytes
530 530 copying phaseroots
531 531 data fully upgraded in a temporary repository
532 532 marking source repository as being upgraded; clients will be unable to read from repository
533 533 starting in-place swap of repository data
534 534 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
535 535 replacing store...
536 536 store replacement complete; repository was inconsistent for *s (glob)
537 537 finalizing requirements file and making repository readable again
538 538 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
539 539 copy of old repository backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
540 540 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
541 541
542 542 Original requirements backed up
543 543
544 544 $ cat .hg/upgradebackup.*/requires
545 545 dotencode
546 546 fncache
547 547 revlogv1
548 548 store
549 549
550 550 generaldelta added to original requirements files
551 551
552 552 $ cat .hg/requires
553 553 dotencode
554 554 fncache
555 555 generaldelta
556 556 revlogv1
557 557 store
558 558
559 559 store directory has files we expect
560 560
561 561 $ ls .hg/store
562 562 00changelog.i
563 563 00manifest.i
564 564 data
565 565 fncache
566 566 phaseroots
567 567 undo
568 568 undo.backupfiles
569 569 undo.phaseroots
570 570
571 571 manifest should be generaldelta
572 572
573 573 $ hg debugrevlog -m | grep flags
574 574 flags : inline, generaldelta
575 575
576 576 verify should be happy
577 577
578 578 $ hg verify
579 579 checking changesets
580 580 checking manifests
581 581 crosschecking files in changesets and manifests
582 582 checking files
583 583 checked 3 changesets with 3 changes to 3 files
584 584
585 585 old store should be backed up
586 586
587 587 $ ls -d .hg/upgradebackup.*/
588 588 .hg/upgradebackup.*/ (glob)
589 589 $ ls .hg/upgradebackup.*/store
590 590 00changelog.i
591 591 00manifest.i
592 592 data
593 593 fncache
594 594 phaseroots
595 595 undo
596 596 undo.backup.fncache
597 597 undo.backupfiles
598 598 undo.phaseroots
599 599
600 600 unless --no-backup is passed
601 601
602 602 $ rm -rf .hg/upgradebackup.*/
603 603 $ hg debugupgraderepo --run --no-backup
604 604 upgrade will perform the following actions:
605 605
606 606 requirements
607 607 preserved: dotencode, fncache, generaldelta, revlogv1, store
608 608 added: sparserevlog
609 609
610 610 sparserevlog
611 611 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
612 612
613 613 processed revlogs:
614 614 - all-filelogs
615 615 - changelog
616 616 - manifest
617 617
618 618 beginning upgrade...
619 619 repository locked and read-only
620 620 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
621 621 (it is safe to interrupt this process any time before data migration completes)
622 622 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
623 623 migrating 519 KB in store; 1.05 MB tracked data
624 624 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
625 625 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
626 626 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
627 627 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
628 628 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
629 629 finished migrating 3 changelog revisions; change in size: 0 bytes
630 630 finished migrating 9 total revisions; total change in store size: 0 bytes
631 631 copying phaseroots
632 632 data fully upgraded in a temporary repository
633 633 marking source repository as being upgraded; clients will be unable to read from repository
634 634 starting in-place swap of repository data
635 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
636 635 replacing store...
637 636 store replacement complete; repository was inconsistent for * (glob)
638 637 finalizing requirements file and making repository readable again
639 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
640 638 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
641 639 $ ls -1 .hg/ | grep upgradebackup
642 640 [1]
643 641
644 642 We can restrict optimization to some revlog:
645 643
646 644 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
647 645 upgrade will perform the following actions:
648 646
649 647 requirements
650 648 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
651 649
652 650 optimisations: re-delta-parent
653 651
654 652 re-delta-parent
655 653 deltas within internal storage will choose a new base revision if needed
656 654
657 655 processed revlogs:
658 656 - manifest
659 657
660 658 beginning upgrade...
661 659 repository locked and read-only
662 660 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
663 661 (it is safe to interrupt this process any time before data migration completes)
664 662 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
665 663 migrating 519 KB in store; 1.05 MB tracked data
666 664 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
667 665 blindly copying data/FooBarDirectory.d/f1.i containing 1 revisions
668 666 blindly copying data/f0.i containing 1 revisions
669 667 blindly copying data/f2.i containing 1 revisions
670 668 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
671 669 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
672 670 cloning 3 revisions from 00manifest.i
673 671 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
674 672 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
675 673 blindly copying 00changelog.i containing 3 revisions
676 674 finished migrating 3 changelog revisions; change in size: 0 bytes
677 675 finished migrating 9 total revisions; total change in store size: 0 bytes
678 676 copying phaseroots
679 677 data fully upgraded in a temporary repository
680 678 marking source repository as being upgraded; clients will be unable to read from repository
681 679 starting in-place swap of repository data
682 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
683 680 replacing store...
684 681 store replacement complete; repository was inconsistent for *s (glob)
685 682 finalizing requirements file and making repository readable again
686 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
687 683 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
688 684
689 685 Check that the repo still works fine
690 686
691 687 $ hg log -G --stat
692 688 @ changeset: 2:76d4395f5413 (no-py3 !)
693 689 @ changeset: 2:fca376863211 (py3 !)
694 690 | tag: tip
695 691 | parent: 0:ba592bf28da2
696 692 | user: test
697 693 | date: Thu Jan 01 00:00:00 1970 +0000
698 694 | summary: add f2
699 695 |
700 696 | f2 | 100000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
701 697 | 1 files changed, 100000 insertions(+), 0 deletions(-)
702 698 |
703 699 | o changeset: 1:2029ce2354e2
704 700 |/ user: test
705 701 | date: Thu Jan 01 00:00:00 1970 +0000
706 702 | summary: add f1
707 703 |
708 704 |
709 705 o changeset: 0:ba592bf28da2
710 706 user: test
711 707 date: Thu Jan 01 00:00:00 1970 +0000
712 708 summary: initial
713 709
714 710
715 711
716 712 $ hg verify
717 713 checking changesets
718 714 checking manifests
719 715 crosschecking files in changesets and manifests
720 716 checking files
721 717 checked 3 changesets with 3 changes to 3 files
722 718
723 719 Check we can select negatively
724 720
725 721 $ hg debugupgrade --optimize re-delta-parent --run --no-manifest --no-backup --debug --traceback
726 722 upgrade will perform the following actions:
727 723
728 724 requirements
729 725 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
730 726
731 727 optimisations: re-delta-parent
732 728
733 729 re-delta-parent
734 730 deltas within internal storage will choose a new base revision if needed
735 731
736 732 processed revlogs:
737 733 - all-filelogs
738 734 - changelog
739 735
740 736 beginning upgrade...
741 737 repository locked and read-only
742 738 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
743 739 (it is safe to interrupt this process any time before data migration completes)
744 740 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
745 741 migrating 519 KB in store; 1.05 MB tracked data
746 742 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
747 743 cloning 1 revisions from data/FooBarDirectory.d/f1.i
748 744 cloning 1 revisions from data/f0.i
749 745 cloning 1 revisions from data/f2.i
750 746 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
751 747 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
752 748 blindly copying 00manifest.i containing 3 revisions
753 749 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
754 750 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
755 751 cloning 3 revisions from 00changelog.i
756 752 finished migrating 3 changelog revisions; change in size: 0 bytes
757 753 finished migrating 9 total revisions; total change in store size: 0 bytes
758 754 copying phaseroots
759 755 data fully upgraded in a temporary repository
760 756 marking source repository as being upgraded; clients will be unable to read from repository
761 757 starting in-place swap of repository data
762 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
763 758 replacing store...
764 759 store replacement complete; repository was inconsistent for *s (glob)
765 760 finalizing requirements file and making repository readable again
766 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
767 761 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
768 762 $ hg verify
769 763 checking changesets
770 764 checking manifests
771 765 crosschecking files in changesets and manifests
772 766 checking files
773 767 checked 3 changesets with 3 changes to 3 files
774 768
775 769 Check that we can select changelog only
776 770
777 771 $ hg debugupgrade --optimize re-delta-parent --run --changelog --no-backup --debug --traceback
778 772 upgrade will perform the following actions:
779 773
780 774 requirements
781 775 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
782 776
783 777 optimisations: re-delta-parent
784 778
785 779 re-delta-parent
786 780 deltas within internal storage will choose a new base revision if needed
787 781
788 782 processed revlogs:
789 783 - changelog
790 784
791 785 beginning upgrade...
792 786 repository locked and read-only
793 787 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
794 788 (it is safe to interrupt this process any time before data migration completes)
795 789 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
796 790 migrating 519 KB in store; 1.05 MB tracked data
797 791 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
798 792 blindly copying data/FooBarDirectory.d/f1.i containing 1 revisions
799 793 blindly copying data/f0.i containing 1 revisions
800 794 blindly copying data/f2.i containing 1 revisions
801 795 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
802 796 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
803 797 blindly copying 00manifest.i containing 3 revisions
804 798 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
805 799 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
806 800 cloning 3 revisions from 00changelog.i
807 801 finished migrating 3 changelog revisions; change in size: 0 bytes
808 802 finished migrating 9 total revisions; total change in store size: 0 bytes
809 803 copying phaseroots
810 804 data fully upgraded in a temporary repository
811 805 marking source repository as being upgraded; clients will be unable to read from repository
812 806 starting in-place swap of repository data
813 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
814 807 replacing store...
815 808 store replacement complete; repository was inconsistent for *s (glob)
816 809 finalizing requirements file and making repository readable again
817 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
818 810 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
819 811 $ hg verify
820 812 checking changesets
821 813 checking manifests
822 814 crosschecking files in changesets and manifests
823 815 checking files
824 816 checked 3 changesets with 3 changes to 3 files
825 817
826 818 Check that we can select filelog only
827 819
828 820 $ hg debugupgrade --optimize re-delta-parent --run --no-changelog --no-manifest --no-backup --debug --traceback
829 821 upgrade will perform the following actions:
830 822
831 823 requirements
832 824 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
833 825
834 826 optimisations: re-delta-parent
835 827
836 828 re-delta-parent
837 829 deltas within internal storage will choose a new base revision if needed
838 830
839 831 processed revlogs:
840 832 - all-filelogs
841 833
842 834 beginning upgrade...
843 835 repository locked and read-only
844 836 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
845 837 (it is safe to interrupt this process any time before data migration completes)
846 838 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
847 839 migrating 519 KB in store; 1.05 MB tracked data
848 840 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
849 841 cloning 1 revisions from data/FooBarDirectory.d/f1.i
850 842 cloning 1 revisions from data/f0.i
851 843 cloning 1 revisions from data/f2.i
852 844 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
853 845 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
854 846 blindly copying 00manifest.i containing 3 revisions
855 847 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
856 848 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
857 849 blindly copying 00changelog.i containing 3 revisions
858 850 finished migrating 3 changelog revisions; change in size: 0 bytes
859 851 finished migrating 9 total revisions; total change in store size: 0 bytes
860 852 copying phaseroots
861 853 data fully upgraded in a temporary repository
862 854 marking source repository as being upgraded; clients will be unable to read from repository
863 855 starting in-place swap of repository data
864 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
865 856 replacing store...
866 857 store replacement complete; repository was inconsistent for *s (glob)
867 858 finalizing requirements file and making repository readable again
868 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
869 859 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
870 860 $ hg verify
871 861 checking changesets
872 862 checking manifests
873 863 crosschecking files in changesets and manifests
874 864 checking files
875 865 checked 3 changesets with 3 changes to 3 files
876 866
877 867
878 868 Check you can't skip revlog clone during important format downgrade
879 869
880 870 $ echo "[format]" > .hg/hgrc
881 871 $ echo "sparse-revlog=no" >> .hg/hgrc
882 872 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
883 873 ignoring revlogs selection flags, format requirements change: sparserevlog
884 874 upgrade will perform the following actions:
885 875
886 876 requirements
887 877 preserved: dotencode, fncache, generaldelta, revlogv1, store
888 878 removed: sparserevlog
889 879
890 880 optimisations: re-delta-parent
891 881
892 882 re-delta-parent
893 883 deltas within internal storage will choose a new base revision if needed
894 884
895 885 processed revlogs:
896 886 - all-filelogs
897 887 - changelog
898 888 - manifest
899 889
900 890 beginning upgrade...
901 891 repository locked and read-only
902 892 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
903 893 (it is safe to interrupt this process any time before data migration completes)
904 894 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
905 895 migrating 519 KB in store; 1.05 MB tracked data
906 896 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
907 897 cloning 1 revisions from data/FooBarDirectory.d/f1.i
908 898 cloning 1 revisions from data/f0.i
909 899 cloning 1 revisions from data/f2.i
910 900 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
911 901 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
912 902 cloning 3 revisions from 00manifest.i
913 903 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
914 904 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
915 905 cloning 3 revisions from 00changelog.i
916 906 finished migrating 3 changelog revisions; change in size: 0 bytes
917 907 finished migrating 9 total revisions; total change in store size: 0 bytes
918 908 copying phaseroots
919 909 data fully upgraded in a temporary repository
920 910 marking source repository as being upgraded; clients will be unable to read from repository
921 911 starting in-place swap of repository data
922 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
923 912 replacing store...
924 913 store replacement complete; repository was inconsistent for *s (glob)
925 914 finalizing requirements file and making repository readable again
926 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
927 915 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
928 916 $ hg verify
929 917 checking changesets
930 918 checking manifests
931 919 crosschecking files in changesets and manifests
932 920 checking files
933 921 checked 3 changesets with 3 changes to 3 files
934 922
935 923 Check you can't skip revlog clone during important format upgrade
936 924
937 925 $ echo "sparse-revlog=yes" >> .hg/hgrc
938 926 $ hg debugupgrade --optimize re-delta-parent --run --manifest --no-backup --debug --traceback
939 927 ignoring revlogs selection flags, format requirements change: sparserevlog
940 928 upgrade will perform the following actions:
941 929
942 930 requirements
943 931 preserved: dotencode, fncache, generaldelta, revlogv1, store
944 932 added: sparserevlog
945 933
946 934 optimisations: re-delta-parent
947 935
948 936 sparserevlog
949 937 Revlog supports delta chain with more unused data between payload. These gaps will be skipped at read time. This allows for better delta chains, making a better compression and faster exchange with server.
950 938
951 939 re-delta-parent
952 940 deltas within internal storage will choose a new base revision if needed
953 941
954 942 processed revlogs:
955 943 - all-filelogs
956 944 - changelog
957 945 - manifest
958 946
959 947 beginning upgrade...
960 948 repository locked and read-only
961 949 creating temporary repository to stage upgraded data: $TESTTMP/upgradegd/.hg/upgrade.* (glob)
962 950 (it is safe to interrupt this process any time before data migration completes)
963 951 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
964 952 migrating 519 KB in store; 1.05 MB tracked data
965 953 migrating 3 filelogs containing 3 revisions (518 KB in store; 1.05 MB tracked data)
966 954 cloning 1 revisions from data/FooBarDirectory.d/f1.i
967 955 cloning 1 revisions from data/f0.i
968 956 cloning 1 revisions from data/f2.i
969 957 finished migrating 3 filelog revisions across 3 filelogs; change in size: 0 bytes
970 958 migrating 1 manifests containing 3 revisions (367 bytes in store; 238 bytes tracked data)
971 959 cloning 3 revisions from 00manifest.i
972 960 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
973 961 migrating changelog containing 3 revisions (394 bytes in store; 199 bytes tracked data)
974 962 cloning 3 revisions from 00changelog.i
975 963 finished migrating 3 changelog revisions; change in size: 0 bytes
976 964 finished migrating 9 total revisions; total change in store size: 0 bytes
977 965 copying phaseroots
978 966 data fully upgraded in a temporary repository
979 967 marking source repository as being upgraded; clients will be unable to read from repository
980 968 starting in-place swap of repository data
981 replaced files will be backed up at $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
982 969 replacing store...
983 970 store replacement complete; repository was inconsistent for *s (glob)
984 971 finalizing requirements file and making repository readable again
985 removing old repository content $TESTTMP/upgradegd/.hg/upgradebackup.* (glob)
986 972 removing temporary repository $TESTTMP/upgradegd/.hg/upgrade.* (glob)
987 973 $ hg verify
988 974 checking changesets
989 975 checking manifests
990 976 crosschecking files in changesets and manifests
991 977 checking files
992 978 checked 3 changesets with 3 changes to 3 files
993 979
994 980 $ cd ..
995 981
996 982 store files with special filenames aren't encoded during copy
997 983
998 984 $ hg init store-filenames
999 985 $ cd store-filenames
1000 986 $ touch foo
1001 987 $ hg -q commit -A -m initial
1002 988 $ touch .hg/store/.XX_special_filename
1003 989
1004 990 $ hg debugupgraderepo --run
1005 991 nothing to do
1006 992 $ hg debugupgraderepo --run --optimize 're-delta-fulladd'
1007 993 upgrade will perform the following actions:
1008 994
1009 995 requirements
1010 996 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
1011 997
1012 998 optimisations: re-delta-fulladd
1013 999
1014 1000 re-delta-fulladd
1015 1001 each revision will be added as new content to the internal storage; this will likely drastically slow down execution time, but some extensions might need it
1016 1002
1017 1003 processed revlogs:
1018 1004 - all-filelogs
1019 1005 - changelog
1020 1006 - manifest
1021 1007
1022 1008 beginning upgrade...
1023 1009 repository locked and read-only
1024 1010 creating temporary repository to stage upgraded data: $TESTTMP/store-filenames/.hg/upgrade.* (glob)
1025 1011 (it is safe to interrupt this process any time before data migration completes)
1026 1012 migrating 3 total revisions (1 in filelogs, 1 in manifests, 1 in changelog)
1027 1013 migrating 301 bytes in store; 107 bytes tracked data
1028 1014 migrating 1 filelogs containing 1 revisions (64 bytes in store; 0 bytes tracked data)
1029 1015 finished migrating 1 filelog revisions across 1 filelogs; change in size: 0 bytes
1030 1016 migrating 1 manifests containing 1 revisions (110 bytes in store; 45 bytes tracked data)
1031 1017 finished migrating 1 manifest revisions across 1 manifests; change in size: 0 bytes
1032 1018 migrating changelog containing 1 revisions (127 bytes in store; 62 bytes tracked data)
1033 1019 finished migrating 1 changelog revisions; change in size: 0 bytes
1034 1020 finished migrating 3 total revisions; total change in store size: 0 bytes
1035 1021 copying .XX_special_filename
1036 1022 copying phaseroots
1037 1023 data fully upgraded in a temporary repository
1038 1024 marking source repository as being upgraded; clients will be unable to read from repository
1039 1025 starting in-place swap of repository data
1040 1026 replaced files will be backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
1041 1027 replacing store...
1042 1028 store replacement complete; repository was inconsistent for *s (glob)
1043 1029 finalizing requirements file and making repository readable again
1044 1030 removing temporary repository $TESTTMP/store-filenames/.hg/upgrade.* (glob)
1045 1031 copy of old repository backed up at $TESTTMP/store-filenames/.hg/upgradebackup.* (glob)
1046 1032 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
1047 1033
1048 1034 fncache is valid after upgrade
1049 1035
1050 1036 $ hg debugrebuildfncache
1051 1037 fncache already up to date
1052 1038
1053 1039 $ cd ..
1054 1040
1055 1041 Check upgrading a large file repository
1056 1042 ---------------------------------------
1057 1043
1058 1044 $ hg init largefilesrepo
1059 1045 $ cat << EOF >> largefilesrepo/.hg/hgrc
1060 1046 > [extensions]
1061 1047 > largefiles =
1062 1048 > EOF
1063 1049
1064 1050 $ cd largefilesrepo
1065 1051 $ touch foo
1066 1052 $ hg add --large foo
1067 1053 $ hg -q commit -m initial
1068 1054 $ cat .hg/requires
1069 1055 dotencode
1070 1056 fncache
1071 1057 generaldelta
1072 1058 largefiles
1073 1059 revlogv1
1074 1060 sparserevlog
1075 1061 store
1076 1062
1077 1063 $ hg debugupgraderepo --run
1078 1064 nothing to do
1079 1065 $ cat .hg/requires
1080 1066 dotencode
1081 1067 fncache
1082 1068 generaldelta
1083 1069 largefiles
1084 1070 revlogv1
1085 1071 sparserevlog
1086 1072 store
1087 1073
1088 1074 $ cat << EOF >> .hg/hgrc
1089 1075 > [extensions]
1090 1076 > lfs =
1091 1077 > [lfs]
1092 1078 > threshold = 10
1093 1079 > EOF
1094 1080 $ echo '123456789012345' > lfs.bin
1095 1081 $ hg ci -Am 'lfs.bin'
1096 1082 adding lfs.bin
1097 1083 $ grep lfs .hg/requires
1098 1084 lfs
1099 1085 $ find .hg/store/lfs -type f
1100 1086 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1101 1087
1102 1088 $ hg debugupgraderepo --run
1103 1089 nothing to do
1104 1090
1105 1091 $ grep lfs .hg/requires
1106 1092 lfs
1107 1093 $ find .hg/store/lfs -type f
1108 1094 .hg/store/lfs/objects/d0/beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1109 1095 $ hg verify
1110 1096 checking changesets
1111 1097 checking manifests
1112 1098 crosschecking files in changesets and manifests
1113 1099 checking files
1114 1100 checked 2 changesets with 2 changes to 2 files
1115 1101 $ hg debugdata lfs.bin 0
1116 1102 version https://git-lfs.github.com/spec/v1
1117 1103 oid sha256:d0beab232adff5ba365880366ad30b1edb85c4c5372442b5d2fe27adc96d653f
1118 1104 size 16
1119 1105 x-is-binary 0
1120 1106
1121 1107 $ cd ..
1122 1108
1123 1109 repository config is taken in account
1124 1110 -------------------------------------
1125 1111
1126 1112 $ cat << EOF >> $HGRCPATH
1127 1113 > [format]
1128 1114 > maxchainlen = 1
1129 1115 > EOF
1130 1116
1131 1117 $ hg init localconfig
1132 1118 $ cd localconfig
1133 1119 $ cat << EOF > file
1134 1120 > some content
1135 1121 > with some length
1136 1122 > to make sure we get a delta
1137 1123 > after changes
1138 1124 > very long
1139 1125 > very long
1140 1126 > very long
1141 1127 > very long
1142 1128 > very long
1143 1129 > very long
1144 1130 > very long
1145 1131 > very long
1146 1132 > very long
1147 1133 > very long
1148 1134 > very long
1149 1135 > EOF
1150 1136 $ hg -q commit -A -m A
1151 1137 $ echo "new line" >> file
1152 1138 $ hg -q commit -m B
1153 1139 $ echo "new line" >> file
1154 1140 $ hg -q commit -m C
1155 1141
1156 1142 $ cat << EOF >> .hg/hgrc
1157 1143 > [format]
1158 1144 > maxchainlen = 9001
1159 1145 > EOF
1160 1146 $ hg config format
1161 1147 format.maxchainlen=9001
1162 1148 $ hg debugdeltachain file
1163 1149 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
1164 1150 0 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
1165 1151 1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
1166 1152 2 1 2 0 other 30 200 107 0.53500 128 21 0.19626 128 128 0.83594 1
1167 1153
1168 1154 $ hg debugupgraderepo --run --optimize 're-delta-all'
1169 1155 upgrade will perform the following actions:
1170 1156
1171 1157 requirements
1172 1158 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
1173 1159
1174 1160 optimisations: re-delta-all
1175 1161
1176 1162 re-delta-all
1177 1163 deltas within internal storage will be fully recomputed; this will likely drastically slow down execution time
1178 1164
1179 1165 processed revlogs:
1180 1166 - all-filelogs
1181 1167 - changelog
1182 1168 - manifest
1183 1169
1184 1170 beginning upgrade...
1185 1171 repository locked and read-only
1186 1172 creating temporary repository to stage upgraded data: $TESTTMP/localconfig/.hg/upgrade.* (glob)
1187 1173 (it is safe to interrupt this process any time before data migration completes)
1188 1174 migrating 9 total revisions (3 in filelogs, 3 in manifests, 3 in changelog)
1189 1175 migrating 1019 bytes in store; 882 bytes tracked data
1190 1176 migrating 1 filelogs containing 3 revisions (320 bytes in store; 573 bytes tracked data)
1191 1177 finished migrating 3 filelog revisions across 1 filelogs; change in size: -9 bytes
1192 1178 migrating 1 manifests containing 3 revisions (333 bytes in store; 138 bytes tracked data)
1193 1179 finished migrating 3 manifest revisions across 1 manifests; change in size: 0 bytes
1194 1180 migrating changelog containing 3 revisions (366 bytes in store; 171 bytes tracked data)
1195 1181 finished migrating 3 changelog revisions; change in size: 0 bytes
1196 1182 finished migrating 9 total revisions; total change in store size: -9 bytes
1197 1183 copying phaseroots
1198 1184 data fully upgraded in a temporary repository
1199 1185 marking source repository as being upgraded; clients will be unable to read from repository
1200 1186 starting in-place swap of repository data
1201 1187 replaced files will be backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
1202 1188 replacing store...
1203 1189 store replacement complete; repository was inconsistent for *s (glob)
1204 1190 finalizing requirements file and making repository readable again
1205 1191 removing temporary repository $TESTTMP/localconfig/.hg/upgrade.* (glob)
1206 1192 copy of old repository backed up at $TESTTMP/localconfig/.hg/upgradebackup.* (glob)
1207 1193 the old repository will not be deleted; remove it to free up disk space once the upgraded repository is verified
1208 1194 $ hg debugdeltachain file
1209 1195 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
1210 1196 0 1 1 -1 base 77 182 77 0.42308 77 0 0.00000 77 77 1.00000 1
1211 1197 1 1 2 0 p1 21 191 98 0.51309 98 0 0.00000 98 98 1.00000 1
1212 1198 2 1 3 1 p1 21 200 119 0.59500 119 0 0.00000 119 119 1.00000 1
1213 1199 $ cd ..
1214 1200
1215 1201 $ cat << EOF >> $HGRCPATH
1216 1202 > [format]
1217 1203 > maxchainlen = 9001
1218 1204 > EOF
1219 1205
1220 1206 Check upgrading a sparse-revlog repository
1221 1207 ---------------------------------------
1222 1208
1223 1209 $ hg init sparserevlogrepo --config format.sparse-revlog=no
1224 1210 $ cd sparserevlogrepo
1225 1211 $ touch foo
1226 1212 $ hg add foo
1227 1213 $ hg -q commit -m "foo"
1228 1214 $ cat .hg/requires
1229 1215 dotencode
1230 1216 fncache
1231 1217 generaldelta
1232 1218 revlogv1
1233 1219 store
1234 1220
1235 1221 Check that we can add the sparse-revlog format requirement
1236 1222 $ hg --config format.sparse-revlog=yes debugupgraderepo --run --quiet
1237 1223 upgrade will perform the following actions:
1238 1224
1239 1225 requirements
1240 1226 preserved: dotencode, fncache, generaldelta, revlogv1, store
1241 1227 added: sparserevlog
1242 1228
1243 1229 processed revlogs:
1244 1230 - all-filelogs
1245 1231 - changelog
1246 1232 - manifest
1247 1233
1248 1234 $ cat .hg/requires
1249 1235 dotencode
1250 1236 fncache
1251 1237 generaldelta
1252 1238 revlogv1
1253 1239 sparserevlog
1254 1240 store
1255 1241
1256 1242 Check that we can remove the sparse-revlog format requirement
1257 1243 $ hg --config format.sparse-revlog=no debugupgraderepo --run --quiet
1258 1244 upgrade will perform the following actions:
1259 1245
1260 1246 requirements
1261 1247 preserved: dotencode, fncache, generaldelta, revlogv1, store
1262 1248 removed: sparserevlog
1263 1249
1264 1250 processed revlogs:
1265 1251 - all-filelogs
1266 1252 - changelog
1267 1253 - manifest
1268 1254
1269 1255 $ cat .hg/requires
1270 1256 dotencode
1271 1257 fncache
1272 1258 generaldelta
1273 1259 revlogv1
1274 1260 store
1275 1261
1276 1262 #if zstd
1277 1263
1278 1264 Check upgrading to a zstd revlog
1279 1265 --------------------------------
1280 1266
1281 1267 upgrade
1282 1268
1283 1269 $ hg --config format.revlog-compression=zstd debugupgraderepo --run --no-backup --quiet
1284 1270 upgrade will perform the following actions:
1285 1271
1286 1272 requirements
1287 1273 preserved: dotencode, fncache, generaldelta, revlogv1, store
1288 1274 added: revlog-compression-zstd, sparserevlog
1289 1275
1290 1276 processed revlogs:
1291 1277 - all-filelogs
1292 1278 - changelog
1293 1279 - manifest
1294 1280
1295 1281 $ hg debugformat -v
1296 1282 format-variant repo config default
1297 1283 fncache: yes yes yes
1298 1284 dotencode: yes yes yes
1299 1285 generaldelta: yes yes yes
1300 1286 share-safe: no no no
1301 1287 sparserevlog: yes yes yes
1302 1288 sidedata: no no no
1303 1289 persistent-nodemap: no no no
1304 1290 copies-sdc: no no no
1305 1291 plain-cl-delta: yes yes yes
1306 1292 compression: zstd zlib zlib
1307 1293 compression-level: default default default
1308 1294 $ cat .hg/requires
1309 1295 dotencode
1310 1296 fncache
1311 1297 generaldelta
1312 1298 revlog-compression-zstd
1313 1299 revlogv1
1314 1300 sparserevlog
1315 1301 store
1316 1302
1317 1303 downgrade
1318 1304
1319 1305 $ hg debugupgraderepo --run --no-backup --quiet
1320 1306 upgrade will perform the following actions:
1321 1307
1322 1308 requirements
1323 1309 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
1324 1310 removed: revlog-compression-zstd
1325 1311
1326 1312 processed revlogs:
1327 1313 - all-filelogs
1328 1314 - changelog
1329 1315 - manifest
1330 1316
1331 1317 $ hg debugformat -v
1332 1318 format-variant repo config default
1333 1319 fncache: yes yes yes
1334 1320 dotencode: yes yes yes
1335 1321 generaldelta: yes yes yes
1336 1322 share-safe: no no no
1337 1323 sparserevlog: yes yes yes
1338 1324 sidedata: no no no
1339 1325 persistent-nodemap: no no no
1340 1326 copies-sdc: no no no
1341 1327 plain-cl-delta: yes yes yes
1342 1328 compression: zlib zlib zlib
1343 1329 compression-level: default default default
1344 1330 $ cat .hg/requires
1345 1331 dotencode
1346 1332 fncache
1347 1333 generaldelta
1348 1334 revlogv1
1349 1335 sparserevlog
1350 1336 store
1351 1337
1352 1338 upgrade from hgrc
1353 1339
1354 1340 $ cat >> .hg/hgrc << EOF
1355 1341 > [format]
1356 1342 > revlog-compression=zstd
1357 1343 > EOF
1358 1344 $ hg debugupgraderepo --run --no-backup --quiet
1359 1345 upgrade will perform the following actions:
1360 1346
1361 1347 requirements
1362 1348 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
1363 1349 added: revlog-compression-zstd
1364 1350
1365 1351 processed revlogs:
1366 1352 - all-filelogs
1367 1353 - changelog
1368 1354 - manifest
1369 1355
1370 1356 $ hg debugformat -v
1371 1357 format-variant repo config default
1372 1358 fncache: yes yes yes
1373 1359 dotencode: yes yes yes
1374 1360 generaldelta: yes yes yes
1375 1361 share-safe: no no no
1376 1362 sparserevlog: yes yes yes
1377 1363 sidedata: no no no
1378 1364 persistent-nodemap: no no no
1379 1365 copies-sdc: no no no
1380 1366 plain-cl-delta: yes yes yes
1381 1367 compression: zstd zstd zlib
1382 1368 compression-level: default default default
1383 1369 $ cat .hg/requires
1384 1370 dotencode
1385 1371 fncache
1386 1372 generaldelta
1387 1373 revlog-compression-zstd
1388 1374 revlogv1
1389 1375 sparserevlog
1390 1376 store
1391 1377
1392 1378 #endif
1393 1379
1394 1380 Check upgrading to a side-data revlog
1395 1381 -------------------------------------
1396 1382
1397 1383 upgrade
1398 1384
1399 1385 $ hg --config format.exp-use-side-data=yes debugupgraderepo --run --no-backup --config "extensions.sidedata=$TESTDIR/testlib/ext-sidedata.py" --quiet
1400 1386 upgrade will perform the following actions:
1401 1387
1402 1388 requirements
1403 1389 preserved: dotencode, fncache, generaldelta, revlogv1, store (no-zstd !)
1404 1390 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, sparserevlog, store (zstd !)
1405 1391 added: exp-sidedata-flag (zstd !)
1406 1392 added: exp-sidedata-flag, sparserevlog (no-zstd !)
1407 1393
1408 1394 processed revlogs:
1409 1395 - all-filelogs
1410 1396 - changelog
1411 1397 - manifest
1412 1398
1413 1399 $ hg debugformat -v
1414 1400 format-variant repo config default
1415 1401 fncache: yes yes yes
1416 1402 dotencode: yes yes yes
1417 1403 generaldelta: yes yes yes
1418 1404 share-safe: no no no
1419 1405 sparserevlog: yes yes yes
1420 1406 sidedata: yes no no
1421 1407 persistent-nodemap: no no no
1422 1408 copies-sdc: no no no
1423 1409 plain-cl-delta: yes yes yes
1424 1410 compression: zlib zlib zlib (no-zstd !)
1425 1411 compression: zstd zstd zlib (zstd !)
1426 1412 compression-level: default default default
1427 1413 $ cat .hg/requires
1428 1414 dotencode
1429 1415 exp-sidedata-flag
1430 1416 fncache
1431 1417 generaldelta
1432 1418 revlog-compression-zstd (zstd !)
1433 1419 revlogv1
1434 1420 sparserevlog
1435 1421 store
1436 1422 $ hg debugsidedata -c 0
1437 1423 2 sidedata entries
1438 1424 entry-0001 size 4
1439 1425 entry-0002 size 32
1440 1426
1441 1427 downgrade
1442 1428
1443 1429 $ hg debugupgraderepo --config format.exp-use-side-data=no --run --no-backup --quiet
1444 1430 upgrade will perform the following actions:
1445 1431
1446 1432 requirements
1447 1433 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store (no-zstd !)
1448 1434 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, sparserevlog, store (zstd !)
1449 1435 removed: exp-sidedata-flag
1450 1436
1451 1437 processed revlogs:
1452 1438 - all-filelogs
1453 1439 - changelog
1454 1440 - manifest
1455 1441
1456 1442 $ hg debugformat -v
1457 1443 format-variant repo config default
1458 1444 fncache: yes yes yes
1459 1445 dotencode: yes yes yes
1460 1446 generaldelta: yes yes yes
1461 1447 share-safe: no no no
1462 1448 sparserevlog: yes yes yes
1463 1449 sidedata: no no no
1464 1450 persistent-nodemap: no no no
1465 1451 copies-sdc: no no no
1466 1452 plain-cl-delta: yes yes yes
1467 1453 compression: zlib zlib zlib (no-zstd !)
1468 1454 compression: zstd zstd zlib (zstd !)
1469 1455 compression-level: default default default
1470 1456 $ cat .hg/requires
1471 1457 dotencode
1472 1458 fncache
1473 1459 generaldelta
1474 1460 revlog-compression-zstd (zstd !)
1475 1461 revlogv1
1476 1462 sparserevlog
1477 1463 store
1478 1464 $ hg debugsidedata -c 0
1479 1465
1480 1466 upgrade from hgrc
1481 1467
1482 1468 $ cat >> .hg/hgrc << EOF
1483 1469 > [format]
1484 1470 > exp-use-side-data=yes
1485 1471 > EOF
1486 1472 $ hg debugupgraderepo --run --no-backup --quiet
1487 1473 upgrade will perform the following actions:
1488 1474
1489 1475 requirements
1490 1476 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store (no-zstd !)
1491 1477 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, sparserevlog, store (zstd !)
1492 1478 added: exp-sidedata-flag
1493 1479
1494 1480 processed revlogs:
1495 1481 - all-filelogs
1496 1482 - changelog
1497 1483 - manifest
1498 1484
1499 1485 $ hg debugformat -v
1500 1486 format-variant repo config default
1501 1487 fncache: yes yes yes
1502 1488 dotencode: yes yes yes
1503 1489 generaldelta: yes yes yes
1504 1490 share-safe: no no no
1505 1491 sparserevlog: yes yes yes
1506 1492 sidedata: yes yes no
1507 1493 persistent-nodemap: no no no
1508 1494 copies-sdc: no no no
1509 1495 plain-cl-delta: yes yes yes
1510 1496 compression: zlib zlib zlib (no-zstd !)
1511 1497 compression: zstd zstd zlib (zstd !)
1512 1498 compression-level: default default default
1513 1499 $ cat .hg/requires
1514 1500 dotencode
1515 1501 exp-sidedata-flag
1516 1502 fncache
1517 1503 generaldelta
1518 1504 revlog-compression-zstd (zstd !)
1519 1505 revlogv1
1520 1506 sparserevlog
1521 1507 store
1522 1508 $ hg debugsidedata -c 0
1523 1509
1524 1510 Demonstrate that nothing to perform upgrade will still run all the way through
1525 1511
1526 1512 $ hg debugupgraderepo --run
1527 1513 nothing to do
General Comments 0
You need to be logged in to leave comments. Login now