##// END OF EJS Templates
pytype: stop excluding upgrade.py...
Matt Harbison -
r49303:a4d8de93 default
parent child Browse files
Show More
@@ -1,401 +1,401
1 # upgrade.py - functions for in place upgrade of Mercurial repository
1 # upgrade.py - functions for in place upgrade of Mercurial repository
2 #
2 #
3 # Copyright (c) 2016-present, Gregory Szorc
3 # Copyright (c) 2016-present, Gregory Szorc
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 from .i18n import _
10 from .i18n import _
11 from . import (
11 from . import (
12 error,
12 error,
13 hg,
13 hg,
14 localrepo,
14 localrepo,
15 lock as lockmod,
15 lock as lockmod,
16 pycompat,
16 pycompat,
17 requirements as requirementsmod,
17 requirements as requirementsmod,
18 scmutil,
18 scmutil,
19 )
19 )
20
20
21 from .upgrade_utils import (
21 from .upgrade_utils import (
22 actions as upgrade_actions,
22 actions as upgrade_actions,
23 engine as upgrade_engine,
23 engine as upgrade_engine,
24 )
24 )
25
25
26 from .utils import (
26 from .utils import (
27 stringutil,
27 stringutil,
28 )
28 )
29
29
30 allformatvariant = upgrade_actions.allformatvariant
30 allformatvariant = upgrade_actions.allformatvariant
31
31
32
32
33 def upgraderepo(
33 def upgraderepo(
34 ui,
34 ui,
35 repo,
35 repo,
36 run=False,
36 run=False,
37 optimize=None,
37 optimize=None,
38 backup=True,
38 backup=True,
39 manifest=None,
39 manifest=None,
40 changelog=None,
40 changelog=None,
41 filelogs=None,
41 filelogs=None,
42 ):
42 ):
43 """Upgrade a repository in place."""
43 """Upgrade a repository in place."""
44 if optimize is None:
44 if optimize is None:
45 optimize = {}
45 optimize = set()
46 repo = repo.unfiltered()
46 repo = repo.unfiltered()
47
47
48 specified_revlogs = {}
48 specified_revlogs = {}
49 if changelog is not None:
49 if changelog is not None:
50 specified_revlogs[upgrade_engine.UPGRADE_CHANGELOG] = changelog
50 specified_revlogs[upgrade_engine.UPGRADE_CHANGELOG] = changelog
51 if manifest is not None:
51 if manifest is not None:
52 specified_revlogs[upgrade_engine.UPGRADE_MANIFEST] = manifest
52 specified_revlogs[upgrade_engine.UPGRADE_MANIFEST] = manifest
53 if filelogs is not None:
53 if filelogs is not None:
54 specified_revlogs[upgrade_engine.UPGRADE_FILELOGS] = filelogs
54 specified_revlogs[upgrade_engine.UPGRADE_FILELOGS] = filelogs
55
55
56 # Ensure the repository can be upgraded.
56 # Ensure the repository can be upgraded.
57 upgrade_actions.check_source_requirements(repo)
57 upgrade_actions.check_source_requirements(repo)
58
58
59 default_options = localrepo.defaultcreateopts(repo.ui)
59 default_options = localrepo.defaultcreateopts(repo.ui)
60 newreqs = localrepo.newreporequirements(repo.ui, default_options)
60 newreqs = localrepo.newreporequirements(repo.ui, default_options)
61 newreqs.update(upgrade_actions.preservedrequirements(repo))
61 newreqs.update(upgrade_actions.preservedrequirements(repo))
62
62
63 upgrade_actions.check_requirements_changes(repo, newreqs)
63 upgrade_actions.check_requirements_changes(repo, newreqs)
64
64
65 # Find and validate all improvements that can be made.
65 # Find and validate all improvements that can be made.
66 alloptimizations = upgrade_actions.findoptimizations(repo)
66 alloptimizations = upgrade_actions.findoptimizations(repo)
67
67
68 # Apply and Validate arguments.
68 # Apply and Validate arguments.
69 optimizations = []
69 optimizations = []
70 for o in alloptimizations:
70 for o in alloptimizations:
71 if o.name in optimize:
71 if o.name in optimize:
72 optimizations.append(o)
72 optimizations.append(o)
73 optimize.discard(o.name)
73 optimize.discard(o.name)
74
74
75 if optimize: # anything left is unknown
75 if optimize: # anything left is unknown
76 raise error.Abort(
76 raise error.Abort(
77 _(b'unknown optimization action requested: %s')
77 _(b'unknown optimization action requested: %s')
78 % b', '.join(sorted(optimize)),
78 % b', '.join(sorted(optimize)),
79 hint=_(b'run without arguments to see valid optimizations'),
79 hint=_(b'run without arguments to see valid optimizations'),
80 )
80 )
81
81
82 format_upgrades = upgrade_actions.find_format_upgrades(repo)
82 format_upgrades = upgrade_actions.find_format_upgrades(repo)
83 up_actions = upgrade_actions.determine_upgrade_actions(
83 up_actions = upgrade_actions.determine_upgrade_actions(
84 repo, format_upgrades, optimizations, repo.requirements, newreqs
84 repo, format_upgrades, optimizations, repo.requirements, newreqs
85 )
85 )
86 removed_actions = upgrade_actions.find_format_downgrades(repo)
86 removed_actions = upgrade_actions.find_format_downgrades(repo)
87
87
88 # check if we need to touch revlog and if so, which ones
88 # check if we need to touch revlog and if so, which ones
89
89
90 touched_revlogs = set()
90 touched_revlogs = set()
91 overwrite_msg = _(b'warning: ignoring %14s, as upgrade is changing: %s\n')
91 overwrite_msg = _(b'warning: ignoring %14s, as upgrade is changing: %s\n')
92 select_msg = _(b'note: selecting %s for processing to change: %s\n')
92 select_msg = _(b'note: selecting %s for processing to change: %s\n')
93 msg_issued = 0
93 msg_issued = 0
94
94
95 FL = upgrade_engine.UPGRADE_FILELOGS
95 FL = upgrade_engine.UPGRADE_FILELOGS
96 MN = upgrade_engine.UPGRADE_MANIFEST
96 MN = upgrade_engine.UPGRADE_MANIFEST
97 CL = upgrade_engine.UPGRADE_CHANGELOG
97 CL = upgrade_engine.UPGRADE_CHANGELOG
98
98
99 if optimizations:
99 if optimizations:
100 if any(specified_revlogs.values()):
100 if any(specified_revlogs.values()):
101 # we have some limitation on revlogs to be recloned
101 # we have some limitation on revlogs to be recloned
102 for rl, enabled in specified_revlogs.items():
102 for rl, enabled in specified_revlogs.items():
103 if enabled:
103 if enabled:
104 touched_revlogs.add(rl)
104 touched_revlogs.add(rl)
105 else:
105 else:
106 touched_revlogs = set(upgrade_engine.UPGRADE_ALL_REVLOGS)
106 touched_revlogs = set(upgrade_engine.UPGRADE_ALL_REVLOGS)
107 for rl, enabled in specified_revlogs.items():
107 for rl, enabled in specified_revlogs.items():
108 if not enabled:
108 if not enabled:
109 touched_revlogs.discard(rl)
109 touched_revlogs.discard(rl)
110
110
111 for action in sorted(up_actions + removed_actions, key=lambda a: a.name):
111 for action in sorted(up_actions + removed_actions, key=lambda a: a.name):
112 # optimisation does not "requires anything, they just needs it.
112 # optimisation does not "requires anything, they just needs it.
113 if action.type != upgrade_actions.FORMAT_VARIANT:
113 if action.type != upgrade_actions.FORMAT_VARIANT:
114 continue
114 continue
115
115
116 if action.touches_filelogs and FL not in touched_revlogs:
116 if action.touches_filelogs and FL not in touched_revlogs:
117 if FL in specified_revlogs:
117 if FL in specified_revlogs:
118 if not specified_revlogs[FL]:
118 if not specified_revlogs[FL]:
119 msg = overwrite_msg % (b'--no-filelogs', action.name)
119 msg = overwrite_msg % (b'--no-filelogs', action.name)
120 ui.warn(msg)
120 ui.warn(msg)
121 msg_issued = 2
121 msg_issued = 2
122 else:
122 else:
123 msg = select_msg % (b'all-filelogs', action.name)
123 msg = select_msg % (b'all-filelogs', action.name)
124 ui.status(msg)
124 ui.status(msg)
125 if not ui.quiet:
125 if not ui.quiet:
126 msg_issued = 1
126 msg_issued = 1
127 touched_revlogs.add(FL)
127 touched_revlogs.add(FL)
128
128
129 if action.touches_manifests and MN not in touched_revlogs:
129 if action.touches_manifests and MN not in touched_revlogs:
130 if MN in specified_revlogs:
130 if MN in specified_revlogs:
131 if not specified_revlogs[MN]:
131 if not specified_revlogs[MN]:
132 msg = overwrite_msg % (b'--no-manifest', action.name)
132 msg = overwrite_msg % (b'--no-manifest', action.name)
133 ui.warn(msg)
133 ui.warn(msg)
134 msg_issued = 2
134 msg_issued = 2
135 else:
135 else:
136 msg = select_msg % (b'all-manifestlogs', action.name)
136 msg = select_msg % (b'all-manifestlogs', action.name)
137 ui.status(msg)
137 ui.status(msg)
138 if not ui.quiet:
138 if not ui.quiet:
139 msg_issued = 1
139 msg_issued = 1
140 touched_revlogs.add(MN)
140 touched_revlogs.add(MN)
141
141
142 if action.touches_changelog and CL not in touched_revlogs:
142 if action.touches_changelog and CL not in touched_revlogs:
143 if CL in specified_revlogs:
143 if CL in specified_revlogs:
144 if not specified_revlogs[CL]:
144 if not specified_revlogs[CL]:
145 msg = overwrite_msg % (b'--no-changelog', action.name)
145 msg = overwrite_msg % (b'--no-changelog', action.name)
146 ui.warn(msg)
146 ui.warn(msg)
147 msg_issued = True
147 msg_issued = True
148 else:
148 else:
149 msg = select_msg % (b'changelog', action.name)
149 msg = select_msg % (b'changelog', action.name)
150 ui.status(msg)
150 ui.status(msg)
151 if not ui.quiet:
151 if not ui.quiet:
152 msg_issued = 1
152 msg_issued = 1
153 touched_revlogs.add(CL)
153 touched_revlogs.add(CL)
154 if msg_issued >= 2:
154 if msg_issued >= 2:
155 ui.warn((b"\n"))
155 ui.warn((b"\n"))
156 elif msg_issued >= 1:
156 elif msg_issued >= 1:
157 ui.status((b"\n"))
157 ui.status((b"\n"))
158
158
159 upgrade_op = upgrade_actions.UpgradeOperation(
159 upgrade_op = upgrade_actions.UpgradeOperation(
160 ui,
160 ui,
161 newreqs,
161 newreqs,
162 repo.requirements,
162 repo.requirements,
163 up_actions,
163 up_actions,
164 removed_actions,
164 removed_actions,
165 touched_revlogs,
165 touched_revlogs,
166 backup,
166 backup,
167 )
167 )
168
168
169 if not run:
169 if not run:
170 fromconfig = []
170 fromconfig = []
171 onlydefault = []
171 onlydefault = []
172
172
173 for d in format_upgrades:
173 for d in format_upgrades:
174 if d.fromconfig(repo):
174 if d.fromconfig(repo):
175 fromconfig.append(d)
175 fromconfig.append(d)
176 elif d.default:
176 elif d.default:
177 onlydefault.append(d)
177 onlydefault.append(d)
178
178
179 if fromconfig or onlydefault:
179 if fromconfig or onlydefault:
180
180
181 if fromconfig:
181 if fromconfig:
182 ui.status(
182 ui.status(
183 _(
183 _(
184 b'repository lacks features recommended by '
184 b'repository lacks features recommended by '
185 b'current config options:\n\n'
185 b'current config options:\n\n'
186 )
186 )
187 )
187 )
188 for i in fromconfig:
188 for i in fromconfig:
189 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
189 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
190
190
191 if onlydefault:
191 if onlydefault:
192 ui.status(
192 ui.status(
193 _(
193 _(
194 b'repository lacks features used by the default '
194 b'repository lacks features used by the default '
195 b'config options:\n\n'
195 b'config options:\n\n'
196 )
196 )
197 )
197 )
198 for i in onlydefault:
198 for i in onlydefault:
199 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
199 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
200
200
201 ui.status(b'\n')
201 ui.status(b'\n')
202 else:
202 else:
203 ui.status(_(b'(no format upgrades found in existing repository)\n'))
203 ui.status(_(b'(no format upgrades found in existing repository)\n'))
204
204
205 ui.status(
205 ui.status(
206 _(
206 _(
207 b'performing an upgrade with "--run" will make the following '
207 b'performing an upgrade with "--run" will make the following '
208 b'changes:\n\n'
208 b'changes:\n\n'
209 )
209 )
210 )
210 )
211
211
212 upgrade_op.print_requirements()
212 upgrade_op.print_requirements()
213 upgrade_op.print_optimisations()
213 upgrade_op.print_optimisations()
214 upgrade_op.print_upgrade_actions()
214 upgrade_op.print_upgrade_actions()
215 upgrade_op.print_affected_revlogs()
215 upgrade_op.print_affected_revlogs()
216
216
217 if upgrade_op.unused_optimizations:
217 if upgrade_op.unused_optimizations:
218 ui.status(
218 ui.status(
219 _(
219 _(
220 b'additional optimizations are available by specifying '
220 b'additional optimizations are available by specifying '
221 b'"--optimize <name>":\n\n'
221 b'"--optimize <name>":\n\n'
222 )
222 )
223 )
223 )
224 upgrade_op.print_unused_optimizations()
224 upgrade_op.print_unused_optimizations()
225 return
225 return
226
226
227 if not (upgrade_op.upgrade_actions or upgrade_op.removed_actions):
227 if not (upgrade_op.upgrade_actions or upgrade_op.removed_actions):
228 ui.status(_(b'nothing to do\n'))
228 ui.status(_(b'nothing to do\n'))
229 return
229 return
230 # Else we're in the run=true case.
230 # Else we're in the run=true case.
231 ui.write(_(b'upgrade will perform the following actions:\n\n'))
231 ui.write(_(b'upgrade will perform the following actions:\n\n'))
232 upgrade_op.print_requirements()
232 upgrade_op.print_requirements()
233 upgrade_op.print_optimisations()
233 upgrade_op.print_optimisations()
234 upgrade_op.print_upgrade_actions()
234 upgrade_op.print_upgrade_actions()
235 upgrade_op.print_affected_revlogs()
235 upgrade_op.print_affected_revlogs()
236
236
237 ui.status(_(b'beginning upgrade...\n'))
237 ui.status(_(b'beginning upgrade...\n'))
238 with repo.wlock(), repo.lock():
238 with repo.wlock(), repo.lock():
239 ui.status(_(b'repository locked and read-only\n'))
239 ui.status(_(b'repository locked and read-only\n'))
240 # Our strategy for upgrading the repository is to create a new,
240 # Our strategy for upgrading the repository is to create a new,
241 # temporary repository, write data to it, then do a swap of the
241 # temporary repository, write data to it, then do a swap of the
242 # data. There are less heavyweight ways to do this, but it is easier
242 # data. There are less heavyweight ways to do this, but it is easier
243 # to create a new repo object than to instantiate all the components
243 # to create a new repo object than to instantiate all the components
244 # (like the store) separately.
244 # (like the store) separately.
245 tmppath = pycompat.mkdtemp(prefix=b'upgrade.', dir=repo.path)
245 tmppath = pycompat.mkdtemp(prefix=b'upgrade.', dir=repo.path)
246 backuppath = None
246 backuppath = None
247 try:
247 try:
248 ui.status(
248 ui.status(
249 _(
249 _(
250 b'creating temporary repository to stage upgraded '
250 b'creating temporary repository to stage upgraded '
251 b'data: %s\n'
251 b'data: %s\n'
252 )
252 )
253 % tmppath
253 % tmppath
254 )
254 )
255
255
256 # clone ui without using ui.copy because repo.ui is protected
256 # clone ui without using ui.copy because repo.ui is protected
257 repoui = repo.ui.__class__(repo.ui)
257 repoui = repo.ui.__class__(repo.ui)
258 dstrepo = hg.repository(repoui, path=tmppath, create=True)
258 dstrepo = hg.repository(repoui, path=tmppath, create=True)
259
259
260 with dstrepo.wlock(), dstrepo.lock():
260 with dstrepo.wlock(), dstrepo.lock():
261 backuppath = upgrade_engine.upgrade(
261 backuppath = upgrade_engine.upgrade(
262 ui, repo, dstrepo, upgrade_op
262 ui, repo, dstrepo, upgrade_op
263 )
263 )
264
264
265 finally:
265 finally:
266 ui.status(_(b'removing temporary repository %s\n') % tmppath)
266 ui.status(_(b'removing temporary repository %s\n') % tmppath)
267 repo.vfs.rmtree(tmppath, forcibly=True)
267 repo.vfs.rmtree(tmppath, forcibly=True)
268
268
269 if backuppath and not ui.quiet:
269 if backuppath and not ui.quiet:
270 ui.warn(
270 ui.warn(
271 _(b'copy of old repository backed up at %s\n') % backuppath
271 _(b'copy of old repository backed up at %s\n') % backuppath
272 )
272 )
273 ui.warn(
273 ui.warn(
274 _(
274 _(
275 b'the old repository will not be deleted; remove '
275 b'the old repository will not be deleted; remove '
276 b'it to free up disk space once the upgraded '
276 b'it to free up disk space once the upgraded '
277 b'repository is verified\n'
277 b'repository is verified\n'
278 )
278 )
279 )
279 )
280
280
281 upgrade_op.print_post_op_messages()
281 upgrade_op.print_post_op_messages()
282
282
283
283
284 def upgrade_share_to_safe(
284 def upgrade_share_to_safe(
285 ui,
285 ui,
286 hgvfs,
286 hgvfs,
287 storevfs,
287 storevfs,
288 current_requirements,
288 current_requirements,
289 mismatch_config,
289 mismatch_config,
290 mismatch_warn,
290 mismatch_warn,
291 ):
291 ):
292 """Upgrades a share to use share-safe mechanism"""
292 """Upgrades a share to use share-safe mechanism"""
293 wlock = None
293 wlock = None
294 store_requirements = localrepo._readrequires(storevfs, False)
294 store_requirements = localrepo._readrequires(storevfs, False)
295 original_crequirements = current_requirements.copy()
295 original_crequirements = current_requirements.copy()
296 # after upgrade, store requires will be shared, so lets find
296 # after upgrade, store requires will be shared, so lets find
297 # the requirements which are not present in store and
297 # the requirements which are not present in store and
298 # write them to share's .hg/requires
298 # write them to share's .hg/requires
299 diffrequires = current_requirements - store_requirements
299 diffrequires = current_requirements - store_requirements
300 # add share-safe requirement as it will mark the share as share-safe
300 # add share-safe requirement as it will mark the share as share-safe
301 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
301 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
302 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
302 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
303 # in `allow` case, we don't try to upgrade, we just respect the source
303 # in `allow` case, we don't try to upgrade, we just respect the source
304 # state, update requirements and continue
304 # state, update requirements and continue
305 if mismatch_config == b'allow':
305 if mismatch_config == b'allow':
306 return
306 return
307 try:
307 try:
308 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
308 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
309 # some process might change the requirement in between, re-read
309 # some process might change the requirement in between, re-read
310 # and update current_requirements
310 # and update current_requirements
311 locked_requirements = localrepo._readrequires(hgvfs, True)
311 locked_requirements = localrepo._readrequires(hgvfs, True)
312 if locked_requirements != original_crequirements:
312 if locked_requirements != original_crequirements:
313 removed = current_requirements - locked_requirements
313 removed = current_requirements - locked_requirements
314 # update current_requirements in place because it's passed
314 # update current_requirements in place because it's passed
315 # as reference
315 # as reference
316 current_requirements -= removed
316 current_requirements -= removed
317 current_requirements |= locked_requirements
317 current_requirements |= locked_requirements
318 diffrequires = current_requirements - store_requirements
318 diffrequires = current_requirements - store_requirements
319 # add share-safe requirement as it will mark the share as share-safe
319 # add share-safe requirement as it will mark the share as share-safe
320 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
320 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
321 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
321 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
322 scmutil.writerequires(hgvfs, diffrequires)
322 scmutil.writerequires(hgvfs, diffrequires)
323 ui.warn(_(b'repository upgraded to use share-safe mode\n'))
323 ui.warn(_(b'repository upgraded to use share-safe mode\n'))
324 except error.LockError as e:
324 except error.LockError as e:
325 hint = _(
325 hint = _(
326 b"see `hg help config.format.use-share-safe` for more information"
326 b"see `hg help config.format.use-share-safe` for more information"
327 )
327 )
328 if mismatch_config == b'upgrade-abort':
328 if mismatch_config == b'upgrade-abort':
329 raise error.Abort(
329 raise error.Abort(
330 _(b'failed to upgrade share, got error: %s')
330 _(b'failed to upgrade share, got error: %s')
331 % stringutil.forcebytestr(e.strerror),
331 % stringutil.forcebytestr(e.strerror),
332 hint=hint,
332 hint=hint,
333 )
333 )
334 elif mismatch_warn:
334 elif mismatch_warn:
335 ui.warn(
335 ui.warn(
336 _(b'failed to upgrade share, got error: %s\n')
336 _(b'failed to upgrade share, got error: %s\n')
337 % stringutil.forcebytestr(e.strerror),
337 % stringutil.forcebytestr(e.strerror),
338 hint=hint,
338 hint=hint,
339 )
339 )
340 finally:
340 finally:
341 if wlock:
341 if wlock:
342 wlock.release()
342 wlock.release()
343
343
344
344
345 def downgrade_share_to_non_safe(
345 def downgrade_share_to_non_safe(
346 ui,
346 ui,
347 hgvfs,
347 hgvfs,
348 sharedvfs,
348 sharedvfs,
349 current_requirements,
349 current_requirements,
350 mismatch_config,
350 mismatch_config,
351 mismatch_warn,
351 mismatch_warn,
352 ):
352 ):
353 """Downgrades a share which use share-safe to not use it"""
353 """Downgrades a share which use share-safe to not use it"""
354 wlock = None
354 wlock = None
355 source_requirements = localrepo._readrequires(sharedvfs, True)
355 source_requirements = localrepo._readrequires(sharedvfs, True)
356 original_crequirements = current_requirements.copy()
356 original_crequirements = current_requirements.copy()
357 # we cannot be 100% sure on which requirements were present in store when
357 # we cannot be 100% sure on which requirements were present in store when
358 # the source supported share-safe. However, we do know that working
358 # the source supported share-safe. However, we do know that working
359 # directory requirements were not there. Hence we remove them
359 # directory requirements were not there. Hence we remove them
360 source_requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS
360 source_requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS
361 current_requirements |= source_requirements
361 current_requirements |= source_requirements
362 current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT)
362 current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT)
363 if mismatch_config == b'allow':
363 if mismatch_config == b'allow':
364 return
364 return
365
365
366 try:
366 try:
367 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
367 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
368 # some process might change the requirement in between, re-read
368 # some process might change the requirement in between, re-read
369 # and update current_requirements
369 # and update current_requirements
370 locked_requirements = localrepo._readrequires(hgvfs, True)
370 locked_requirements = localrepo._readrequires(hgvfs, True)
371 if locked_requirements != original_crequirements:
371 if locked_requirements != original_crequirements:
372 removed = current_requirements - locked_requirements
372 removed = current_requirements - locked_requirements
373 # update current_requirements in place because it's passed
373 # update current_requirements in place because it's passed
374 # as reference
374 # as reference
375 current_requirements -= removed
375 current_requirements -= removed
376 current_requirements |= locked_requirements
376 current_requirements |= locked_requirements
377 current_requirements |= source_requirements
377 current_requirements |= source_requirements
378 current_requirements -= set(requirementsmod.SHARESAFE_REQUIREMENT)
378 current_requirements -= set(requirementsmod.SHARESAFE_REQUIREMENT)
379 scmutil.writerequires(hgvfs, current_requirements)
379 scmutil.writerequires(hgvfs, current_requirements)
380 ui.warn(_(b'repository downgraded to not use share-safe mode\n'))
380 ui.warn(_(b'repository downgraded to not use share-safe mode\n'))
381 except error.LockError as e:
381 except error.LockError as e:
382 hint = _(
382 hint = _(
383 b"see `hg help config.format.use-share-safe` for more information"
383 b"see `hg help config.format.use-share-safe` for more information"
384 )
384 )
385 # If upgrade-abort is set, abort when upgrade fails, else let the
385 # If upgrade-abort is set, abort when upgrade fails, else let the
386 # process continue as `upgrade-allow` is set
386 # process continue as `upgrade-allow` is set
387 if mismatch_config == b'downgrade-abort':
387 if mismatch_config == b'downgrade-abort':
388 raise error.Abort(
388 raise error.Abort(
389 _(b'failed to downgrade share, got error: %s')
389 _(b'failed to downgrade share, got error: %s')
390 % stringutil.forcebytestr(e.strerror),
390 % stringutil.forcebytestr(e.strerror),
391 hint=hint,
391 hint=hint,
392 )
392 )
393 elif mismatch_warn:
393 elif mismatch_warn:
394 ui.warn(
394 ui.warn(
395 _(b'failed to downgrade share, got error: %s\n')
395 _(b'failed to downgrade share, got error: %s\n')
396 % stringutil.forcebytestr(e.strerror),
396 % stringutil.forcebytestr(e.strerror),
397 hint=hint,
397 hint=hint,
398 )
398 )
399 finally:
399 finally:
400 if wlock:
400 if wlock:
401 wlock.release()
401 wlock.release()
@@ -1,104 +1,102
1 #require pytype py3 slow
1 #require pytype py3 slow
2
2
3 $ cd $RUNTESTDIR/..
3 $ cd $RUNTESTDIR/..
4
4
5 Many of the individual files that are excluded here confuse pytype
5 Many of the individual files that are excluded here confuse pytype
6 because they do a mix of Python 2 and Python 3 things
6 because they do a mix of Python 2 and Python 3 things
7 conditionally. There's no good way to help it out with that as far as
7 conditionally. There's no good way to help it out with that as far as
8 I can tell, so let's just hide those files from it for now. We should
8 I can tell, so let's just hide those files from it for now. We should
9 endeavor to empty this list out over time, as some of these are
9 endeavor to empty this list out over time, as some of these are
10 probably hiding real problems.
10 probably hiding real problems.
11
11
12 mercurial/bundlerepo.py # no vfs and ui attrs on bundlerepo
12 mercurial/bundlerepo.py # no vfs and ui attrs on bundlerepo
13 mercurial/changegroup.py # mysterious incorrect type detection
13 mercurial/changegroup.py # mysterious incorrect type detection
14 mercurial/chgserver.py # [attribute-error]
14 mercurial/chgserver.py # [attribute-error]
15 mercurial/cmdutil.py # No attribute 'markcopied' on mercurial.context.filectx [attribute-error]
15 mercurial/cmdutil.py # No attribute 'markcopied' on mercurial.context.filectx [attribute-error]
16 mercurial/context.py # many [attribute-error]
16 mercurial/context.py # many [attribute-error]
17 mercurial/copies.py # No attribute 'items' on None [attribute-error]
17 mercurial/copies.py # No attribute 'items' on None [attribute-error]
18 mercurial/crecord.py # tons of [attribute-error], [module-attr]
18 mercurial/crecord.py # tons of [attribute-error], [module-attr]
19 mercurial/debugcommands.py # [wrong-arg-types]
19 mercurial/debugcommands.py # [wrong-arg-types]
20 mercurial/dispatch.py # initstdio: No attribute ... on TextIO [attribute-error]
20 mercurial/dispatch.py # initstdio: No attribute ... on TextIO [attribute-error]
21 mercurial/exchange.py # [attribute-error]
21 mercurial/exchange.py # [attribute-error]
22 mercurial/hgweb/hgweb_mod.py # [attribute-error], [name-error], [wrong-arg-types]
22 mercurial/hgweb/hgweb_mod.py # [attribute-error], [name-error], [wrong-arg-types]
23 mercurial/hgweb/server.py # [attribute-error], [name-error], [module-attr]
23 mercurial/hgweb/server.py # [attribute-error], [name-error], [module-attr]
24 mercurial/hgweb/webcommands.py # [missing-parameter]
24 mercurial/hgweb/webcommands.py # [missing-parameter]
25 mercurial/hgweb/wsgicgi.py # confused values in os.environ
25 mercurial/hgweb/wsgicgi.py # confused values in os.environ
26 mercurial/httppeer.py # [attribute-error], [wrong-arg-types]
26 mercurial/httppeer.py # [attribute-error], [wrong-arg-types]
27 mercurial/interfaces # No attribute 'capabilities' on peer [attribute-error]
27 mercurial/interfaces # No attribute 'capabilities' on peer [attribute-error]
28 mercurial/keepalive.py # [attribute-error]
28 mercurial/keepalive.py # [attribute-error]
29 mercurial/localrepo.py # [attribute-error]
29 mercurial/localrepo.py # [attribute-error]
30 mercurial/lsprof.py # unguarded import
30 mercurial/lsprof.py # unguarded import
31 mercurial/manifest.py # [unsupported-operands], [wrong-arg-types]
31 mercurial/manifest.py # [unsupported-operands], [wrong-arg-types]
32 mercurial/minirst.py # [unsupported-operands], [attribute-error]
32 mercurial/minirst.py # [unsupported-operands], [attribute-error]
33 mercurial/patch.py # [wrong-arg-types]
33 mercurial/patch.py # [wrong-arg-types]
34 mercurial/pure/osutil.py # [invalid-typevar], [not-callable]
34 mercurial/pure/osutil.py # [invalid-typevar], [not-callable]
35 mercurial/pure/parsers.py # [attribute-error]
35 mercurial/pure/parsers.py # [attribute-error]
36 mercurial/pycompat.py # bytes vs str issues
36 mercurial/pycompat.py # bytes vs str issues
37 mercurial/repoview.py # [attribute-error]
37 mercurial/repoview.py # [attribute-error]
38 mercurial/sslutil.py # [attribute-error]
38 mercurial/sslutil.py # [attribute-error]
39 mercurial/statprof.py # bytes vs str on TextIO.write() [wrong-arg-types]
39 mercurial/statprof.py # bytes vs str on TextIO.write() [wrong-arg-types]
40 mercurial/testing/storage.py # tons of [attribute-error]
40 mercurial/testing/storage.py # tons of [attribute-error]
41 mercurial/ui.py # [attribute-error], [wrong-arg-types]
41 mercurial/ui.py # [attribute-error], [wrong-arg-types]
42 mercurial/unionrepo.py # ui, svfs, unfiltered [attribute-error]
42 mercurial/unionrepo.py # ui, svfs, unfiltered [attribute-error]
43 mercurial/upgrade.py # line 84, in upgraderepo: No attribute 'discard' on Dict[nothing, nothing] [attribute-error]
44 mercurial/util.py # [attribute-error], [wrong-arg-count]
43 mercurial/util.py # [attribute-error], [wrong-arg-count]
45 mercurial/utils/procutil.py # [attribute-error], [module-attr], [bad-return-type]
44 mercurial/utils/procutil.py # [attribute-error], [module-attr], [bad-return-type]
46 mercurial/utils/stringutil.py # [module-attr], [wrong-arg-count]
45 mercurial/utils/stringutil.py # [module-attr], [wrong-arg-count]
47 mercurial/utils/memorytop.py # not 3.6 compatible
46 mercurial/utils/memorytop.py # not 3.6 compatible
48 mercurial/win32.py # [not-callable]
47 mercurial/win32.py # [not-callable]
49 mercurial/wireprotoframing.py # [unsupported-operands], [attribute-error], [import-error]
48 mercurial/wireprotoframing.py # [unsupported-operands], [attribute-error], [import-error]
50 mercurial/wireprotoserver.py # line 253, in _availableapis: No attribute '__iter__' on Callable[[Any, Any], Any] [attribute-error]
49 mercurial/wireprotoserver.py # line 253, in _availableapis: No attribute '__iter__' on Callable[[Any, Any], Any] [attribute-error]
51 mercurial/wireprotov1peer.py # [attribute-error]
50 mercurial/wireprotov1peer.py # [attribute-error]
52 mercurial/wireprotov1server.py # BUG?: BundleValueError handler accesses subclass's attrs
51 mercurial/wireprotov1server.py # BUG?: BundleValueError handler accesses subclass's attrs
53 mercurial/wireprotov2server.py # [unsupported-operands], [attribute-error]
52 mercurial/wireprotov2server.py # [unsupported-operands], [attribute-error]
54
53
55 TODO: use --no-cache on test server? Caching the files locally helps during
54 TODO: use --no-cache on test server? Caching the files locally helps during
56 development, but may be a hinderance for CI testing.
55 development, but may be a hinderance for CI testing.
57
56
58 $ pytype -V 3.6 --keep-going --jobs auto mercurial \
57 $ pytype -V 3.6 --keep-going --jobs auto mercurial \
59 > -x mercurial/bundlerepo.py \
58 > -x mercurial/bundlerepo.py \
60 > -x mercurial/changegroup.py \
59 > -x mercurial/changegroup.py \
61 > -x mercurial/chgserver.py \
60 > -x mercurial/chgserver.py \
62 > -x mercurial/cmdutil.py \
61 > -x mercurial/cmdutil.py \
63 > -x mercurial/context.py \
62 > -x mercurial/context.py \
64 > -x mercurial/copies.py \
63 > -x mercurial/copies.py \
65 > -x mercurial/crecord.py \
64 > -x mercurial/crecord.py \
66 > -x mercurial/debugcommands.py \
65 > -x mercurial/debugcommands.py \
67 > -x mercurial/dispatch.py \
66 > -x mercurial/dispatch.py \
68 > -x mercurial/exchange.py \
67 > -x mercurial/exchange.py \
69 > -x mercurial/hgweb/hgweb_mod.py \
68 > -x mercurial/hgweb/hgweb_mod.py \
70 > -x mercurial/hgweb/server.py \
69 > -x mercurial/hgweb/server.py \
71 > -x mercurial/hgweb/webcommands.py \
70 > -x mercurial/hgweb/webcommands.py \
72 > -x mercurial/hgweb/wsgicgi.py \
71 > -x mercurial/hgweb/wsgicgi.py \
73 > -x mercurial/httppeer.py \
72 > -x mercurial/httppeer.py \
74 > -x mercurial/interfaces \
73 > -x mercurial/interfaces \
75 > -x mercurial/keepalive.py \
74 > -x mercurial/keepalive.py \
76 > -x mercurial/localrepo.py \
75 > -x mercurial/localrepo.py \
77 > -x mercurial/lsprof.py \
76 > -x mercurial/lsprof.py \
78 > -x mercurial/manifest.py \
77 > -x mercurial/manifest.py \
79 > -x mercurial/minirst.py \
78 > -x mercurial/minirst.py \
80 > -x mercurial/patch.py \
79 > -x mercurial/patch.py \
81 > -x mercurial/pure/osutil.py \
80 > -x mercurial/pure/osutil.py \
82 > -x mercurial/pure/parsers.py \
81 > -x mercurial/pure/parsers.py \
83 > -x mercurial/pycompat.py \
82 > -x mercurial/pycompat.py \
84 > -x mercurial/repoview.py \
83 > -x mercurial/repoview.py \
85 > -x mercurial/sslutil.py \
84 > -x mercurial/sslutil.py \
86 > -x mercurial/statprof.py \
85 > -x mercurial/statprof.py \
87 > -x mercurial/testing/storage.py \
86 > -x mercurial/testing/storage.py \
88 > -x mercurial/thirdparty \
87 > -x mercurial/thirdparty \
89 > -x mercurial/ui.py \
88 > -x mercurial/ui.py \
90 > -x mercurial/unionrepo.py \
89 > -x mercurial/unionrepo.py \
91 > -x mercurial/upgrade.py \
92 > -x mercurial/utils/procutil.py \
90 > -x mercurial/utils/procutil.py \
93 > -x mercurial/utils/stringutil.py \
91 > -x mercurial/utils/stringutil.py \
94 > -x mercurial/utils/memorytop.py \
92 > -x mercurial/utils/memorytop.py \
95 > -x mercurial/win32.py \
93 > -x mercurial/win32.py \
96 > -x mercurial/wireprotoframing.py \
94 > -x mercurial/wireprotoframing.py \
97 > -x mercurial/wireprotoserver.py \
95 > -x mercurial/wireprotoserver.py \
98 > -x mercurial/wireprotov1peer.py \
96 > -x mercurial/wireprotov1peer.py \
99 > -x mercurial/wireprotov1server.py \
97 > -x mercurial/wireprotov1server.py \
100 > -x mercurial/wireprotov2server.py \
98 > -x mercurial/wireprotov2server.py \
101 > > $TESTTMP/pytype-output.txt || cat $TESTTMP/pytype-output.txt
99 > > $TESTTMP/pytype-output.txt || cat $TESTTMP/pytype-output.txt
102
100
103 Only show the results on a failure, because the output on success is also
101 Only show the results on a failure, because the output on success is also
104 voluminous and variable.
102 voluminous and variable.
General Comments 0
You need to be logged in to leave comments. Login now