mercurial/verify.py
author Patrick Mezard <pmezard@gmail.com>
Wed, 17 Sep 2008 22:15:36 +0200
changeset 7047 277c91fe8384
parent 7004 90227c42b5f6
child 7141 8d1bdaf842de
permissions -rw-r--r--
Update coverage.py There is no technical reason to update it except it contains all the patches already done in mercurial plus other stuff. It will be easier to update and maintain in the future.
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 _
6762
f67d1468ac50 util: add sort helper
Matt Mackall <mpm@selenic.com>
parents: 6752
diff changeset
    10
import revlog, util
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):
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    20
    mflinkrevs = {}
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
    filelinkrevs = {}
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
    filenodes = {}
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    23
    revisions = 0
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    24
    badrevs = {}
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
    errors = [0]
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
    warnings = [0]
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:
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    33
            badrevs[linkrev] = True
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    34
        else:
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    35
            linkrev = '?'
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    36
        msg = "%s: %s" % (linkrev, msg)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    37
        if filename:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    38
            msg = "%s@%s" % (filename, msg)
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    39
        ui.warn(" " + msg + "\n")
2778
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
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    42
    def exc(linkrev, msg, inst, filename=None):
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    43
        if isinstance(inst, KeyboardInterrupt):
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    44
            ui.warn(_("interrupted"))
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    45
            raise
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    46
        err(linkrev, "%s: %s" % (msg, inst), filename)
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    47
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
    def warn(msg):
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    49
        ui.warn(msg + "\n")
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
        warnings[0] += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    52
    def checklog(obj, name):
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    53
        if not len(obj) and (havecl or havemf):
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    54
            err(0, _("empty or missing %s") % name)
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    55
            return
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    56
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
        d = obj.checksize()
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
        if d[0]:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    59
            err(None, _("data length off by %d bytes") % d[0], name)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
        if d[1]:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
    61
            err(None, _("index contains %d extra bytes") % d[1], name)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
        if obj.version != revlog.REVLOGV0:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
            if not revlogv1:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
                warn(_("warning: `%s' uses revlog format 1") % name)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
        elif revlogv1:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
            warn(_("warning: `%s' uses revlog format 0") % name)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    69
    def checkentry(obj, i, node, seen, linkrevs, f):
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    70
        lr = obj.linkrev(node)
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    71
        if lr < 0 or (havecl and lr not in linkrevs):
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    72
            t = "unexpected"
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    73
            if lr < 0 or lr >= len(cl):
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    74
                t = "nonexistent"
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    75
            err(None, _("rev %d point to %s changeset %d") % (i, t, lr), f)
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    76
            if linkrevs:
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    77
                warn(_(" (expected %s)") % " ".join(map(str,linkrevs)))
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    78
            lr = None # can't be trusted
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    79
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    80
        try:
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    81
            p1, p2 = obj.parents(node)
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    82
            if p1 not in seen and p1 != nullid:
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    83
                err(lr, _("unknown parent 1 %s of %s") %
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    84
                    (short(p1), short(n)), f)
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    85
            if p2 not in seen and p2 != nullid:
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    86
                err(lr, _("unknown parent 2 %s of %s") %
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    87
                    (short(p2), short(p1)), f)
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    88
        except Exception, inst:
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    89
            exc(lr, _("checking parents of %s") % short(node), inst, f)
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    90
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    91
        if node in seen:
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    92
            err(lr, _("duplicate revision %d (%d)") % (i, seen[n]), f)
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    93
        seen[n] = i
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    94
        return lr
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
    95
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    96
    revlogv1 = cl.version != revlog.REVLOGV0
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    97
    if ui.verbose or not revlogv1:
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
    98
        ui.status(_("repository uses revlog format %d\n") %
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    99
                       (revlogv1 and 1 or 0))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   100
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   101
    havecl = len(cl) > 0
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   102
    havemf = len(mf) > 0
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   103
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   104
    ui.status(_("checking changesets\n"))
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   105
    seen = {}
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   106
    checklog(cl, "changelog")
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6534
diff changeset
   107
    for i in repo:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   108
        n = cl.node(i)
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   109
        checkentry(cl, i, n, seen, [i], "changelog")
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   110
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   111
        try:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   112
            changes = cl.read(n)
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   113
            mflinkrevs.setdefault(changes[0], []).append(i)
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   114
            for f in changes[3]:
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   115
                filelinkrevs.setdefault(f, []).append(i)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   116
        except Exception, inst:
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   117
            exc(i, _("unpacking changeset %s") % short(n), inst)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   118
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   119
    ui.status(_("checking manifests\n"))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   120
    seen = {}
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   121
    checklog(mf, "manifest")
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   122
    for i in mf:
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   123
        n = mf.node(i)
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   124
        lr = checkentry(mf, i, n, seen, mflinkrevs.get(n, []), "manifest")
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   125
        if n in mflinkrevs:
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   126
            del mflinkrevs[n]
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   127
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   128
        try:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   129
            for f, fn in mf.readdelta(n).iteritems():
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   130
                if not f:
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   131
                    err(lr, _("file without name in manifest"))
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   132
                elif f != "/dev/null":
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   133
                    fns = filenodes.setdefault(f, {})
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   134
                    if fn not in fns:
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   135
                        fns[fn] = n
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   136
        except Exception, inst:
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   137
            exc(lr, _("reading manifest delta %s") % short(n), inst)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   138
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   139
    ui.status(_("crosschecking files in changesets and manifests\n"))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   140
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   141
    if havemf:
