sapling/tests/test-fixcorrupt.t
Adam Simpkins 642dea7e2c fixcorrupt: automatically look back as far as necessary
Summary:
Update the fixcorrupt extension to look back as far as necessary in the revlog
to find a good entry.  Previously the user had to supply a good value using the
--checklen argument.  If --checklen was too small, fixcorrupt could end up
trying to truncate in the middle of a corrupted section of the revlog, which
would cause problems as it was still using corrupted data.

This change ensures that fixcorrupt always looks back far enough to find a good
entry.  We start by looking at the last 10 entries, and double that amount each
time the first item in the list is still bad.

Test Plan:
Used it to fix a corrupted fbsource repository where the corruption was 36
commits back.

Reviewers: #mercurial, quark, stash

Reviewed By: stash

Subscribers: stash, net-systems-diffs@fb.com, yogeshwer, mjpieters

Differential Revision: https://phabricator.intern.facebook.com/D4874243

Signature: t1:4874243:1492007518:7406b03a9967815a496a8c2fae394c5f21f7e60a
2017-04-12 14:09:22 -07:00

122 lines
3.4 KiB
Perl

$ SKIPREMOTEFILELOGCHECK=1
$ export SKIPREMOTEFILELOGCHECK
$ cat > noinline.py << EOF
> from mercurial import revlog
> revlog.REVLOG_DEFAULT_FLAGS = 0
> revlog.REVLOG_DEFAULT_VERSION = revlog.REVLOG_DEFAULT_FORMAT
> EOF
$ cat >> $HGRCPATH << EOF
> [extensions]
> noinline=$TESTTMP/noinline.py
> fixcorrupt=$TESTDIR/../hgext3rd/fixcorrupt.py
> EOF
$ rebuildrepo() {
> cd $TESTTMP
> [ -d repo ] && rm -rf repo
> hg init repo
> cd repo
> for i in 1 2 3 4 5; do
> echo $i > $i
> hg commit -m $i -A $i
> done
> }
$ cat > rewrite.py <<EOF
> # change (sys.argv[2]) bytes at the end of (sys.argv[1]) file to zeros
> import sys
> path = sys.argv[1]
> n = int(sys.argv[2])
> with open(path, 'rb+') as f:
> f.seek(0, 2)
> filesize = f.tell()
> n = min(n, filesize)
> f.seek(filesize - n)
> f.write(b'\0' * n)
> EOF
$ corrupt() {
> $PYTHON $TESTTMP/rewrite.py .hg/store/"$1" "$2"
> }
Nothing wrong
$ rebuildrepo
$ hg debugfixcorrupt
changelog looks okay
manifest looks okay
nothing to do
[1]
Changelog corruption
$ corrupt 00changelog.d 150
$ hg verify -q 2>&1 | grep error
15 integrity errors encountered!
$ hg debugfixcorrupt --no-dryrun
changelog: corrupted at rev 2 (linkrev=2)
manifest: marked corrupted at rev 2 (linkrev=2)
changelog: will lose 2 revisions
truncating 00changelog.d from 275 to 110 bytes
truncating 00changelog.i from 320 to 128 bytes
manifest: will lose 2 revisions
truncating 00manifest.d from 264 to 99 bytes
truncating 00manifest.i from 320 to 128 bytes
fix completed. re-run to check more revisions.
$ hg verify -q 2>&1 | grep error
[1]
Manifest corruption
$ rebuildrepo
$ corrupt 00manifest.d 150
$ cp -R .hg/store .hg/store.bak
$ hg debugfixcorrupt --no-dryrun
changelog looks okay
manifest: corrupted at rev 2 (linkrev=2)
changelog: will lose 2 revisions
truncating 00changelog.d from 275 to 110 bytes
truncating 00changelog.i from 320 to 128 bytes
manifest: will lose 2 revisions
truncating 00manifest.d from 264 to 99 bytes
truncating 00manifest.i from 320 to 128 bytes
fix completed. re-run to check more revisions.
$ hg verify -q 2>&1 | grep error
[1]
Verify backups
$ cat > sha256.py << EOF
> import hashlib, sys
> s = hashlib.sha256()
> s.update(sys.stdin.read())
> sys.stdout.write('%s' % s.hexdigest()[:8])
> EOF
$ ls .hg/truncate-backups | sort
*-00changelog.d.backup-byte-110-to-275 (glob)
*-00changelog.i.backup-byte-128-to-320 (glob)
*-00manifest.d.backup-byte-99-to-264 (glob)
*-00manifest.i.backup-byte-128-to-320 (glob)
$ wc -c .hg/store/00changelog* .hg/store/00manifest* | sort
*99 .hg/store/00manifest.d (glob)
*110 .hg/store/00changelog.d (glob)
*128 .hg/store/00changelog.i (glob)
*128 .hg/store/00manifest.i (glob)
*465 total (glob)
$ for i in 00changelog.i 00changelog.d 00manifest.i 00manifest.d; do
> printf '%s: before fix: ' $i
> cat .hg/store.bak/$i | $PYTHON sha256.py
> printf ', restored from backup: '
> cat .hg/store/$i .hg/truncate-backups/*-$i.backup* | $PYTHON sha256.py
> printf '\n'
> done
00changelog.i: before fix: cd8b27c9, restored from backup: cd8b27c9
00changelog.d: before fix: 873f2076, restored from backup: 873f2076
00manifest.i: before fix: 1fbd16af, restored from backup: 1fbd16af
00manifest.d: before fix: 46207222, restored from backup: 46207222