mercurial/verify.py
author Matt Mackall <mpm@selenic.com>
Thu, 26 Jun 2008 14:35:50 -0500
changeset 6751 7424a75f919a
parent 6750 fb42030d79d6
child 6752 e79a8f36c2a5
permissions -rw-r--r--
verify: add some local variables
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2778
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>
2778
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
6211
f89fd07fc51d Expand import * to allow Pyflakes to find problems
Joel Rosdahl <joel@rosdahl.net>
parents: 5541
diff changeset
     8
from node import nullid, short
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3744
diff changeset
     9
from i18n import _
5175
012dbf88b9b2 remove unneeded imports of mdiff
Matt Mackall <mpm@selenic.com>
parents: 4915
diff changeset
    10
import revlog
2778
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):
4915
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):
2778
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
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    23
    firstbad = [None]
2778
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 = {}
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    27
    ui = repo.ui
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    28
    cl = repo.changelog
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    29
    mf = repo.manifest
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    31
    def err(linkrev, msg, filename=None):
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    32
        if linkrev != None:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    33
            if firstbad[0] != None:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    34
                firstbad[0] = min(firstbad[0], linkrev)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    35
            else:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    36
                firstbad[0] = linkrev
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    37
        else:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    38
            linkrev = "?"
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    39
        msg = "%s: %s" % (linkrev, msg)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    40
        if filename:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    41
            msg = "%s@%s" % (filename, msg)
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    42
        ui.warn(" " + msg + "\n")
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
        errors[0] += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    44
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
    def warn(msg):
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    46
        ui.warn(msg + "\n")
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
        warnings[0] += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
    def checksize(obj, name):
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
        d = obj.checksize()
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
        if d[0]:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    52
            err(None, _("data length off by %d bytes") % d[0], name)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
        if d[1]:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    54
            err(None, _("index contains %d extra bytes") % d[1], name)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
    def checkversion(obj, name):
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
        if obj.version != revlog.REVLOGV0:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
            if not revlogv1:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
                warn(_("warning: `%s' uses revlog format 1") % name)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
        elif revlogv1:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    61
            warn(_("warning: `%s' uses revlog format 0") % name)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    63
    revlogv1 = cl.version != revlog.REVLOGV0
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    64
    if ui.verbose or not revlogv1:
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    65
        ui.status(_("repository uses revlog format %d\n") %
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
                       (revlogv1 and 1 or 0))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
    68
    havecl = havemf = 1
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
    seen = {}
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    70
    ui.status(_("checking changesets\n"))
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    71
    if not len(cl) and len(mf):
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
    72
        havecl = 0
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
    73
        err(0, _("empty or missing 00changelog.i"))
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
    74
    else:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    75
        checksize(cl, "changelog")
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6534
diff changeset
    77
    for i in repo:
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
        changesets += 1
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    79
        n = cl.node(i)
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    80
        l = cl.linkrev(n)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    81
        if l != i:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    82
            err(i, _("incorrect link (%d) for changeset") %(l))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
        if n in seen:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    84
            err(i, _("duplicates changeset at revision %d") % seen[n])
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    85
        seen[n] = i
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    86
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    87
        for p in cl.parents(n):
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    88
            if p not in cl.nodemap:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    89
                err(i, _("changeset has unknown parent %s") % short(p))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    90
        try:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    91
            changes = cl.read(n)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    92
        except KeyboardInterrupt:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    93
            ui.warn(_("interrupted"))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    94
            raise
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    95
        except Exception, inst:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    96
            err(i, _("unpacking changeset: %s") % inst)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    97
            continue
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    98
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    99
        if changes[0] not in neededmanifests:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   100
            neededmanifests[changes[0]] = i
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   101
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   102
        for f in changes[3]:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   103
            filelinkrevs.setdefault(f, []).append(i)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   104
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   105
    seen = {}
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   106
    ui.status(_("checking manifests\n"))
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   107
    if len(cl) and not len(mf):
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   108
        havemf = 0
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   109
        err(0, _("empty or missing 00manifest.i"))
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   110
    else:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   111
        checkversion(mf, "manifest")
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   112
        checksize(mf, "manifest")
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   113
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   114
    for i in mf:
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   115
        n = mf.node(i)
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   116
        l = mf.linkrev(n)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   117
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   118
        if l < 0 or (havecl and l >= len(cl)):
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   119
            err(None, _("bad link (%d) at manifest revision %d") % (l, i))
2778
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
        if n in neededmanifests:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   122
            del neededmanifests[n]
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   123
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   124
        if n in seen:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   125
            err(l, _("duplicates manifest from %d") % seen[n])
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   126
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   127
        seen[n] = l
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   128
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   129
        for p in mf.parents(n):
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   130
            if p not in mf.nodemap:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   131
                err(l, _("manifest has unknown parent %s") % short(p))
