mercurial/verify.py
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
Wed, 26 Sep 2007 01:58:45 -0300
changeset 5338 f87685355c9c
parent 5323 29be4228303b
permissions -rw-r--r--
revlog: fix revlogio.packentry corner case We want to store version information about the revlog in the first entry of its index. The code in packentry was using some heuristics to detect whether this was the first entry, but these heuristics could fail in some cases (e.g. rev 0 was empty; rev 1 descends directly from the nullid and is stored as a delta). We now give the revision number to packentry to avoid heuristics.
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