##// END OF EJS Templates
upgrade: drop some dead code...
marmoute -
r49278:dc2ef4b4 default
parent child Browse files
Show More
@@ -1,418 +1,401 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 specified_revlogs = {}
49 49 if changelog is not None:
50 50 specified_revlogs[upgrade_engine.UPGRADE_CHANGELOG] = changelog
51 51 if manifest is not None:
52 52 specified_revlogs[upgrade_engine.UPGRADE_MANIFEST] = manifest
53 53 if filelogs is not None:
54 54 specified_revlogs[upgrade_engine.UPGRADE_FILELOGS] = filelogs
55 55
56 56 # Ensure the repository can be upgraded.
57 57 upgrade_actions.check_source_requirements(repo)
58 58
59 59 default_options = localrepo.defaultcreateopts(repo.ui)
60 60 newreqs = localrepo.newreporequirements(repo.ui, default_options)
61 61 newreqs.update(upgrade_actions.preservedrequirements(repo))
62 62
63 63 upgrade_actions.check_requirements_changes(repo, newreqs)
64 64
65 65 # Find and validate all improvements that can be made.
66 66 alloptimizations = upgrade_actions.findoptimizations(repo)
67 67
68 68 # Apply and Validate arguments.
69 69 optimizations = []
70 70 for o in alloptimizations:
71 71 if o.name in optimize:
72 72 optimizations.append(o)
73 73 optimize.discard(o.name)
74 74
75 75 if optimize: # anything left is unknown
76 76 raise error.Abort(
77 77 _(b'unknown optimization action requested: %s')
78 78 % b', '.join(sorted(optimize)),
79 79 hint=_(b'run without arguments to see valid optimizations'),
80 80 )
81 81
82 82 format_upgrades = upgrade_actions.find_format_upgrades(repo)
83 83 up_actions = upgrade_actions.determine_upgrade_actions(
84 84 repo, format_upgrades, optimizations, repo.requirements, newreqs
85 85 )
86 86 removed_actions = upgrade_actions.find_format_downgrades(repo)
87 87
88 removedreqs = repo.requirements - newreqs
89 addedreqs = newreqs - repo.requirements
90
91 88 # check if we need to touch revlog and if so, which ones
92 89
93 90 touched_revlogs = set()
94 91 overwrite_msg = _(b'warning: ignoring %14s, as upgrade is changing: %s\n')
95 92 select_msg = _(b'note: selecting %s for processing to change: %s\n')
96 93 msg_issued = 0
97 94
98 95 FL = upgrade_engine.UPGRADE_FILELOGS
99 96 MN = upgrade_engine.UPGRADE_MANIFEST
100 97 CL = upgrade_engine.UPGRADE_CHANGELOG
101 98
102 99 if optimizations:
103 100 if any(specified_revlogs.values()):
104 101 # we have some limitation on revlogs to be recloned
105 102 for rl, enabled in specified_revlogs.items():
106 103 if enabled:
107 104 touched_revlogs.add(rl)
108 105 else:
109 106 touched_revlogs = set(upgrade_engine.UPGRADE_ALL_REVLOGS)
110 107 for rl, enabled in specified_revlogs.items():
111 108 if not enabled:
112 109 touched_revlogs.discard(rl)
113 110
114 111 for action in sorted(up_actions + removed_actions, key=lambda a: a.name):
115 112 # optimisation does not "requires anything, they just needs it.
116 113 if action.type != upgrade_actions.FORMAT_VARIANT:
117 114 continue
118 115
119 116 if action.touches_filelogs and FL not in touched_revlogs:
120 117 if FL in specified_revlogs:
121 118 if not specified_revlogs[FL]:
122 119 msg = overwrite_msg % (b'--no-filelogs', action.name)
123 120 ui.warn(msg)
124 121 msg_issued = 2
125 122 else:
126 123 msg = select_msg % (b'all-filelogs', action.name)
127 124 ui.status(msg)
128 125 if not ui.quiet:
129 126 msg_issued = 1
130 127 touched_revlogs.add(FL)
131 128
132 129 if action.touches_manifests and MN not in touched_revlogs:
133 130 if MN in specified_revlogs:
134 131 if not specified_revlogs[MN]:
135 132 msg = overwrite_msg % (b'--no-manifest', action.name)
136 133 ui.warn(msg)
137 134 msg_issued = 2
138 135 else:
139 136 msg = select_msg % (b'all-manifestlogs', action.name)
140 137 ui.status(msg)
141 138 if not ui.quiet:
142 139 msg_issued = 1
143 140 touched_revlogs.add(MN)
144 141
145 142 if action.touches_changelog and CL not in touched_revlogs:
146 143 if CL in specified_revlogs:
147 144 if not specified_revlogs[CL]:
148 145 msg = overwrite_msg % (b'--no-changelog', action.name)
149 146 ui.warn(msg)
150 147 msg_issued = True
151 148 else:
152 149 msg = select_msg % (b'changelog', action.name)
153 150 ui.status(msg)
154 151 if not ui.quiet:
155 152 msg_issued = 1
156 153 touched_revlogs.add(CL)
157 154 if msg_issued >= 2:
158 155 ui.warn((b"\n"))
159 156 elif msg_issued >= 1:
160 157 ui.status((b"\n"))
161 158
162 # check the consistency of the revlog selection with the planned action
163
164 if touched_revlogs != upgrade_engine.UPGRADE_ALL_REVLOGS:
165 incompatible = upgrade_actions.RECLONES_REQUIREMENTS & (
166 removedreqs | addedreqs
167 )
168 if incompatible:
169 msg = _(
170 b'ignoring revlogs selection flags, format requirements '
171 b'change: %s\n'
172 )
173 ui.warn(msg % b', '.join(sorted(incompatible)))
174 touched_revlogs = upgrade_engine.UPGRADE_ALL_REVLOGS
175
176 159 upgrade_op = upgrade_actions.UpgradeOperation(
177 160 ui,
178 161 newreqs,
179 162 repo.requirements,
180 163 up_actions,
181 164 removed_actions,
182 165 touched_revlogs,
183 166 backup,
184 167 )
185 168
186 169 if not run:
187 170 fromconfig = []
188 171 onlydefault = []
189 172
190 173 for d in format_upgrades:
191 174 if d.fromconfig(repo):
192 175 fromconfig.append(d)
193 176 elif d.default:
194 177 onlydefault.append(d)
195 178
196 179 if fromconfig or onlydefault:
197 180
198 181 if fromconfig:
199 182 ui.status(
200 183 _(
201 184 b'repository lacks features recommended by '
202 185 b'current config options:\n\n'
203 186 )
204 187 )
205 188 for i in fromconfig:
206 189 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
207 190
208 191 if onlydefault:
209 192 ui.status(
210 193 _(
211 194 b'repository lacks features used by the default '
212 195 b'config options:\n\n'
213 196 )
214 197 )
215 198 for i in onlydefault:
216 199 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
217 200
218 201 ui.status(b'\n')
219 202 else:
220 203 ui.status(_(b'(no format upgrades found in existing repository)\n'))
221 204
222 205 ui.status(
223 206 _(
224 207 b'performing an upgrade with "--run" will make the following '
225 208 b'changes:\n\n'
226 209 )
227 210 )
228 211
229 212 upgrade_op.print_requirements()
230 213 upgrade_op.print_optimisations()
231 214 upgrade_op.print_upgrade_actions()
232 215 upgrade_op.print_affected_revlogs()
233 216
234 217 if upgrade_op.unused_optimizations:
235 218 ui.status(
236 219 _(
237 220 b'additional optimizations are available by specifying '
238 221 b'"--optimize <name>":\n\n'
239 222 )
240 223 )
241 224 upgrade_op.print_unused_optimizations()
242 225 return
243 226
244 227 if not (upgrade_op.upgrade_actions or upgrade_op.removed_actions):
245 228 ui.status(_(b'nothing to do\n'))
246 229 return
247 230 # Else we're in the run=true case.
248 231 ui.write(_(b'upgrade will perform the following actions:\n\n'))
249 232 upgrade_op.print_requirements()
250 233 upgrade_op.print_optimisations()
251 234 upgrade_op.print_upgrade_actions()
252 235 upgrade_op.print_affected_revlogs()
253 236
254 237 ui.status(_(b'beginning upgrade...\n'))
255 238 with repo.wlock(), repo.lock():
256 239 ui.status(_(b'repository locked and read-only\n'))
257 240 # Our strategy for upgrading the repository is to create a new,
258 241 # temporary repository, write data to it, then do a swap of the
259 242 # data. There are less heavyweight ways to do this, but it is easier
260 243 # to create a new repo object than to instantiate all the components
261 244 # (like the store) separately.
262 245 tmppath = pycompat.mkdtemp(prefix=b'upgrade.', dir=repo.path)
263 246 backuppath = None
264 247 try:
265 248 ui.status(
266 249 _(
267 250 b'creating temporary repository to stage upgraded '
268 251 b'data: %s\n'
269 252 )
270 253 % tmppath
271 254 )
272 255
273 256 # clone ui without using ui.copy because repo.ui is protected
274 257 repoui = repo.ui.__class__(repo.ui)
275 258 dstrepo = hg.repository(repoui, path=tmppath, create=True)
276 259
277 260 with dstrepo.wlock(), dstrepo.lock():
278 261 backuppath = upgrade_engine.upgrade(
279 262 ui, repo, dstrepo, upgrade_op
280 263 )
281 264
282 265 finally:
283 266 ui.status(_(b'removing temporary repository %s\n') % tmppath)
284 267 repo.vfs.rmtree(tmppath, forcibly=True)
285 268
286 269 if backuppath and not ui.quiet:
287 270 ui.warn(
288 271 _(b'copy of old repository backed up at %s\n') % backuppath
289 272 )
290 273 ui.warn(
291 274 _(
292 275 b'the old repository will not be deleted; remove '
293 276 b'it to free up disk space once the upgraded '
294 277 b'repository is verified\n'
295 278 )
296 279 )
297 280
298 281 upgrade_op.print_post_op_messages()
299 282
300 283
301 284 def upgrade_share_to_safe(
302 285 ui,
303 286 hgvfs,
304 287 storevfs,
305 288 current_requirements,
306 289 mismatch_config,
307 290 mismatch_warn,
308 291 ):
309 292 """Upgrades a share to use share-safe mechanism"""
310 293 wlock = None
311 294 store_requirements = localrepo._readrequires(storevfs, False)
312 295 original_crequirements = current_requirements.copy()
313 296 # after upgrade, store requires will be shared, so lets find
314 297 # the requirements which are not present in store and
315 298 # write them to share's .hg/requires
316 299 diffrequires = current_requirements - store_requirements
317 300 # add share-safe requirement as it will mark the share as share-safe
318 301 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
319 302 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
320 303 # in `allow` case, we don't try to upgrade, we just respect the source
321 304 # state, update requirements and continue
322 305 if mismatch_config == b'allow':
323 306 return
324 307 try:
325 308 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
326 309 # some process might change the requirement in between, re-read
327 310 # and update current_requirements
328 311 locked_requirements = localrepo._readrequires(hgvfs, True)
329 312 if locked_requirements != original_crequirements:
330 313 removed = current_requirements - locked_requirements
331 314 # update current_requirements in place because it's passed
332 315 # as reference
333 316 current_requirements -= removed
334 317 current_requirements |= locked_requirements
335 318 diffrequires = current_requirements - store_requirements
336 319 # add share-safe requirement as it will mark the share as share-safe
337 320 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
338 321 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
339 322 scmutil.writerequires(hgvfs, diffrequires)
340 323 ui.warn(_(b'repository upgraded to use share-safe mode\n'))
341 324 except error.LockError as e:
342 325 hint = _(
343 326 "see `hg help config.format.use-share-safe` for more information"
344 327 )
345 328 if mismatch_config == b'upgrade-abort':
346 329 raise error.Abort(
347 330 _(b'failed to upgrade share, got error: %s')
348 331 % stringutil.forcebytestr(e.strerror),
349 332 hint=hint,
350 333 )
351 334 elif mismatch_warn:
352 335 ui.warn(
353 336 _(b'failed to upgrade share, got error: %s\n')
354 337 % stringutil.forcebytestr(e.strerror),
355 338 hint=hint,
356 339 )
357 340 finally:
358 341 if wlock:
359 342 wlock.release()
360 343
361 344
362 345 def downgrade_share_to_non_safe(
363 346 ui,
364 347 hgvfs,
365 348 sharedvfs,
366 349 current_requirements,
367 350 mismatch_config,
368 351 mismatch_warn,
369 352 ):
370 353 """Downgrades a share which use share-safe to not use it"""
371 354 wlock = None
372 355 source_requirements = localrepo._readrequires(sharedvfs, True)
373 356 original_crequirements = current_requirements.copy()
374 357 # we cannot be 100% sure on which requirements were present in store when
375 358 # the source supported share-safe. However, we do know that working
376 359 # directory requirements were not there. Hence we remove them
377 360 source_requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS
378 361 current_requirements |= source_requirements
379 362 current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT)
380 363 if mismatch_config == b'allow':
381 364 return
382 365
383 366 try:
384 367 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
385 368 # some process might change the requirement in between, re-read
386 369 # and update current_requirements
387 370 locked_requirements = localrepo._readrequires(hgvfs, True)
388 371 if locked_requirements != original_crequirements:
389 372 removed = current_requirements - locked_requirements
390 373 # update current_requirements in place because it's passed
391 374 # as reference
392 375 current_requirements -= removed
393 376 current_requirements |= locked_requirements
394 377 current_requirements |= source_requirements
395 378 current_requirements -= set(requirementsmod.SHARESAFE_REQUIREMENT)
396 379 scmutil.writerequires(hgvfs, current_requirements)
397 380 ui.warn(_(b'repository downgraded to not use share-safe mode\n'))
398 381 except error.LockError as e:
399 382 hint = _(
400 383 "see `hg help config.format.use-share-safe` for more information"
401 384 )
402 385 # If upgrade-abort is set, abort when upgrade fails, else let the
403 386 # process continue as `upgrade-allow` is set
404 387 if mismatch_config == b'downgrade-abort':
405 388 raise error.Abort(
406 389 _(b'failed to downgrade share, got error: %s')
407 390 % stringutil.forcebytestr(e.strerror),
408 391 hint=hint,
409 392 )
410 393 elif mismatch_warn:
411 394 ui.warn(
412 395 _(b'failed to downgrade share, got error: %s\n')
413 396 % stringutil.forcebytestr(e.strerror),
414 397 hint=hint,
415 398 )
416 399 finally:
417 400 if wlock:
418 401 wlock.release()
General Comments 0
You need to be logged in to leave comments. Login now