##// END OF EJS Templates
upgrade: byteify a few error messages...
Matt Harbison -
r49280:cb477ede stable
parent child Browse files
Show More
@@ -1,356 +1,356 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 121 backup,
122 122 )
123 123
124 124 if not run:
125 125 fromconfig = []
126 126 onlydefault = []
127 127
128 128 for d in format_upgrades:
129 129 if d.fromconfig(repo):
130 130 fromconfig.append(d)
131 131 elif d.default:
132 132 onlydefault.append(d)
133 133
134 134 if fromconfig or onlydefault:
135 135
136 136 if fromconfig:
137 137 ui.status(
138 138 _(
139 139 b'repository lacks features recommended by '
140 140 b'current config options:\n\n'
141 141 )
142 142 )
143 143 for i in fromconfig:
144 144 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
145 145
146 146 if onlydefault:
147 147 ui.status(
148 148 _(
149 149 b'repository lacks features used by the default '
150 150 b'config options:\n\n'
151 151 )
152 152 )
153 153 for i in onlydefault:
154 154 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
155 155
156 156 ui.status(b'\n')
157 157 else:
158 158 ui.status(_(b'(no format upgrades found in existing repository)\n'))
159 159
160 160 ui.status(
161 161 _(
162 162 b'performing an upgrade with "--run" will make the following '
163 163 b'changes:\n\n'
164 164 )
165 165 )
166 166
167 167 upgrade_op.print_requirements()
168 168 upgrade_op.print_optimisations()
169 169 upgrade_op.print_upgrade_actions()
170 170 upgrade_op.print_affected_revlogs()
171 171
172 172 if upgrade_op.unused_optimizations:
173 173 ui.status(
174 174 _(
175 175 b'additional optimizations are available by specifying '
176 176 b'"--optimize <name>":\n\n'
177 177 )
178 178 )
179 179 upgrade_op.print_unused_optimizations()
180 180 return
181 181
182 182 if not (upgrade_op.upgrade_actions or upgrade_op.removed_actions):
183 183 ui.status(_(b'nothing to do\n'))
184 184 return
185 185 # Else we're in the run=true case.
186 186 ui.write(_(b'upgrade will perform the following actions:\n\n'))
187 187 upgrade_op.print_requirements()
188 188 upgrade_op.print_optimisations()
189 189 upgrade_op.print_upgrade_actions()
190 190 upgrade_op.print_affected_revlogs()
191 191
192 192 ui.status(_(b'beginning upgrade...\n'))
193 193 with repo.wlock(), repo.lock():
194 194 ui.status(_(b'repository locked and read-only\n'))
195 195 # Our strategy for upgrading the repository is to create a new,
196 196 # temporary repository, write data to it, then do a swap of the
197 197 # data. There are less heavyweight ways to do this, but it is easier
198 198 # to create a new repo object than to instantiate all the components
199 199 # (like the store) separately.
200 200 tmppath = pycompat.mkdtemp(prefix=b'upgrade.', dir=repo.path)
201 201 backuppath = None
202 202 try:
203 203 ui.status(
204 204 _(
205 205 b'creating temporary repository to stage upgraded '
206 206 b'data: %s\n'
207 207 )
208 208 % tmppath
209 209 )
210 210
211 211 # clone ui without using ui.copy because repo.ui is protected
212 212 repoui = repo.ui.__class__(repo.ui)
213 213 dstrepo = hg.repository(repoui, path=tmppath, create=True)
214 214
215 215 with dstrepo.wlock(), dstrepo.lock():
216 216 backuppath = upgrade_engine.upgrade(
217 217 ui, repo, dstrepo, upgrade_op
218 218 )
219 219
220 220 finally:
221 221 ui.status(_(b'removing temporary repository %s\n') % tmppath)
222 222 repo.vfs.rmtree(tmppath, forcibly=True)
223 223
224 224 if backuppath and not ui.quiet:
225 225 ui.warn(
226 226 _(b'copy of old repository backed up at %s\n') % backuppath
227 227 )
228 228 ui.warn(
229 229 _(
230 230 b'the old repository will not be deleted; remove '
231 231 b'it to free up disk space once the upgraded '
232 232 b'repository is verified\n'
233 233 )
234 234 )
235 235
236 236 upgrade_op.print_post_op_messages()
237 237
238 238
239 239 def upgrade_share_to_safe(
240 240 ui,
241 241 hgvfs,
242 242 storevfs,
243 243 current_requirements,
244 244 mismatch_config,
245 245 mismatch_warn,
246 246 ):
247 247 """Upgrades a share to use share-safe mechanism"""
248 248 wlock = None
249 249 store_requirements = localrepo._readrequires(storevfs, False)
250 250 original_crequirements = current_requirements.copy()
251 251 # after upgrade, store requires will be shared, so lets find
252 252 # the requirements which are not present in store and
253 253 # write them to share's .hg/requires
254 254 diffrequires = current_requirements - store_requirements
255 255 # add share-safe requirement as it will mark the share as share-safe
256 256 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
257 257 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
258 258 # in `allow` case, we don't try to upgrade, we just respect the source
259 259 # state, update requirements and continue
260 260 if mismatch_config == b'allow':
261 261 return
262 262 try:
263 263 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
264 264 # some process might change the requirement in between, re-read
265 265 # and update current_requirements
266 266 locked_requirements = localrepo._readrequires(hgvfs, True)
267 267 if locked_requirements != original_crequirements:
268 268 removed = current_requirements - locked_requirements
269 269 # update current_requirements in place because it's passed
270 270 # as reference
271 271 current_requirements -= removed
272 272 current_requirements |= locked_requirements
273 273 diffrequires = current_requirements - store_requirements
274 274 # add share-safe requirement as it will mark the share as share-safe
275 275 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
276 276 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
277 277 scmutil.writerequires(hgvfs, diffrequires)
278 278 ui.warn(_(b'repository upgraded to use share-safe mode\n'))
279 279 except error.LockError as e:
280 280 hint = _(
281 "see `hg help config.format.use-share-safe` for more information"
281 b"see `hg help config.format.use-share-safe` for more information"
282 282 )
283 283 if mismatch_config == b'upgrade-abort':
284 284 raise error.Abort(
285 285 _(b'failed to upgrade share, got error: %s')
286 286 % stringutil.forcebytestr(e.strerror),
287 287 hint=hint,
288 288 )
289 289 elif mismatch_warn:
290 290 ui.warn(
291 291 _(b'failed to upgrade share, got error: %s\n')
292 292 % stringutil.forcebytestr(e.strerror),
293 293 hint=hint,
294 294 )
295 295 finally:
296 296 if wlock:
297 297 wlock.release()
298 298
299 299
300 300 def downgrade_share_to_non_safe(
301 301 ui,
302 302 hgvfs,
303 303 sharedvfs,
304 304 current_requirements,
305 305 mismatch_config,
306 306 mismatch_warn,
307 307 ):
308 308 """Downgrades a share which use share-safe to not use it"""
309 309 wlock = None
310 310 source_requirements = localrepo._readrequires(sharedvfs, True)
311 311 original_crequirements = current_requirements.copy()
312 312 # we cannot be 100% sure on which requirements were present in store when
313 313 # the source supported share-safe. However, we do know that working
314 314 # directory requirements were not there. Hence we remove them
315 315 source_requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS
316 316 current_requirements |= source_requirements
317 317 current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT)
318 318 if mismatch_config == b'allow':
319 319 return
320 320
321 321 try:
322 322 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
323 323 # some process might change the requirement in between, re-read
324 324 # and update current_requirements
325 325 locked_requirements = localrepo._readrequires(hgvfs, True)
326 326 if locked_requirements != original_crequirements:
327 327 removed = current_requirements - locked_requirements
328 328 # update current_requirements in place because it's passed
329 329 # as reference
330 330 current_requirements -= removed
331 331 current_requirements |= locked_requirements
332 332 current_requirements |= source_requirements
333 333 current_requirements -= set(requirementsmod.SHARESAFE_REQUIREMENT)
334 334 scmutil.writerequires(hgvfs, current_requirements)
335 335 ui.warn(_(b'repository downgraded to not use share-safe mode\n'))
336 336 except error.LockError as e:
337 337 hint = _(
338 "see `hg help config.format.use-share-safe` for more information"
338 b"see `hg help config.format.use-share-safe` for more information"
339 339 )
340 340 # If upgrade-abort is set, abort when upgrade fails, else let the
341 341 # process continue as `upgrade-allow` is set
342 342 if mismatch_config == b'downgrade-abort':
343 343 raise error.Abort(
344 344 _(b'failed to downgrade share, got error: %s')
345 345 % stringutil.forcebytestr(e.strerror),
346 346 hint=hint,
347 347 )
348 348 elif mismatch_warn:
349 349 ui.warn(
350 350 _(b'failed to downgrade share, got error: %s\n')
351 351 % stringutil.forcebytestr(e.strerror),
352 352 hint=hint,
353 353 )
354 354 finally:
355 355 if wlock:
356 356 wlock.release()
General Comments 0
You need to be logged in to leave comments. Login now