6762
f67d1468ac50 util: add sort helper
Matt Mackall <mpm@selenic.com>
parents: 6752
diff changeset
   142
        for c, m in util.sort([(c, m) for m in mflinkrevs for c in mflinkrevs[m]]):
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   143
            err(c, _("changeset refers to unknown manifest %s") % short(m))
6762
f67d1468ac50 util: add sort helper
Matt Mackall <mpm@selenic.com>
parents: 6752
diff changeset
   144
        del mflinkrevs
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   145
6762
f67d1468ac50 util: add sort helper
Matt Mackall <mpm@selenic.com>
parents: 6752
diff changeset
   146
        for f in util.sort(filelinkrevs):
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   147
            if f not in filenodes:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   148
                lr = filelinkrevs[f][0]
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   149
                err(lr, _("in changeset but not in manifest"), f)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   150
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   151
    if havecl:
6762
f67d1468ac50 util: add sort helper
Matt Mackall <mpm@selenic.com>
parents: 6752
diff changeset
   152
        for f in util.sort(filenodes):
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   153
            if f not in filelinkrevs:
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   154
                try:
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   155
                    lr = min([repo.file(f).linkrev(n) for n in filenodes[f]])
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   156
                except:
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   157
                    lr = None
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   158
                err(lr, _("in manifest but not in changeset"), f)
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   159
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   160
    ui.status(_("checking files\n"))
6892
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6889
diff changeset
   161
6900
def492d1b592 store: change handling of decoding errors
Matt Mackall <mpm@selenic.com>
parents: 6892
diff changeset
   162
    storefiles = {}
def492d1b592 store: change handling of decoding errors
Matt Mackall <mpm@selenic.com>
parents: 6892
diff changeset
   163
    for f, f2, size in repo.store.datafiles():
def492d1b592 store: change handling of decoding errors
Matt Mackall <mpm@selenic.com>
parents: 6892
diff changeset
   164
        if not f:
def492d1b592 store: change handling of decoding errors
Matt Mackall <mpm@selenic.com>
parents: 6892
diff changeset
   165
            err(None, _("cannot decode filename '%s'") % f2)
def492d1b592 store: change handling of decoding errors
Matt Mackall <mpm@selenic.com>
parents: 6892
diff changeset
   166
        elif size > 0:
6892
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6889
diff changeset
   167
            storefiles[f] = True
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6889
diff changeset
   168
6762
f67d1468ac50 util: add sort helper
Matt Mackall <mpm@selenic.com>
parents: 6752
diff changeset
   169
    files = util.sort(util.unique(filenodes.keys() + filelinkrevs.keys()))
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   170
    for f in files:
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   171
        fl = repo.file(f)
