mercurial/verify.py
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Thu, 11 Oct 2007 16:28:30 +0200
changeset 5456 a58d415b272e
parent 5323 29be4228303b
permissions -rw-r--r--
fix typo
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# verify.py - repository integrity checking for Mercurial
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4395
diff changeset
     3
# Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
from node import *
3893
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3745
diff changeset
     9
from i18n import _
5182
012dbf88b9b2 remove unneeded imports of mdiff
Matt Mackall <mpm@selenic.com>
parents: 4959
diff changeset
    10
import revlog
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    11
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    12
def verify(repo):
4959
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    13
    lock = repo.lock()
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    14
    try:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    15
        return _verify(repo)
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    16
    finally:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    17
        del lock
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    18
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    19
def _verify(repo):
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
    filelinkrevs = {}
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
    filenodes = {}
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
    changesets = revisions = files = 0
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    23
    firstbad = [None]
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
    errors = [0]
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
    warnings = [0]
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
    neededmanifests = {}
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    27
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    28
    def err(linkrev, msg, filename=None):
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    29
        if linkrev != None:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    30
            if firstbad[0] != None:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    31
                firstbad[0] = min(firstbad[0], linkrev)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    32
            else:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    33
                firstbad[0] = linkrev
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    34
        else:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    35
            linkrev = "?"
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    36
        msg = "%s: %s" % (linkrev, msg)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    37
        if filename:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    38
            msg = "%s@%s" % (filename, msg)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    39
        repo.ui.warn(" " + msg + "\n")
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    40
        errors[0] += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    41
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
    def warn(msg):
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
        repo.ui.warn(msg + "\n")
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    44
        warnings[0] += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
    def checksize(obj, name):
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
        d = obj.checksize()
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
        if d[0]:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    49
            err(None, _("data length off by %d bytes") % d[0], name)
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
        if d[1]:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    51
            err(None, _("index contains %d extra bytes") % d[1], name)
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
    def checkversion(obj, name):
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    54
        if obj.version != revlog.REVLOGV0:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
            if not revlogv1:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
                warn(_("warning: `%s' uses revlog format 1") % name)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
        elif revlogv1:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
            warn(_("warning: `%s' uses revlog format 0") % name)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
4267
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 3893
diff changeset
    60
    revlogv1 = repo.changelog.version != revlog.REVLOGV0
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 3893
diff changeset
    61
    if repo.ui.verbose or not revlogv1:
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
        repo.ui.status(_("repository uses revlog format %d\n") %
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
                       (revlogv1 and 1 or 0))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
    seen = {}
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
    repo.ui.status(_("checking changesets\n"))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
    checksize(repo.changelog, "changelog")
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
3468
0e68608bd11d use xrange instead of range
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3189
diff changeset
    69
    for i in xrange(repo.changelog.count()):
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
        changesets += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    71
        n = repo.changelog.node(i)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    72
        l = repo.changelog.linkrev(n)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
        if l != i:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    74
            err(i, _("incorrect link (%d) for changeset") %(l))
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
        if n in seen:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    76
            err(i, _("duplicates changeset at revision %d") % seen[n])
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    77
        seen[n] = i
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    79
        for p in repo.changelog.parents(n):
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
            if p not in repo.changelog.nodemap:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    81
                err(i, _("changeset has unknown parent %s") % short(p))
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    82
        try:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
            changes = repo.changelog.read(n)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    84
        except KeyboardInterrupt:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
            repo.ui.warn(_("interrupted"))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    86
            raise
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    87
        except Exception, inst:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    88
            err(i, _("unpacking changeset: %s") % inst)
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    89
            continue
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    90
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    91
        if changes[0] not in neededmanifests:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
    92
            neededmanifests[changes[0]] = i
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    93
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    94
        for f in changes[3]:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    95
            filelinkrevs.setdefault(f, []).append(i)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    96
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    97
    seen = {}
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    98
    repo.ui.status(_("checking manifests\n"))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    99
    checkversion(repo.manifest, "manifest")
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   100
    checksize(repo.manifest, "manifest")
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   101
3468
0e68608bd11d use xrange instead of range
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3189
diff changeset
   102
    for i in xrange(repo.manifest.count()):
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   103
        n = repo.manifest.node(i)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   104
        l = repo.manifest.linkrev(n)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   105
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   106
        if l < 0 or l >= repo.changelog.count():
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   107
            err(None, _("bad link (%d) at manifest revision %d") % (l, i))
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   108
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   109
        if n in neededmanifests:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   110
            del neededmanifests[n]
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   111
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   112
        if n in seen:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   113
            err(l, _("duplicates manifest from %d") % seen[n])
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   114
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   115
        seen[n] = l
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   116
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   117
        for p in repo.manifest.parents(n):
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   118
            if p not in repo.manifest.nodemap:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   119
                err(l, _("manifest has unknown parent %s") % short(p))
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   120
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   121
        try:
