mercurial/verify.py
changeset 6751 7424a75f919a
parent 6750 fb42030d79d6
child 6752 e79a8f36c2a5
equal deleted inserted replaced
6750:fb42030d79d6 6751:7424a75f919a
    22     changesets = revisions = files = 0
    22     changesets = revisions = files = 0
    23     firstbad = [None]
    23     firstbad = [None]
    24     errors = [0]
    24     errors = [0]
    25     warnings = [0]
    25     warnings = [0]
    26     neededmanifests = {}
    26     neededmanifests = {}
       
    27     ui = repo.ui
       
    28     cl = repo.changelog
       
    29     mf = repo.manifest
    27 
    30 
    28     def err(linkrev, msg, filename=None):
    31     def err(linkrev, msg, filename=None):
    29         if linkrev != None:
    32         if linkrev != None:
    30             if firstbad[0] != None:
    33             if firstbad[0] != None:
    31                 firstbad[0] = min(firstbad[0], linkrev)
    34                 firstbad[0] = min(firstbad[0], linkrev)
    34         else:
    37         else:
    35             linkrev = "?"
    38             linkrev = "?"
    36         msg = "%s: %s" % (linkrev, msg)
    39         msg = "%s: %s" % (linkrev, msg)
    37         if filename:
    40         if filename:
    38             msg = "%s@%s" % (filename, msg)
    41             msg = "%s@%s" % (filename, msg)
    39         repo.ui.warn(" " + msg + "\n")
    42         ui.warn(" " + msg + "\n")
    40         errors[0] += 1
    43         errors[0] += 1
    41 
    44 
    42     def warn(msg):
    45     def warn(msg):
    43         repo.ui.warn(msg + "\n")
    46         ui.warn(msg + "\n")
    44         warnings[0] += 1
    47         warnings[0] += 1
    45 
    48 
    46     def checksize(obj, name):
    49     def checksize(obj, name):
    47         d = obj.checksize()
    50         d = obj.checksize()
    48         if d[0]:
    51         if d[0]:
    55             if not revlogv1:
    58             if not revlogv1:
    56                 warn(_("warning: `%s' uses revlog format 1") % name)
    59                 warn(_("warning: `%s' uses revlog format 1") % name)
    57         elif revlogv1:
    60         elif revlogv1:
    58             warn(_("warning: `%s' uses revlog format 0") % name)
    61             warn(_("warning: `%s' uses revlog format 0") % name)
    59 
    62 
    60     revlogv1 = repo.changelog.version != revlog.REVLOGV0
    63     revlogv1 = cl.version != revlog.REVLOGV0
    61     if repo.ui.verbose or not revlogv1:
    64     if ui.verbose or not revlogv1:
    62         repo.ui.status(_("repository uses revlog format %d\n") %
    65         ui.status(_("repository uses revlog format %d\n") %
    63                        (revlogv1 and 1 or 0))
    66                        (revlogv1 and 1 or 0))
    64 
    67 
    65     havecl = havemf = 1
    68     havecl = havemf = 1
    66     seen = {}
    69     seen = {}
    67     repo.ui.status(_("checking changesets\n"))
    70     ui.status(_("checking changesets\n"))
    68     if not len(repo) and len(repo.manifest):
    71     if not len(cl) and len(mf):
    69         havecl = 0
    72         havecl = 0
    70         err(0, _("empty or missing 00changelog.i"))
    73         err(0, _("empty or missing 00changelog.i"))
    71     else:
    74     else:
    72         checksize(repo.changelog, "changelog")
    75         checksize(cl, "changelog")
    73 
    76 
    74     for i in repo:
    77     for i in repo:
    75         changesets += 1
    78         changesets += 1
    76         n = repo.changelog.node(i)
    79         n = cl.node(i)
    77         l = repo.changelog.linkrev(n)
    80         l = cl.linkrev(n)
    78         if l != i:
    81         if l != i:
    79             err(i, _("incorrect link (%d) for changeset") %(l))
    82             err(i, _("incorrect link (%d) for changeset") %(l))
    80         if n in seen:
    83         if n in seen:
    81             err(i, _("duplicates changeset at revision %d") % seen[n])
    84             err(i, _("duplicates changeset at revision %d") % seen[n])
    82         seen[n] = i
    85         seen[n] = i
    83 
    86 
    84         for p in repo.changelog.parents(n):
    87         for p in cl.parents(n):
    85             if p not in repo.changelog.nodemap:
    88             if p not in cl.nodemap:
    86                 err(i, _("changeset has unknown parent %s") % short(p))
    89                 err(i, _("changeset has unknown parent %s") % short(p))
    87         try:
    90         try:
    88             changes = repo.changelog.read(n)
    91             changes = cl.read(n)
    89         except KeyboardInterrupt:
    92         except KeyboardInterrupt:
    90             repo.ui.warn(_("interrupted"))
    93             ui.warn(_("interrupted"))
    91             raise
    94             raise
    92         except Exception, inst:
    95         except Exception, inst:
    93             err(i, _("unpacking changeset: %s") % inst)
    96             err(i, _("unpacking changeset: %s") % inst)
    94             continue
    97             continue
    95 
    98 
    98 
   101 
    99         for f in changes[3]:
   102         for f in changes[3]:
   100             filelinkrevs.setdefault(f, []).append(i)
   103             filelinkrevs.setdefault(f, []).append(i)
   101 
   104 
   102     seen = {}
   105     seen = {}
   103     repo.ui.status(_("checking manifests\n"))
   106     ui.status(_("checking manifests\n"))
   104     if len(repo) and not len(repo.manifest):
   107     if len(cl) and not len(mf):
   105         havemf = 0
   108         havemf = 0
   106         err(0, _("empty or missing 00manifest.i"))
   109         err(0, _("empty or missing 00manifest.i"))
   107     else:
   110     else:
   108         checkversion(repo.manifest, "manifest")
   111         checkversion(mf, "manifest")
   109         checksize(repo.manifest, "manifest")
   112         checksize(mf, "manifest")
   110 
   113 
   111     for i in repo.manifest:
   114     for i in mf:
   112         n = repo.manifest.node(i)
   115         n = mf.node(i)
   113         l = repo.manifest.linkrev(n)
   116         l = mf.linkrev(n)
   114 
   117 
   115         if l < 0 or (havecl and l >= len(repo)):
   118         if l < 0 or (havecl and l >= len(cl)):
   116             err(None, _("bad link (%d) at manifest revision %d") % (l, i))
   119             err(None, _("bad link (%d) at manifest revision %d") % (l, i))
   117 
   120 
   118         if n in neededmanifests:
   121         if n in neededmanifests:
   119             del neededmanifests[n]
   122             del neededmanifests[n]
   120 
   123 
   121         if n in seen:
   124         if n in seen:
   122             err(l, _("duplicates manifest from %d") % seen[n])
   125             err(l, _("duplicates manifest from %d") % seen[n])
   123 
   126 
   124         seen[n] = l
   127         seen[n] = l
   125 
   128 
   126         for p in repo.manifest.parents(n):
   129         for p in mf.parents(n):
   127             if p not in repo.manifest.nodemap:
   130             if p not in mf.nodemap:
   128                 err(l, _("manifest has unknown parent %s") % short(p))
   131                 err(l, _("manifest has unknown parent %s") % short(p))
   129 
   132 
   130         try:
   133         try:
   131             for f, fn in repo.manifest.readdelta(n).iteritems():
   134             for f, fn in mf.readdelta(n).iteritems():
   132                 fns = filenodes.setdefault(f, {})
   135                 fns = filenodes.setdefault(f, {})
   133                 if fn not in fns:
   136                 if fn not in fns:
   134                     fns[fn] = n
   137                     fns[fn] = n
   135         except KeyboardInterrupt:
   138         except KeyboardInterrupt:
   136             repo.ui.warn(_("interrupted"))
   139             ui.warn(_("interrupted"))
   137             raise
   140             raise
   138         except Exception, inst:
   141         except Exception, inst:
   139             err(l, _("reading manifest delta: %s") % inst)
   142             err(l, _("reading manifest delta: %s") % inst)
   140             continue
   143             continue
   141 
   144 
   142     repo.ui.status(_("crosschecking files in changesets and manifests\n"))
   145     ui.status(_("crosschecking files in changesets and manifests\n"))
   143 
   146 
   144     if havemf > 0:
   147     if havemf > 0:
   145         nm = [(c, m) for m, c in neededmanifests.items()]
   148         nm = [(c, m) for m, c in neededmanifests.items()]
   146         nm.sort()
   149         nm.sort()
   147         for c, m in nm:
   150         for c, m in nm:
   151     if havecl:
   154     if havecl:
   152         fl = filenodes.keys()
   155         fl = filenodes.keys()
   153         fl.sort()
   156         fl.sort()
   154         for f in fl:
   157         for f in fl:
   155             if f not in filelinkrevs:
   158             if f not in filelinkrevs:
   156                 lrs = [repo.manifest.linkrev(n) for n in filenodes[f]]
   159                 lrs = [mf.linkrev(n) for n in filenodes[f]]
   157                 lrs.sort()
   160                 lrs.sort()
   158                 err(lrs[0], _("in manifest but not in changeset"), f)
   161                 err(lrs[0], _("in manifest but not in changeset"), f)
   159         del fl
   162         del fl
   160 
   163 
   161     if havemf:
   164     if havemf:
   165             if f not in filenodes:
   168             if f not in filenodes:
   166                 lr = filelinkrevs[f][0]
   169                 lr = filelinkrevs[f][0]
   167                 err(lr, _("in changeset but not in manifest"), f)
   170                 err(lr, _("in changeset but not in manifest"), f)
   168         del fl
   171         del fl
   169 
   172 
   170     repo.ui.status(_("checking files\n"))
   173     ui.status(_("checking files\n"))
   171     ff = dict.fromkeys(filenodes.keys() + filelinkrevs.keys()).keys()
   174     ff = dict.fromkeys(filenodes.keys() + filelinkrevs.keys()).keys()
   172     ff.sort()
   175     ff.sort()
   173     for f in ff:
   176     for f in ff:
   174         if f == "/dev/null":
   177         if f == "/dev/null":
   175             continue
   178             continue
   217 
   220 
   218             # verify contents
   221             # verify contents
   219             try:
   222             try:
   220                 t = fl.read(n)
   223                 t = fl.read(n)
   221             except KeyboardInterrupt:
   224             except KeyboardInterrupt:
   222                 repo.ui.warn(_("interrupted"))
   225                 ui.warn(_("interrupted"))
   223                 raise
   226                 raise
   224             except Exception, inst:
   227             except Exception, inst:
   225                 err(flr, _("unpacking %s: %s") % (short(n), inst), f)
   228                 err(flr, _("unpacking %s: %s") % (short(n), inst), f)
   226 
   229 
   227             # verify parents
   230             # verify parents
   232                         (short(p1), short(n)), f)
   235                         (short(p1), short(n)), f)
   233                 if p2 not in nodes:
   236                 if p2 not in nodes:
   234                     err(flr, _("unknown parent 2 %s of %s") %
   237                     err(flr, _("unknown parent 2 %s of %s") %
   235                             (short(p2), short(p1)), f)
   238                             (short(p2), short(p1)), f)
   236             except KeyboardInterrupt:
   239             except KeyboardInterrupt:
   237                 repo.ui.warn(_("interrupted"))
   240                 ui.warn(_("interrupted"))
   238                 raise
   241                 raise
   239             except Exception, inst:
   242             except Exception, inst:
   240                 err(flr, _("checking parents of %s: %s") % (short(n), inst), f)
   243                 err(flr, _("checking parents of %s: %s") % (short(n), inst), f)
   241             nodes[n] = 1
   244             nodes[n] = 1
   242 
   245 
   252                         err(flr, _("copy source revision is nullid %s:%s")
   255                         err(flr, _("copy source revision is nullid %s:%s")
   253                             % (rp[0], short(rp[1])), f)
   256                             % (rp[0], short(rp[1])), f)
   254                     else:
   257                     else:
   255                         rev = fl2.rev(rp[1])
   258                         rev = fl2.rev(rp[1])
   256             except KeyboardInterrupt:
   259             except KeyboardInterrupt:
   257                 repo.ui.warn(_("interrupted"))
   260                 ui.warn(_("interrupted"))
   258                 raise
   261                 raise
   259             except Exception, inst:
   262             except Exception, inst:
   260                 err(flr, _("checking rename of %s: %s") %
   263                 err(flr, _("checking rename of %s: %s") %
   261                     (short(n), inst), f)
   264                     (short(n), inst), f)
   262 
   265 
   263         # cross-check
   266         # cross-check
   264         if f in filenodes:
   267         if f in filenodes:
   265             fns = [(repo.manifest.linkrev(filenodes[f][n]), n)
   268             fns = [(mf.linkrev(filenodes[f][n]), n)
   266                    for n in filenodes[f]]
   269                    for n in filenodes[f]]
   267             fns.sort()
   270             fns.sort()
   268             for lr, node in fns:
   271             for lr, node in fns:
   269                 err(lr, _("%s in manifests not found") % short(node), f)
   272                 err(lr, _("%s in manifests not found") % short(node), f)
   270 
   273 
   271     repo.ui.status(_("%d files, %d changesets, %d total revisions\n") %
   274     ui.status(_("%d files, %d changesets, %d total revisions\n") %
   272                    (files, changesets, revisions))
   275                    (files, changesets, revisions))
   273 
   276 
   274     if warnings[0]:
   277     if warnings[0]:
   275         repo.ui.warn(_("%d warnings encountered!\n") % warnings[0])
   278         ui.warn(_("%d warnings encountered!\n") % warnings[0])
   276     if errors[0]:
   279     if errors[0]:
   277         repo.ui.warn(_("%d integrity errors encountered!\n") % errors[0])
   280         ui.warn(_("%d integrity errors encountered!\n") % errors[0])
   278         if firstbad[0]:
   281         if firstbad[0]:
   279             repo.ui.warn(_("(first damaged changeset appears to be %d)\n")
   282             ui.warn(_("(first damaged changeset appears to be %d)\n")
   280                          % firstbad[0])
   283                          % firstbad[0])
   281         return 1
   284         return 1