6892
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6889
diff changeset
   172
6900
def492d1b592 store: change handling of decoding errors
Matt Mackall <mpm@selenic.com>
parents: 6892
diff changeset
   173
        for ff in fl.files():
6892
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6889
diff changeset
   174
            try:
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6889
diff changeset
   175
                del storefiles[ff]
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6889
diff changeset
   176
            except KeyError:
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6889
diff changeset
   177
                err(0, _("missing revlog!"), ff)
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6889
diff changeset
   178
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   179
        checklog(fl, f)
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
   180
        seen = {}
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6534
diff changeset
   181
        for i in fl:
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   182
            revisions += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   183
            n = fl.node(i)
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   184
            lr = checkentry(fl, i, n, seen, filelinkrevs.get(f, []), f)
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   185
            if f in filenodes:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   186
                if havemf and n not in filenodes[f]:
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   187
                    err(lr, _("%s not in manifests") % (short(n)), f)
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   188
                else:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   189
                    del filenodes[f][n]
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   190
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   191
            # verify contents
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   192
            try:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   193
                t = fl.read(n)
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   194
                rp = fl.renamed(n)
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   195
                if len(t) != fl.size(i):
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   196
                    if not fl._readmeta(n): # ancient copy?
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   197
                        err(lr, _("unpacked size is %s, %s expected") %
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   198
                            (len(t), fl.size(i)), f)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   199
            except Exception, inst:
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   200
                exc(lr, _("unpacking %s") % short(n), inst, f)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   201
3744
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   202
            # check renames
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   203
            try:
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   204
                if rp:
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   205
                    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
   206
                    if not len(fl2):
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   207
                        err(lr, _("empty or missing copy source revlog %s:%s")
6534
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
   208
                            % (rp[0], short(rp[1])), f)
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
   209
                    elif rp[1] == nullid:
7004
90227c42b5f6 c0bd7d8b69ef uses err() instead of warn() but prototype doesn't match
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6900
diff changeset
   210
                        warn(_("warning: %s@%s: copy source revision is nullid %s:%s")
90227c42b5f6 c0bd7d8b69ef uses err() instead of warn() but prototype doesn't match
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6900
diff changeset
   211
                            % (f, lr, rp[0], short(rp[1])))
6534
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
   212
                    else:
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
   213
                        rev = fl2.rev(rp[1])
3744
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   214
            except Exception, inst:
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   215
                exc(lr, _("checking rename of %s") % short(n), inst, f)
3744
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
   216
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   217
        # cross-check
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   218
        if f in filenodes:
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   219
            fns = [(mf.linkrev(l), n) for n,l in filenodes[f].items()]
6762
f67d1468ac50 util: add sort helper
Matt Mackall <mpm@selenic.com>
parents: 6752
diff changeset
   220
            for lr, node in util.sort(fns):
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
   221
                err(lr, _("%s in manifests not found") % short(node), f)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   222
6892
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6889
diff changeset
   223
    for f in storefiles:
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6889
diff changeset
   224
        warn(_("warning: orphan revlog '%s'") % f)
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6889
diff changeset
   225
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   226
    ui.status(_("%d files, %d changesets, %d total revisions\n") %
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   227
                   (len(files), len(cl), revisions))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   228
    if warnings[0]:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   229
        ui.warn(_("%d warnings encountered!\n") % warnings[0])
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   230
    if errors[0]:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   231
        ui.warn(_("%d integrity errors encountered!\n") % errors[0])
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   232
        if badrevs:
6751
7424a75f919a verify: add some local variables
Matt Mackall <mpm@selenic.com>
parents: 6750
diff changeset
   233
            ui.warn(_("(first damaged changeset appears to be %d)\n")
6752
e79a8f36c2a5 verify: lots of refactoring
Matt Mackall <mpm@selenic.com>
parents: 6751
diff changeset
   234
                    % min(badrevs))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   235
        return 1