3189
f3b939444c72 Abstract manifest block parsing.
Brendan Cully <brendan@kublai.com>
parents: 2802
diff changeset
   122
            for f, fn in repo.manifest.readdelta(n).iteritems():
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   123
                fns = filenodes.setdefault(f, {})
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   124
                if fn not in fns:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   125
                    fns[fn] = n
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   126
        except KeyboardInterrupt:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   127
            repo.ui.warn(_("interrupted"))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   128
            raise
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   129
        except Exception, inst:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   130
            err(l, _("reading manifest delta: %s") % inst)
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   131
            continue
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   132
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   133
    repo.ui.status(_("crosschecking files in changesets and manifests\n"))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   134
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   135
    nm = neededmanifests.items()
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   136
    nm.sort()
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   137
    for m, c in nm:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   138
        err(m, _("changeset refers to unknown manifest %s") % short(c))
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   139
    del neededmanifests, nm
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   140
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   141
    for f in filenodes:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   142
        if f not in filelinkrevs:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   143
            lrs = [repo.manifest.linkrev(n) for n in filenodes[f]]
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   144
            lrs.sort()
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   145
            err(lrs[0], _("in manifest but not in changeset"), f)
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   146
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   147
    for f in filelinkrevs:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   148
        if f not in filenodes:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   149
            lr = filelinkrevs[f][0]
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   150
            err(lr, _("in changeset but not in manifest"), f)
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   151
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   152
    repo.ui.status(_("checking files\n"))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   153
    ff = filenodes.keys()
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   154
    ff.sort()
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   155
    for f in ff:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   156
        if f == "/dev/null":
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   157
            continue
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   158
        files += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   159
        if not f:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   160
            lr = repo.manifest.linkrev(filenodes[f][0])
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   161
            err(lr, _("file without name in manifest %s") % short(ff[n]))
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   162
            continue
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   163
        fl = repo.file(f)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   164
        checkversion(fl, f)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   165
        checksize(fl, f)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   166
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   167
        seen = {}
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   168
        nodes = {nullid: 1}
3468
0e68608bd11d use xrange instead of range
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3189
diff changeset
   169
        for i in xrange(fl.count()):
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   170
            revisions += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   171
            n = fl.node(i)
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   172
            flr = fl.linkrev(n)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   173
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   174
            if flr not in filelinkrevs.get(f, []):
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   175
                if flr < 0 or flr >= repo.changelog.count():
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   176
                    err(None, _("rev %d point to nonexistent changeset %d")
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   177
                        % (i, flr), f)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   178
                else:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   179
                    err(None, _("rev %d points to unexpected changeset %d")
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   180
                        % (i, flr), f)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   181
                if f in filelinkrevs:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   182
                    warn(_(" (expected %s)") % filelinkrevs[f][0])
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   183
                flr = None # can't be trusted
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   184
            else:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   185
                filelinkrevs[f].remove(flr)
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   186
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   187
            if n in seen:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   188
                err(flr, _("duplicate revision %d") % i, f)
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   189
            if n not in filenodes[f]:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   190
                err(flr, _("%s not in manifests") % (short(n)), f)
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   191
            else:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   192
                del filenodes[f][n]
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   193
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   194
            # verify contents
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   195
            try:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   196
                t = fl.read(n)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   197
            except KeyboardInterrupt:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   198
                repo.ui.warn(_("interrupted"))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   199
                raise
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   200
            except Exception, inst:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   201
                err(flr, _("unpacking %s: %s") % (short(n), inst), f)
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   202
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   203
            # verify parents
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   204
            try:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   205
                (p1, p2) = fl.parents(n)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   206
                if p1 not in nodes:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   207
                    err(flr, _("unknown parent 1 %s of %s") %
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   208
                        (short(p1), short(n)), f)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   209
                if p2 not in nodes:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   210
                    err(flr, _("unknown parent 2 %s of %s") %
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   211
                            (short(p2), short(p1)), f)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   212
            except KeyboardInterrupt:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   213
                repo.ui.warn(_("interrupted"))
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   214
                raise
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   215
            except Exception, inst:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   216
                err(flr, _("checking parents of %s: %s") % (short(n), inst), f)
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   217
            nodes[n] = 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   218
3745
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3468
diff changeset
   219
            # check renames
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3468
diff changeset
   220
            try:
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3468
diff changeset
   221
                rp = fl.renamed(n)
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3468
diff changeset
   222
                if rp:
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3468
diff changeset
   223
                    fl2 = repo.file(rp[0])
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3468
diff changeset
   224
                    rev = fl2.rev(rp[1])
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3468
diff changeset
   225
            except KeyboardInterrupt:
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3468
diff changeset
   226
                repo.ui.warn(_("interrupted"))
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3468
diff changeset
   227
                raise
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3468
diff changeset
   228
            except Exception, inst:
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   229
                err(flr, _("checking rename of %s: %s") %
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   230
                    (short(n), inst), f)
3745
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3468
diff changeset
   231
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   232
        # cross-check
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   233
        fns = [(repo.manifest.linkrev(filenodes[f][n]), n)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   234
               for n in filenodes[f]]
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   235
        fns.sort()
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   236
        for lr, node in fns:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   237
            err(lr, _("%s in manifests not found") % short(node), f)
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   238
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   239
    repo.ui.status(_("%d files, %d changesets, %d total revisions\n") %
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   240
                   (files, changesets, revisions))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   241
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   242
    if warnings[0]:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   243
        repo.ui.warn(_("%d warnings encountered!\n") % warnings[0])
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   244
    if errors[0]:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   245
        repo.ui.warn(_("%d integrity errors encountered!\n") % errors[0])
5323
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   246
        if firstbad[0]:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   247
            repo.ui.warn(_("(first damaged changeset appears to be %d)\n")
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5186
diff changeset
   248
                         % firstbad[0])
2802
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   249
        return 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   250