2778
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
        try:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   134
            for f, fn in mf.readdelta(n).iteritems():
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   135
                fns = filenodes.setdefault(f, {})
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   136
                if fn not in fns:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   137
                    fns[fn] = n
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   138
        except KeyboardInterrupt:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   139
            ui.warn(_("interrupted"))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   140
            raise
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   141
        except Exception, inst:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   142
            err(l, _("reading manifest delta: %s") % inst)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   143
            continue
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   144
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   145
    ui.status(_("crosschecking files in changesets and manifests\n"))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   146
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   147
    if havemf > 0:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   148
        nm = [(c, m) for m, c in neededmanifests.items()]
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   149
        nm.sort()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   150
        for c, m in nm:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   151
            err(c, _("changeset refers to unknown manifest %s") % short(m))
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   152
        del neededmanifests, nm
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   153
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   154
    if havecl:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   155
        fl = filenodes.keys()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   156
        fl.sort()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   157
        for f in fl:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   158
            if f not in filelinkrevs:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   159
                lrs = [mf.linkrev(n) for n in filenodes[f]]
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   160
                lrs.sort()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   161
                err(lrs[0], _("in manifest but not in changeset"), f)
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   162
        del fl
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   163
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   164
    if havemf:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   165
        fl = filelinkrevs.keys()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   166
        fl.sort()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   167
        for f in fl:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   168
            if f not in filenodes:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   169
                lr = filelinkrevs[f][0]
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   170
                err(lr, _("in changeset but not in manifest"), f)
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   171
        del fl
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   172
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   173
    ui.status(_("checking files\n"))
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   174
    ff = dict.fromkeys(filenodes.keys() + filelinkrevs.keys()).keys()
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   175
    ff.sort()
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   176
    for f in ff:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   177
        if f == "/dev/null":
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   178
            continue
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   179
        files += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   180
        if not f:
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   181
            lr = filelinkrevs[f][0]
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   182
            err(lr, _("file without name in manifest"))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   183
            continue
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   184
        fl = repo.file(f)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   185
        checkversion(fl, f)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   186
        checksize(fl, f)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   187
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6534
diff changeset
   188
        if not len(fl):
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   189
            err(filelinkrevs[f][0], _("empty or missing revlog"), f)
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   190
            continue
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   191
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   192
        seen = {}
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   193
        nodes = {nullid: 1}
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6534
diff changeset
   194
        for i in fl:
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   195
            revisions += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   196
            n = fl.node(i)
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   197
            flr = fl.linkrev(n)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   198
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   199
            if flr < 0 or (havecl and flr not in filelinkrevs.get(f, [])):
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6534
diff changeset
   200
                if flr < 0 or flr >= len(repo):
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   201
                    err(None, _("rev %d point to nonexistent changeset %d")
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   202
                        % (i, flr), f)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   203
                else:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   204
                    err(None, _("rev %d points to unexpected changeset %d")
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   205
                        % (i, flr), f)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   206
                if f in filelinkrevs:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   207
                    warn(_(" (expected %s)") % filelinkrevs[f][0])
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   208
                flr = None # can't be trusted
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   209
            else:
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   210
                if havecl:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   211
                    filelinkrevs[f].remove(flr)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   212
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   213
            if n in seen:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   214
                err(flr, _("duplicate revision %d") % i, f)
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   215
            if f in filenodes:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   216
                if havemf and n not in filenodes[f]:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   217
                    err(flr, _("%s not in manifests") % (short(n)), f)
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   218
                else:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   219
                    del filenodes[f][n]
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   220
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   221
            # verify contents
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   222
            try:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   223
                t = fl.read(n)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   224
            except KeyboardInterrupt:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   225
                ui.warn(_("interrupted"))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   226
                raise
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   227
            except Exception, inst:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   228
                err(flr, _("unpacking %s: %s") % (short(n), inst), f)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   229
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   230
            # verify parents
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   231
            try:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   232
                (p1, p2) = fl.parents(n)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   233
                if p1 not in nodes:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   234
                    err(flr, _("unknown parent 1 %s of %s") %
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   235
                        (short(p1), short(n)), f)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   236
                if p2 not in nodes:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   237
                    err(flr, _("unknown parent 2 %s of %s") %
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   238
                            (short(p2), short(p1)), f)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   239
            except KeyboardInterrupt:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   240
                ui.warn(_("interrupted"))
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   241
                raise
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   242
            except Exception, inst:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   243
                err(flr, _("checking parents of %s: %s") % (short(n), inst), f)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   244
            nodes[n] = 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   245
3744
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   246
            # check renames
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   247
            try:
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   248
                rp = fl.renamed(n)
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   249
                if rp:
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   250
                    fl2 = repo.file(rp[0])
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6534
diff changeset
   251
                    if not len(fl2):
6534
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
   252
                        err(flr, _("empty or missing copy source revlog %s:%s")
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
   253
                            % (rp[0], short(rp[1])), f)
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
   254
                    elif rp[1] == nullid:
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
   255
                        err(flr, _("copy source revision is nullid %s:%s")
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
   256
                            % (rp[0], short(rp[1])), f)
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
   257
                    else:
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
   258
                        rev = fl2.rev(rp[1])
3744
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   259
            except KeyboardInterrupt:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   260
                ui.warn(_("interrupted"))
3744
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   261
                raise
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   262
            except Exception, inst:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   263
                err(flr, _("checking rename of %s: %s") %
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   264
                    (short(n), inst), f)
3744
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   265
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   266
        # cross-check
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   267
        if f in filenodes:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   268
            fns = [(mf.linkrev(filenodes[f][n]), n)
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   269
                   for n in filenodes[f]]
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   270
            fns.sort()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   271
            for lr, node in fns:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   272
                err(lr, _("%s in manifests not found") % short(node), f)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   273
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   274
    ui.status(_("%d files, %d changesets, %d total revisions\n") %
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   275
                   (files, changesets, revisions))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   276
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   277
    if warnings[0]:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   278
        ui.warn(_("%d warnings encountered!\n") % warnings[0])
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   279
    if errors[0]:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   280
        ui.warn(_("%d integrity errors encountered!\n") % errors[0])
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   281
        if firstbad[0]:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   282
            ui.warn(_("(first damaged changeset appears to be %d)\n")
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   283
                         % firstbad[0])
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   284
        return 1