Show More
|
1 | NO CONTENT: new file 100644, binary diff hidden |
@@ -71,6 +71,7 b' from . import (' | |||
|
71 | 71 | registrar, |
|
72 | 72 | repair, |
|
73 | 73 | repoview, |
|
74 | requirements, | |
|
74 | 75 | revlog, |
|
75 | 76 | revset, |
|
76 | 77 | revsetlang, |
@@ -105,6 +106,7 b' from .utils import (' | |||
|
105 | 106 | from .revlogutils import ( |
|
106 | 107 | deltas as deltautil, |
|
107 | 108 | nodemap, |
|
109 | rewrite, | |
|
108 | 110 | sidedata, |
|
109 | 111 | ) |
|
110 | 112 | |
@@ -1451,6 +1453,63 b' def debugfileset(ui, repo, expr, **opts)' | |||
|
1451 | 1453 | ui.write(b"%s\n" % f) |
|
1452 | 1454 | |
|
1453 | 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 | ) | |
|
1511 | ||
|
1512 | ||
|
1454 | 1513 | @command(b'debugformat', [] + cmdutil.formatteropts) |
|
1455 | 1514 | def debugformat(ui, repo, **opts): |
|
1456 | 1515 | """display format information about the current repository |
@@ -7,6 +7,7 b'' | |||
|
7 | 7 | # This software may be used and distributed according to the terms of the |
|
8 | 8 | # GNU General Public License version 2 or any later version. |
|
9 | 9 | |
|
10 | import binascii | |
|
10 | 11 | import contextlib |
|
11 | 12 | import os |
|
12 | 13 | |
@@ -472,3 +473,224 b' def _rewrite_censor(' | |||
|
472 | 473 | new_index_file.write(entry_bin) |
|
473 | 474 | revlog._docket.index_end = new_index_file.tell() |
|
474 | 475 | revlog._docket.data_end = new_data_file.tell() |
|
476 | ||
|
477 | ||
|
478 | def _get_filename_from_filelog_index(path): | |
|
479 | # Drop the extension and the `data/` prefix | |
|
480 | path_part = path.rsplit(b'.', 1)[0].split(b'/', 1) | |
|
481 | if len(path_part) < 2: | |
|
482 | msg = _(b"cannot recognize filelog from filename: '%s'") | |
|
483 | msg %= path | |
|
484 | raise error.Abort(msg) | |
|
485 | ||
|
486 | return path_part[1] | |
|
487 | ||
|
488 | ||
|
489 | def _filelog_from_filename(repo, path): | |
|
490 | """Returns the filelog for the given `path`. Stolen from `engine.py`""" | |
|
491 | ||
|
492 | from .. import filelog # avoid cycle | |
|
493 | ||
|
494 | fl = filelog.filelog(repo.svfs, path) | |
|
495 | return fl | |
|
496 | ||
|
497 | ||
|
498 | def _write_swapped_parents(repo, rl, rev, offset, fp): | |
|
499 | """Swaps p1 and p2 and overwrites the revlog entry for `rev` in `fp`""" | |
|
500 | from ..pure import parsers # avoid cycle | |
|
501 | ||
|
502 | if repo._currentlock(repo._lockref) is None: | |
|
503 | # Let's be paranoid about it | |
|
504 | msg = "repo needs to be locked to rewrite parents" | |
|
505 | raise error.ProgrammingError(msg) | |
|
506 | ||
|
507 | index_format = parsers.IndexObject.index_format | |
|
508 | entry = rl.index[rev] | |
|
509 | new_entry = list(entry) | |
|
510 | new_entry[5], new_entry[6] = entry[6], entry[5] | |
|
511 | packed = index_format.pack(*new_entry[:8]) | |
|
512 | fp.seek(offset) | |
|
513 | fp.write(packed) | |
|
514 | ||
|
515 | ||
|
516 | def _reorder_filelog_parents(repo, fl, to_fix): | |
|
517 | """ | |
|
518 | Swaps p1 and p2 for all `to_fix` revisions of filelog `fl` and writes the | |
|
519 | new version to disk, overwriting the old one with a rename. | |
|
520 | """ | |
|
521 | from ..pure import parsers # avoid cycle | |
|
522 | ||
|
523 | ui = repo.ui | |
|
524 | assert len(to_fix) > 0 | |
|
525 | rl = fl._revlog | |
|
526 | if rl._format_version != constants.REVLOGV1: | |
|
527 | msg = "expected version 1 revlog, got version '%d'" % rl._format_version | |
|
528 | raise error.ProgrammingError(msg) | |
|
529 | ||
|
530 | index_file = rl._indexfile | |
|
531 | new_file_path = index_file + b'.tmp-parents-fix' | |
|
532 | repaired_msg = _(b"repaired revision %d of 'filelog %s'\n") | |
|
533 | ||
|
534 | with ui.uninterruptible(): | |
|
535 | try: | |
|
536 | util.copyfile( | |
|
537 | rl.opener.join(index_file), | |
|
538 | rl.opener.join(new_file_path), | |
|
539 | checkambig=rl._checkambig, | |
|
540 | ) | |
|
541 | ||
|
542 | with rl.opener(new_file_path, mode=b"r+") as fp: | |
|
543 | if rl._inline: | |
|
544 | index = parsers.InlinedIndexObject(fp.read()) | |
|
545 | for rev in fl.revs(): | |
|
546 | if rev in to_fix: | |
|
547 | offset = index._calculate_index(rev) | |
|
548 | _write_swapped_parents(repo, rl, rev, offset, fp) | |
|
549 | ui.write(repaired_msg % (rev, index_file)) | |
|
550 | else: | |
|
551 | index_format = parsers.IndexObject.index_format | |
|
552 | for rev in to_fix: | |
|
553 | offset = rev * index_format.size | |
|
554 | _write_swapped_parents(repo, rl, rev, offset, fp) | |
|
555 | ui.write(repaired_msg % (rev, index_file)) | |
|
556 | ||
|
557 | rl.opener.rename(new_file_path, index_file) | |
|
558 | rl.clearcaches() | |
|
559 | rl._loadindex() | |
|
560 | finally: | |
|
561 | util.tryunlink(new_file_path) | |
|
562 | ||
|
563 | ||
|
564 | def _is_revision_affected(ui, fl, filerev, path): | |
|
565 | """Mercurial currently (5.9rc0) uses `p1 == nullrev and p2 != nullrev` as a | |
|
566 | special meaning compared to the reverse in the context of filelog-based | |
|
567 | copytracing. issue6528 exists because new code assumed that parent ordering | |
|
568 | didn't matter, so this detects if the revision contains metadata (since | |
|
569 | it's only used for filelog-based copytracing) and its parents are in the | |
|
570 | "wrong" order.""" | |
|
571 | try: | |
|
572 | raw_text = fl.rawdata(filerev) | |
|
573 | except error.CensoredNodeError: | |
|
574 | # We don't care about censored nodes as they never carry metadata | |
|
575 | return False | |
|
576 | has_meta = raw_text.startswith(b'\x01\n') | |
|
577 | if has_meta: | |
|
578 | (p1, p2) = fl.parentrevs(filerev) | |
|
579 | if p1 != nullrev and p2 == nullrev: | |
|
580 | return True | |
|
581 | return False | |
|
582 | ||
|
583 | ||
|
584 | def _from_report(ui, repo, context, from_report, dry_run): | |
|
585 | """ | |
|
586 | Fix the revisions given in the `from_report` file, but still checks if the | |
|
587 | revisions are indeed affected to prevent an unfortunate cyclic situation | |
|
588 | where we'd swap well-ordered parents again. | |
|
589 | ||
|
590 | See the doc for `debug_fix_issue6528` for the format documentation. | |
|
591 | """ | |
|
592 | ui.write(_(b"loading report file '%s'\n") % from_report) | |
|
593 | ||
|
594 | with context(), open(from_report, mode='rb') as f: | |
|
595 | for line in f.read().split(b'\n'): | |
|
596 | if not line: | |
|
597 | continue | |
|
598 | filenodes, filename = line.split(b' ', 1) | |
|
599 | fl = _filelog_from_filename(repo, filename) | |
|
600 | to_fix = set( | |
|
601 | fl.rev(binascii.unhexlify(n)) for n in filenodes.split(b',') | |
|
602 | ) | |
|
603 | excluded = set() | |
|
604 | ||
|
605 | for filerev in to_fix: | |
|
606 | if _is_revision_affected(ui, fl, filerev, filename): | |
|
607 | msg = b"found affected revision %d for filelog '%s'\n" | |
|
608 | ui.warn(msg % (filerev, filename)) | |
|
609 | else: | |
|
610 | msg = _(b"revision %s of file '%s' is not affected\n") | |
|
611 | msg %= (binascii.hexlify(fl.node(filerev)), filename) | |
|
612 | ui.warn(msg) | |
|
613 | excluded.add(filerev) | |
|
614 | ||
|
615 | to_fix = to_fix - excluded | |
|
616 | if not to_fix: | |
|
617 | msg = _(b"no affected revisions were found for '%s'\n") | |
|
618 | ui.write(msg % filename) | |
|
619 | continue | |
|
620 | if not dry_run: | |
|
621 | _reorder_filelog_parents(repo, fl, sorted(to_fix)) | |
|
622 | ||
|
623 | ||
|
624 | def repair_issue6528(ui, repo, dry_run=False, to_report=None, from_report=None): | |
|
625 | from .. import store # avoid cycle | |
|
626 | ||
|
627 | @contextlib.contextmanager | |
|
628 | def context(): | |
|
629 | if dry_run or to_report: # No need for locking | |
|
630 | yield | |
|
631 | else: | |
|
632 | with repo.wlock(), repo.lock(): | |
|
633 | yield | |
|
634 | ||
|
635 | if from_report: | |
|
636 | return _from_report(ui, repo, context, from_report, dry_run) | |
|
637 | ||
|
638 | report_entries = [] | |
|
639 | ||
|
640 | with context(): | |
|
641 | files = list( | |
|
642 | (file_type, path) | |
|
643 | for (file_type, path, _e, _s) in repo.store.datafiles() | |
|
644 | if path.endswith(b'.i') and file_type & store.FILEFLAGS_FILELOG | |
|
645 | ) | |
|
646 | ||
|
647 | progress = ui.makeprogress( | |
|
648 | _(b"looking for affected revisions"), | |
|
649 | unit=_(b"filelogs"), | |
|
650 | total=len(files), | |
|
651 | ) | |
|
652 | found_nothing = True | |
|
653 | ||
|
654 | for file_type, path in files: | |
|
655 | if ( | |
|
656 | not path.endswith(b'.i') | |
|
657 | or not file_type & store.FILEFLAGS_FILELOG | |
|
658 | ): | |
|
659 | continue | |
|
660 | progress.increment() | |
|
661 | filename = _get_filename_from_filelog_index(path) | |
|
662 | fl = _filelog_from_filename(repo, filename) | |
|
663 | ||
|
664 | # Set of filerevs (or hex filenodes if `to_report`) that need fixing | |
|
665 | to_fix = set() | |
|
666 | for filerev in fl.revs(): | |
|
667 | # TODO speed up by looking at the start of the delta | |
|
668 | # If it hasn't changed, it's not worth looking at the other revs | |
|
669 | # in the same chain | |
|
670 | affected = _is_revision_affected(ui, fl, filerev, path) | |
|
671 | if affected: | |
|
672 | msg = b"found affected revision %d for filelog '%s'\n" | |
|
673 | ui.warn(msg % (filerev, path)) | |
|
674 | found_nothing = False | |
|
675 | if not dry_run: | |
|
676 | if to_report: | |
|
677 | to_fix.add(binascii.hexlify(fl.node(filerev))) | |
|
678 | else: | |
|
679 | to_fix.add(filerev) | |
|
680 | ||
|
681 | if to_fix: | |
|
682 | to_fix = sorted(to_fix) | |
|
683 | if to_report: | |
|
684 | report_entries.append((filename, to_fix)) | |
|
685 | else: | |
|
686 | _reorder_filelog_parents(repo, fl, to_fix) | |
|
687 | ||
|
688 | if found_nothing: | |
|
689 | ui.write(_(b"no affected revisions were found\n")) | |
|
690 | ||
|
691 | if to_report and report_entries: | |
|
692 | with open(to_report, mode="wb") as f: | |
|
693 | for path, to_fix in report_entries: | |
|
694 | f.write(b"%s %s\n" % (b",".join(to_fix), path)) | |
|
695 | ||
|
696 | progress.complete() |
@@ -74,6 +74,7 b' Do not show debug commands if there are ' | |||
|
74 | 74 | |
|
75 | 75 | Show debug commands if there are no other candidates |
|
76 | 76 | $ hg debugcomplete debug |
|
77 | debug-repair-issue6528 | |
|
77 | 78 | debugancestor |
|
78 | 79 | debugantivirusrunning |
|
79 | 80 | debugapplystreamclonebundle |
@@ -266,6 +267,7 b' Show all commands + options' | |||
|
266 | 267 | config: untrusted, exp-all-known, edit, local, source, shared, non-shared, global, template |
|
267 | 268 | continue: dry-run |
|
268 | 269 | copy: forget, after, at-rev, force, include, exclude, dry-run |
|
270 | debug-repair-issue6528: to-report, from-report, dry-run | |
|
269 | 271 | debugancestor: |
|
270 | 272 | debugantivirusrunning: |
|
271 | 273 | debugapplystreamclonebundle: |
@@ -975,6 +975,9 b' Test list of internal help commands' | |||
|
975 | 975 | $ hg help debug |
|
976 | 976 | debug commands (internal and unsupported): |
|
977 | 977 | |
|
978 | debug-repair-issue6528 | |
|
979 | find affected revisions and repair them. See issue6528 for more | |
|
980 | details. | |
|
978 | 981 | debugancestor |
|
979 | 982 | find the ancestor revision of two revisions in a given index |
|
980 | 983 | debugantivirusrunning |
@@ -3,7 +3,7 b' Test non-regression on the corruption as' | |||
|
3 | 3 | =============================================================== |
|
4 | 4 | |
|
5 | 5 | Setup |
|
6 | ----- | |
|
6 | ===== | |
|
7 | 7 | |
|
8 | 8 | $ hg init base-repo |
|
9 | 9 | $ cd base-repo |
@@ -93,7 +93,7 b' Check commit Graph' | |||
|
93 | 93 | |
|
94 | 94 | |
|
95 | 95 | Check the lack of corruption |
|
96 | ---------------------------- | |
|
96 | ============================ | |
|
97 | 97 | |
|
98 | 98 | $ hg clone --pull base-repo cloned |
|
99 | 99 | requesting all changes |
@@ -166,3 +166,249 b' Check commit Graph' | |||
|
166 | 166 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
167 | 167 | summary: c_base_c - create a.txt |
|
168 | 168 | |
|
169 | ||
|
170 | Test the command that fixes the issue | |
|
171 | ===================================== | |
|
172 | ||
|
173 | Restore a broken repository with multiple broken revisions and a filename that | |
|
174 | would get encoded to test the `report` options. | |
|
175 | It's a tarball because unbundle might magically fix the issue later. | |
|
176 | ||
|
177 | $ cd .. | |
|
178 | $ mkdir repo-to-fix | |
|
179 | $ cd repo-to-fix | |
|
180 | #if windows | |
|
181 | tar interprets `:` in paths (like `C:`) as being remote, force local on Windows | |
|
182 | only since some versions of tar don't have this flag. | |
|
183 | ||
|
184 | $ tar --force-local -xf $TESTDIR/bundles/issue6528.tar | |
|
185 | #else | |
|
186 | $ tar xf $TESTDIR/bundles/issue6528.tar | |
|
187 | #endif | |
|
188 | ||
|
189 | Check that the issue is present | |
|
190 | $ hg st | |
|
191 | M D.txt | |
|
192 | M b.txt | |
|
193 | $ hg debugrevlogindex b.txt | |
|
194 | rev linkrev nodeid p1 p2 | |
|
195 | 0 2 05b806ebe5ea 000000000000 000000000000 | |
|
196 | 1 3 a58b36ad6b65 05b806ebe5ea 000000000000 | |
|
197 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |
|
198 | 3 7 ea4f2f2463cc 216a5fe8b8ed 000000000000 | |
|
199 | $ hg debugrevlogindex D.txt | |
|
200 | rev linkrev nodeid p1 p2 | |
|
201 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |
|
202 | 1 7 2a80419dfc31 2a8d3833f2fb 000000000000 | |
|
203 | ||
|
204 | Dry-run the fix | |
|
205 | $ hg debug-repair-issue6528 --dry-run | |
|
206 | found affected revision 1 for filelog 'data/D.txt.i' | |
|
207 | found affected revision 1 for filelog 'data/b.txt.i' | |
|
208 | found affected revision 3 for filelog 'data/b.txt.i' | |
|
209 | $ hg st | |
|
210 | M D.txt | |
|
211 | M b.txt | |
|
212 | $ hg debugrevlogindex b.txt | |
|
213 | rev linkrev nodeid p1 p2 | |
|
214 | 0 2 05b806ebe5ea 000000000000 000000000000 | |
|
215 | 1 3 a58b36ad6b65 05b806ebe5ea 000000000000 | |
|
216 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |
|
217 | 3 7 ea4f2f2463cc 216a5fe8b8ed 000000000000 | |
|
218 | $ hg debugrevlogindex D.txt | |
|
219 | rev linkrev nodeid p1 p2 | |
|
220 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |
|
221 | 1 7 2a80419dfc31 2a8d3833f2fb 000000000000 | |
|
222 | ||
|
223 | Run the fix | |
|
224 | $ hg debug-repair-issue6528 | |
|
225 | found affected revision 1 for filelog 'data/D.txt.i' | |
|
226 | repaired revision 1 of 'filelog data/D.txt.i' | |
|
227 | found affected revision 1 for filelog 'data/b.txt.i' | |
|
228 | found affected revision 3 for filelog 'data/b.txt.i' | |
|
229 | repaired revision 1 of 'filelog data/b.txt.i' | |
|
230 | repaired revision 3 of 'filelog data/b.txt.i' | |
|
231 | ||
|
232 | Check that the fix worked and that running it twice does nothing | |
|
233 | $ hg st | |
|
234 | $ hg debugrevlogindex b.txt | |
|
235 | rev linkrev nodeid p1 p2 | |
|
236 | 0 2 05b806ebe5ea 000000000000 000000000000 | |
|
237 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |
|
238 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |
|
239 | 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed | |
|
240 | $ hg debugrevlogindex D.txt | |
|
241 | rev linkrev nodeid p1 p2 | |
|
242 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |
|
243 | 1 7 2a80419dfc31 000000000000 2a8d3833f2fb | |
|
244 | $ hg debug-repair-issue6528 | |
|
245 | no affected revisions were found | |
|
246 | $ hg st | |
|
247 | $ hg debugrevlogindex b.txt | |
|
248 | rev linkrev nodeid p1 p2 | |
|
249 | 0 2 05b806ebe5ea 000000000000 000000000000 | |
|
250 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |
|
251 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |
|
252 | 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed | |
|
253 | $ hg debugrevlogindex D.txt | |
|
254 | rev linkrev nodeid p1 p2 | |
|
255 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |
|
256 | 1 7 2a80419dfc31 000000000000 2a8d3833f2fb | |
|
257 | ||
|
258 | Try the using the report options | |
|
259 | -------------------------------- | |
|
260 | ||
|
261 | $ cd .. | |
|
262 | $ mkdir repo-to-fix-report | |
|
263 | $ cd repo-to-fix | |
|
264 | #if windows | |
|
265 | tar interprets `:` in paths (like `C:`) as being remote, force local on Windows | |
|
266 | only since some versions of tar don't have this flag. | |
|
267 | ||
|
268 | $ tar --force-local -xf $TESTDIR/bundles/issue6528.tar | |
|
269 | #else | |
|
270 | $ tar xf $TESTDIR/bundles/issue6528.tar | |
|
271 | #endif | |
|
272 | ||
|
273 | $ hg debug-repair-issue6528 --to-report $TESTTMP/report.txt | |
|
274 | found affected revision 1 for filelog 'data/D.txt.i' | |
|
275 | found affected revision 1 for filelog 'data/b.txt.i' | |
|
276 | found affected revision 3 for filelog 'data/b.txt.i' | |
|
277 | $ cat $TESTTMP/report.txt | |
|
278 | 2a80419dfc31d7dfb308ac40f3f138282de7d73b D.txt | |
|
279 | a58b36ad6b6545195952793099613c2116f3563b,ea4f2f2463cca5b29ddf3461012b8ce5c6dac175 b.txt | |
|
280 | ||
|
281 | $ hg debug-repair-issue6528 --from-report $TESTTMP/report.txt --dry-run | |
|
282 | loading report file '$TESTTMP/report.txt' | |
|
283 | found affected revision 1 for filelog 'D.txt' | |
|
284 | found affected revision 1 for filelog 'b.txt' | |
|
285 | found affected revision 3 for filelog 'b.txt' | |
|
286 | $ hg st | |
|
287 | M D.txt | |
|
288 | M b.txt | |
|
289 | $ hg debugrevlogindex b.txt | |
|
290 | rev linkrev nodeid p1 p2 | |
|
291 | 0 2 05b806ebe5ea 000000000000 000000000000 | |
|
292 | 1 3 a58b36ad6b65 05b806ebe5ea 000000000000 | |
|
293 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |
|
294 | 3 7 ea4f2f2463cc 216a5fe8b8ed 000000000000 | |
|
295 | $ hg debugrevlogindex D.txt | |
|
296 | rev linkrev nodeid p1 p2 | |
|
297 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |
|
298 | 1 7 2a80419dfc31 2a8d3833f2fb 000000000000 | |
|
299 | ||
|
300 | $ hg debug-repair-issue6528 --from-report $TESTTMP/report.txt | |
|
301 | loading report file '$TESTTMP/report.txt' | |
|
302 | found affected revision 1 for filelog 'D.txt' | |
|
303 | repaired revision 1 of 'filelog data/D.txt.i' | |
|
304 | found affected revision 1 for filelog 'b.txt' | |
|
305 | found affected revision 3 for filelog 'b.txt' | |
|
306 | repaired revision 1 of 'filelog data/b.txt.i' | |
|
307 | repaired revision 3 of 'filelog data/b.txt.i' | |
|
308 | $ hg st | |
|
309 | $ hg debugrevlogindex b.txt | |
|
310 | rev linkrev nodeid p1 p2 | |
|
311 | 0 2 05b806ebe5ea 000000000000 000000000000 | |
|
312 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |
|
313 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |
|
314 | 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed | |
|
315 | $ hg debugrevlogindex D.txt | |
|
316 | rev linkrev nodeid p1 p2 | |
|
317 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |
|
318 | 1 7 2a80419dfc31 000000000000 2a8d3833f2fb | |
|
319 | ||
|
320 | Check that the revision is not "fixed" again | |
|
321 | ||
|
322 | $ hg debug-repair-issue6528 --from-report $TESTTMP/report.txt | |
|
323 | loading report file '$TESTTMP/report.txt' | |
|
324 | revision 2a80419dfc31d7dfb308ac40f3f138282de7d73b of file 'D.txt' is not affected | |
|
325 | no affected revisions were found for 'D.txt' | |
|
326 | revision a58b36ad6b6545195952793099613c2116f3563b of file 'b.txt' is not affected | |
|
327 | revision ea4f2f2463cca5b29ddf3461012b8ce5c6dac175 of file 'b.txt' is not affected | |
|
328 | no affected revisions were found for 'b.txt' | |
|
329 | $ hg st | |
|
330 | $ hg debugrevlogindex b.txt | |
|
331 | rev linkrev nodeid p1 p2 | |
|
332 | 0 2 05b806ebe5ea 000000000000 000000000000 | |
|
333 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |
|
334 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |
|
335 | 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed | |
|
336 | $ hg debugrevlogindex D.txt | |
|
337 | rev linkrev nodeid p1 p2 | |
|
338 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |
|
339 | 1 7 2a80419dfc31 000000000000 2a8d3833f2fb | |
|
340 | ||
|
341 | Try it with a non-inline revlog | |
|
342 | ------------------------------- | |
|
343 | ||
|
344 | $ cd .. | |
|
345 | $ mkdir $TESTTMP/ext | |
|
346 | $ cat << EOF > $TESTTMP/ext/small_inline.py | |
|
347 | > from mercurial import revlog | |
|
348 | > revlog._maxinline = 8 | |
|
349 | > EOF | |
|
350 | ||
|
351 | $ cat << EOF >> $HGRCPATH | |
|
352 | > [extensions] | |
|
353 | > small_inline=$TESTTMP/ext/small_inline.py | |
|
354 | > EOF | |
|
355 | ||
|
356 | $ mkdir repo-to-fix-not-inline | |
|
357 | $ cd repo-to-fix-not-inline | |
|
358 | #if windows | |
|
359 | tar interprets `:` in paths (like `C:`) as being remote, force local on Windows | |
|
360 | only since some versions of tar don't have this flag. | |
|
361 | ||
|
362 | $ tar --force-local -xf $TESTDIR/bundles/issue6528.tar | |
|
363 | #else | |
|
364 | $ tar xf $TESTDIR/bundles/issue6528.tar | |
|
365 | #endif | |
|
366 | $ echo b >> b.txt | |
|
367 | $ hg commit -qm "inline -> separate" | |
|
368 | $ find .hg -name *b.txt.d | |
|
369 | .hg/store/data/b.txt.d | |
|
370 | ||
|
371 | Status is correct, but the problem is still there, in the earlier revision | |
|
372 | $ hg st | |
|
373 | $ hg up 3 | |
|
374 | 1 files updated, 0 files merged, 1 files removed, 0 files unresolved | |
|
375 | $ hg st | |
|
376 | M b.txt | |
|
377 | $ hg debugrevlogindex b.txt | |
|
378 | rev linkrev nodeid p1 p2 | |
|
379 | 0 2 05b806ebe5ea 000000000000 000000000000 | |
|
380 | 1 3 a58b36ad6b65 05b806ebe5ea 000000000000 | |
|
381 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |
|
382 | 3 7 ea4f2f2463cc 216a5fe8b8ed 000000000000 | |
|
383 | 4 8 db234885e2fe ea4f2f2463cc 000000000000 | |
|
384 | $ hg debugrevlogindex D.txt | |
|
385 | rev linkrev nodeid p1 p2 | |
|
386 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |
|
387 | 1 7 2a80419dfc31 2a8d3833f2fb 000000000000 | |
|
388 | 2 8 65aecc89bb5d 2a80419dfc31 000000000000 | |
|
389 | ||
|
390 | Run the fix on the non-inline revlog | |
|
391 | $ hg debug-repair-issue6528 | |
|
392 | found affected revision 1 for filelog 'data/D.txt.i' | |
|
393 | repaired revision 1 of 'filelog data/D.txt.i' | |
|
394 | found affected revision 1 for filelog 'data/b.txt.i' | |
|
395 | found affected revision 3 for filelog 'data/b.txt.i' | |
|
396 | repaired revision 1 of 'filelog data/b.txt.i' | |
|
397 | repaired revision 3 of 'filelog data/b.txt.i' | |
|
398 | ||
|
399 | Check that it worked | |
|
400 | $ hg debugrevlogindex b.txt | |
|
401 | rev linkrev nodeid p1 p2 | |
|
402 | 0 2 05b806ebe5ea 000000000000 000000000000 | |
|
403 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |
|
404 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |
|
405 | 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed | |
|
406 | 4 8 db234885e2fe ea4f2f2463cc 000000000000 | |
|
407 | $ hg debugrevlogindex D.txt | |
|
408 | rev linkrev nodeid p1 p2 | |
|
409 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |
|
410 | 1 7 2a80419dfc31 000000000000 2a8d3833f2fb | |
|
411 | 2 8 65aecc89bb5d 2a80419dfc31 000000000000 | |
|
412 | $ hg debug-repair-issue6528 | |
|
413 | no affected revisions were found | |
|
414 | $ hg st |
General Comments 0
You need to be logged in to leave comments.
Login now