mirror of
https://github.com/facebook/sapling.git
synced 2025-01-07 14:10:42 +03:00
migrate verify
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 migrate verify Move the bulk of the verify code into the localrepository class and move the command into commands.py manifest hash: 793a8d0094d56ab0a411cd11d7fe7f39c923f209 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCog33ywK+sNU5EO8RApfBAJ4mCmiMmZE1fEfbR6sA+aP1csPvqQCfXHzY 3XK7yc19AivXf5HGKEOL3eM= =GISf -----END PGP SIGNATURE-----
This commit is contained in:
parent
58e0ba5a39
commit
cede7eda00
125
hg
125
hg
@ -17,7 +17,7 @@
|
||||
# pass
|
||||
|
||||
import sys
|
||||
from mercurial import hg, mdiff, fancyopts, ui, commands
|
||||
from mercurial import hg, fancyopts, ui, commands
|
||||
|
||||
try:
|
||||
sys.exit(commands.dispatch(sys.argv[1:]))
|
||||
@ -116,129 +116,6 @@ elif cmd == "tags":
|
||||
r = "?"
|
||||
print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
|
||||
|
||||
elif cmd == "verify":
|
||||
filelinkrevs = {}
|
||||
filenodes = {}
|
||||
manifestchangeset = {}
|
||||
changesets = revisions = files = 0
|
||||
errors = 0
|
||||
|
||||
ui.status("checking changesets\n")
|
||||
for i in range(repo.changelog.count()):
|
||||
changesets += 1
|
||||
n = repo.changelog.node(i)
|
||||
for p in repo.changelog.parents(n):
|
||||
if p not in repo.changelog.nodemap:
|
||||
ui.warn("changeset %s has unknown parent %s\n" %
|
||||
(hg.short(n), hg.short(p)))
|
||||
errors += 1
|
||||
try:
|
||||
changes = repo.changelog.read(n)
|
||||
except Exception, inst:
|
||||
ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
|
||||
errors += 1
|
||||
|
||||
manifestchangeset[changes[0]] = n
|
||||
for f in changes[3]:
|
||||
filelinkrevs.setdefault(f, []).append(i)
|
||||
|
||||
ui.status("checking manifests\n")
|
||||
for i in range(repo.manifest.count()):
|
||||
n = repo.manifest.node(i)
|
||||
for p in repo.manifest.parents(n):
|
||||
if p not in repo.manifest.nodemap:
|
||||
ui.warn("manifest %s has unknown parent %s\n" %
|
||||
(hg.short(n), hg.short(p)))
|
||||
errors += 1
|
||||
ca = repo.changelog.node(repo.manifest.linkrev(n))
|
||||
cc = manifestchangeset[n]
|
||||
if ca != cc:
|
||||
ui.warn("manifest %s points to %s, not %s\n" %
|
||||
(hg.hex(n), hg.hex(ca), hg.hex(cc)))
|
||||
errors += 1
|
||||
|
||||
try:
|
||||
delta = mdiff.patchtext(repo.manifest.delta(n))
|
||||
except KeyboardInterrupt:
|
||||
print "aborted"
|
||||
sys.exit(0)
|
||||
except Exception, inst:
|
||||
ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
|
||||
errors += 1
|
||||
|
||||
ff = [ l.split('\0') for l in delta.splitlines() ]
|
||||
for f, fn in ff:
|
||||
filenodes.setdefault(f, {})[hg.bin(fn)] = 1
|
||||
|
||||
ui.status("crosschecking files in changesets and manifests\n")
|
||||
for f in filenodes:
|
||||
if f not in filelinkrevs:
|
||||
ui.warn("file %s in manifest but not in changesets\n" % f)
|
||||
errors += 1
|
||||
|
||||
for f in filelinkrevs:
|
||||
if f not in filenodes:
|
||||
ui.warn("file %s in changeset but not in manifest\n" % f)
|
||||
errors += 1
|
||||
|
||||
ui.status("checking files\n")
|
||||
ff = filenodes.keys()
|
||||
ff.sort()
|
||||
for f in ff:
|
||||
if f == "/dev/null": continue
|
||||
files += 1
|
||||
fl = repo.file(f)
|
||||
nodes = { hg.nullid: 1 }
|
||||
for i in range(fl.count()):
|
||||
revisions += 1
|
||||
n = fl.node(i)
|
||||
|
||||
if n not in filenodes[f]:
|
||||
ui.warn("%s: %d:%s not in manifests\n" % (f, i, hg.short(n)))
|
||||
print len(filenodes[f].keys()), fl.count(), f
|
||||
errors += 1
|
||||
else:
|
||||
del filenodes[f][n]
|
||||
|
||||
flr = fl.linkrev(n)
|
||||
if flr not in filelinkrevs[f]:
|
||||
ui.warn("%s:%s points to unexpected changeset rev %d\n"
|
||||
% (f, hg.short(n), fl.linkrev(n)))
|
||||
errors += 1
|
||||
else:
|
||||
filelinkrevs[f].remove(flr)
|
||||
|
||||
# verify contents
|
||||
try:
|
||||
t = fl.read(n)
|
||||
except Exception, inst:
|
||||
ui.warn("unpacking file %s %s: %s\n" % (f, hg.short(n), inst))
|
||||
errors += 1
|
||||
|
||||
# verify parents
|
||||
(p1, p2) = fl.parents(n)
|
||||
if p1 not in nodes:
|
||||
ui.warn("file %s:%s unknown parent 1 %s" %
|
||||
(f, hg.short(n), hg.short(p1)))
|
||||
errors += 1
|
||||
if p2 not in nodes:
|
||||
ui.warn("file %s:%s unknown parent 2 %s" %
|
||||
(f, hg.short(n), hg.short(p1)))
|
||||
errors += 1
|
||||
nodes[n] = 1
|
||||
|
||||
# cross-check
|
||||
for node in filenodes[f]:
|
||||
ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
|
||||
errors += 1
|
||||
|
||||
ui.status("%d files, %d changesets, %d total revisions\n" %
|
||||
(files, changesets, revisions))
|
||||
|
||||
if errors:
|
||||
ui.warn("%d integrity errors encountered!\n" % errors)
|
||||
sys.exit(1)
|
||||
|
||||
else:
|
||||
if cmd: ui.warn("unknown command\n\n")
|
||||
sys.exit(1)
|
||||
|
@ -389,6 +389,10 @@ def tip(ui, repo):
|
||||
def undo(ui, repo):
|
||||
repo.undo()
|
||||
|
||||
def verify(ui, repo):
|
||||
"""verify the integrity of the repository"""
|
||||
return repo.verify()
|
||||
|
||||
table = {
|
||||
"add": (add, [], "hg add [files]"),
|
||||
"addremove": (addremove, [], "hg addremove"),
|
||||
@ -436,6 +440,7 @@ table = {
|
||||
"status": (status, [], 'hg status'),
|
||||
"tip": (tip, [], 'hg tip'),
|
||||
"undo": (undo, [], 'hg undo'),
|
||||
"verify": (verify, [], 'hg verify'),
|
||||
}
|
||||
|
||||
norepo = "init branch help"
|
||||
|
127
mercurial/hg.py
127
mercurial/hg.py
@ -993,6 +993,133 @@ class localrepository:
|
||||
os.unlink(b)
|
||||
os.unlink(c)
|
||||
|
||||
def verify(self):
|
||||
filelinkrevs = {}
|
||||
filenodes = {}
|
||||
manifestchangeset = {}
|
||||
changesets = revisions = files = 0
|
||||
errors = 0
|
||||
|
||||
self.ui.status("checking changesets\n")
|
||||
for i in range(self.changelog.count()):
|
||||
changesets += 1
|
||||
n = self.changelog.node(i)
|
||||
for p in self.changelog.parents(n):
|
||||
if p not in self.changelog.nodemap:
|
||||
self.ui.warn("changeset %s has unknown parent %s\n" %
|
||||
(short(n), short(p)))
|
||||
errors += 1
|
||||
try:
|
||||
changes = self.changelog.read(n)
|
||||
except Exception, inst:
|
||||
self.ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
|
||||
errors += 1
|
||||
|
||||
manifestchangeset[changes[0]] = n
|
||||
for f in changes[3]:
|
||||
filelinkrevs.setdefault(f, []).append(i)
|
||||
|
||||
self.ui.status("checking manifests\n")
|
||||
for i in range(self.manifest.count()):
|
||||
n = self.manifest.node(i)
|
||||
for p in self.manifest.parents(n):
|
||||
if p not in self.manifest.nodemap:
|
||||
self.ui.warn("manifest %s has unknown parent %s\n" %
|
||||
(short(n), short(p)))
|
||||
errors += 1
|
||||
ca = self.changelog.node(self.manifest.linkrev(n))
|
||||
cc = manifestchangeset[n]
|
||||
if ca != cc:
|
||||
self.ui.warn("manifest %s points to %s, not %s\n" %
|
||||
(hex(n), hex(ca), hex(cc)))
|
||||
errors += 1
|
||||
|
||||
try:
|
||||
delta = mdiff.patchtext(self.manifest.delta(n))
|
||||
except KeyboardInterrupt:
|
||||
print "aborted"
|
||||
sys.exit(0)
|
||||
except Exception, inst:
|
||||
self.ui.warn("unpacking manifest %s: %s\n"
|
||||
% (short(n), inst))
|
||||
errors += 1
|
||||
|
||||
ff = [ l.split('\0') for l in delta.splitlines() ]
|
||||
for f, fn in ff:
|
||||
filenodes.setdefault(f, {})[bin(fn)] = 1
|
||||
|
||||
self.ui.status("crosschecking files in changesets and manifests\n")
|
||||
for f in filenodes:
|
||||
if f not in filelinkrevs:
|
||||
self.ui.warn("file %s in manifest but not in changesets\n" % f)
|
||||
errors += 1
|
||||
|
||||
for f in filelinkrevs:
|
||||
if f not in filenodes:
|
||||
self.ui.warn("file %s in changeset but not in manifest\n" % f)
|
||||
errors += 1
|
||||
|
||||
self.ui.status("checking files\n")
|
||||
ff = filenodes.keys()
|
||||
ff.sort()
|
||||
for f in ff:
|
||||
if f == "/dev/null": continue
|
||||
files += 1
|
||||
fl = self.file(f)
|
||||
nodes = { nullid: 1 }
|
||||
for i in range(fl.count()):
|
||||
revisions += 1
|
||||
n = fl.node(i)
|
||||
|
||||
if n not in filenodes[f]:
|
||||
self.ui.warn("%s: %d:%s not in manifests\n"
|
||||
% (f, i, short(n)))
|
||||
print len(filenodes[f].keys()), fl.count(), f
|
||||
errors += 1
|
||||
else:
|
||||
del filenodes[f][n]
|
||||
|
||||
flr = fl.linkrev(n)
|
||||
if flr not in filelinkrevs[f]:
|
||||
self.ui.warn("%s:%s points to unexpected changeset %d\n"
|
||||
% (f, short(n), fl.linkrev(n)))
|
||||
errors += 1
|
||||
else:
|
||||
filelinkrevs[f].remove(flr)
|
||||
|
||||
# verify contents
|
||||
try:
|
||||
t = fl.read(n)
|
||||
except Exception, inst:
|
||||
self.ui.warn("unpacking file %s %s: %s\n"
|
||||
% (f, short(n), inst))
|
||||
errors += 1
|
||||
|
||||
# verify parents
|
||||
(p1, p2) = fl.parents(n)
|
||||
if p1 not in nodes:
|
||||
self.ui.warn("file %s:%s unknown parent 1 %s" %
|
||||
(f, short(n), short(p1)))
|
||||
errors += 1
|
||||
if p2 not in nodes:
|
||||
self.ui.warn("file %s:%s unknown parent 2 %s" %
|
||||
(f, short(n), short(p1)))
|
||||
errors += 1
|
||||
nodes[n] = 1
|
||||
|
||||
# cross-check
|
||||
for node in filenodes[f]:
|
||||
self.ui.warn("node %s in manifests not in %s\n"
|
||||
% (hex(n), f))
|
||||
errors += 1
|
||||
|
||||
self.ui.status("%d files, %d changesets, %d total revisions\n" %
|
||||
(files, changesets, revisions))
|
||||
|
||||
if errors:
|
||||
self.ui.warn("%d integrity errors encountered!\n" % errors)
|
||||
return 1
|
||||
|
||||
class remoterepository:
|
||||
def __init__(self, ui, path):
|
||||
self.url = path
|
||||
|
Loading…
Reference in New Issue
Block a user