comparison mercurial/debugcommands.py @ 47810:b30a53ffbf9b stable

debugcommands: introduce a debug command to repair repos affected by issue6528 This command is quite basic and slow, it will loop over the entirety of the filelogs in the repository and check each revision for corruption, then fixes the affected filelogs. It takes under 25 minutes for Mozilla-Central on my not-top-of-the-line laptop, using the `--to-report` and `--from-report` options will make this pretty tolerable to use, I think. This change also introduces a test for the fix. Differential Revision: https://phab.mercurial-scm.org/D11239
author Rapha?l Gom?s <rgomes@octobus.net>
date Tue, 27 Jul 2021 21:45:27 +0200
parents 284a20269a97
children 855463b5fe49
comparison
equal deleted inserted replaced
47809:3b04e4746020 47810:b30a53ffbf9b
69 pvec, 69 pvec,
70 pycompat, 70 pycompat,
71 registrar, 71 registrar,
72 repair, 72 repair,
73 repoview, 73 repoview,
74 requirements,
74 revlog, 75 revlog,
75 revset, 76 revset,
76 revsetlang, 77 revsetlang,
77 scmutil, 78 scmutil,
78 setdiscovery, 79 setdiscovery,
103 ) 104 )
104 105
105 from .revlogutils import ( 106 from .revlogutils import (
106 deltas as deltautil, 107 deltas as deltautil,
107 nodemap, 108 nodemap,
109 rewrite,
108 sidedata, 110 sidedata,
109 ) 111 )
110 112
111 release = lockmod.release 113 release = lockmod.release
112 114
1447 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n') 1449 ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
1448 for f in sorted(files): 1450 for f in sorted(files):
1449 if not m(f): 1451 if not m(f):
1450 continue 1452 continue
1451 ui.write(b"%s\n" % f) 1453 ui.write(b"%s\n" % f)
1454
1455
1456 @command(
1457 b"debug-repair-issue6528",
1458 [
1459 (
1460 b'',
1461 b'to-report',
1462 b'',
1463 _(b'build a report of affected revisions to this file'),
1464 _(b'FILE'),
1465 ),
1466 (
1467 b'',
1468 b'from-report',
1469 b'',
1470 _(b'repair revisions listed in this report file'),
1471 _(b'FILE'),
1472 ),
1473 ]
1474 + cmdutil.dryrunopts,
1475 )
1476 def debug_repair_issue6528(ui, repo, **opts):
1477 """find affected revisions and repair them. See issue6528 for more details.
1478
1479 The `--to-report` and `--from-report` flags allow you to cache and reuse the
1480 computation of affected revisions for a given repository across clones.
1481 The report format is line-based (with empty lines ignored):
1482
1483 ```
1484 <ascii-hex of the affected revision>,... <unencoded filelog index filename>
1485 ```
1486
1487 There can be multiple broken revisions per filelog, they are separated by
1488 a comma with no spaces. The only space is between the revision(s) and the
1489 filename.
1490
1491 Note that this does *not* mean that this repairs future affected revisions,
1492 that needs a separate fix at the exchange level that hasn't been written yet
1493 (as of 5.9rc0).
1494 """
1495 cmdutil.check_incompatible_arguments(
1496 opts, 'to_report', ['from_report', 'dry_run']
1497 )
1498 dry_run = opts.get('dry_run')
1499 to_report = opts.get('to_report')
1500 from_report = opts.get('from_report')
1501 # TODO maybe add filelog pattern and revision pattern parameters to help
1502 # narrow down the search for users that know what they're looking for?
1503
1504 if requirements.REVLOGV1_REQUIREMENT not in repo.requirements:
1505 msg = b"can only repair revlogv1 repositories, v2 is not affected"
1506 raise error.Abort(_(msg))
1507
1508 rewrite.repair_issue6528(
1509 ui, repo, dry_run=dry_run, to_report=to_report, from_report=from_report
1510 )
1452 1511
1453 1512
1454 @command(b'debugformat', [] + cmdutil.formatteropts) 1513 @command(b'debugformat', [] + cmdutil.formatteropts)
1455 def debugformat(ui, repo, **opts): 1514 def debugformat(ui, repo, **opts):
1456 """display format information about the current repository 1515 """display format information about the current repository