hg
changeset 247 863b508c5b36
parent 246 96cde50a746f
child 248 b7645b3c86ff
equal deleted inserted replaced
246:96cde50a746f 247:863b508c5b36
    15 #    psyco.full()
    15 #    psyco.full()
    16 # except:
    16 # except:
    17 #    pass
    17 #    pass
    18 
    18 
    19 import sys
    19 import sys
    20 from mercurial import hg, mdiff, fancyopts, ui, commands
    20 from mercurial import hg, fancyopts, ui, commands
    21 
    21 
    22 try:
    22 try:
    23     sys.exit(commands.dispatch(sys.argv[1:]))
    23     sys.exit(commands.dispatch(sys.argv[1:]))
    24 except commands.UnknownCommand:
    24 except commands.UnknownCommand:
    25     # fall through
    25     # fall through
   114             r = repo.changelog.rev(n)
   114             r = repo.changelog.rev(n)
   115         except KeyError:
   115         except KeyError:
   116             r = "?"
   116             r = "?"
   117         print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
   117         print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
   118 
   118 
   119 elif cmd == "verify":
       
   120     filelinkrevs = {}
       
   121     filenodes = {}
       
   122     manifestchangeset = {}
       
   123     changesets = revisions = files = 0
       
   124     errors = 0
       
   125 
       
   126     ui.status("checking changesets\n")
       
   127     for i in range(repo.changelog.count()):
       
   128         changesets += 1
       
   129         n = repo.changelog.node(i)
       
   130         for p in repo.changelog.parents(n):
       
   131             if p not in repo.changelog.nodemap:
       
   132                 ui.warn("changeset %s has unknown parent %s\n" %
       
   133                         (hg.short(n), hg.short(p)))
       
   134                 errors += 1
       
   135         try:
       
   136             changes = repo.changelog.read(n)
       
   137         except Exception, inst:
       
   138             ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
       
   139             errors += 1
       
   140             
       
   141         manifestchangeset[changes[0]] = n
       
   142         for f in changes[3]:
       
   143             filelinkrevs.setdefault(f, []).append(i)
       
   144 
       
   145     ui.status("checking manifests\n")
       
   146     for i in range(repo.manifest.count()):
       
   147         n = repo.manifest.node(i)
       
   148         for p in repo.manifest.parents(n):
       
   149             if p not in repo.manifest.nodemap:
       
   150                 ui.warn("manifest %s has unknown parent %s\n" %
       
   151                         (hg.short(n), hg.short(p)))
       
   152                 errors += 1
       
   153         ca = repo.changelog.node(repo.manifest.linkrev(n))
       
   154         cc = manifestchangeset[n]
       
   155         if ca != cc:
       
   156             ui.warn("manifest %s points to %s, not %s\n" %
       
   157                     (hg.hex(n), hg.hex(ca), hg.hex(cc)))
       
   158             errors += 1
       
   159 
       
   160         try:
       
   161             delta = mdiff.patchtext(repo.manifest.delta(n))
       
   162         except KeyboardInterrupt:
       
   163             print "aborted"
       
   164             sys.exit(0)
       
   165         except Exception, inst:
       
   166             ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
       
   167             errors += 1
       
   168 
       
   169         ff = [ l.split('\0') for l in delta.splitlines() ]
       
   170         for f, fn in ff:
       
   171             filenodes.setdefault(f, {})[hg.bin(fn)] = 1
       
   172 
       
   173     ui.status("crosschecking files in changesets and manifests\n")
       
   174     for f in filenodes:
       
   175         if f not in filelinkrevs:
       
   176             ui.warn("file %s in manifest but not in changesets\n" % f)
       
   177             errors += 1
       
   178 
       
   179     for f in filelinkrevs:
       
   180         if f not in filenodes:
       
   181             ui.warn("file %s in changeset but not in manifest\n" % f)
       
   182             errors += 1
       
   183 
       
   184     ui.status("checking files\n")
       
   185     ff = filenodes.keys()
       
   186     ff.sort()
       
   187     for f in ff:
       
   188         if f == "/dev/null": continue
       
   189         files += 1
       
   190         fl = repo.file(f)
       
   191         nodes = { hg.nullid: 1 }
       
   192         for i in range(fl.count()):
       
   193             revisions += 1
       
   194             n = fl.node(i)
       
   195 
       
   196             if n not in filenodes[f]:
       
   197                 ui.warn("%s: %d:%s not in manifests\n" % (f, i, hg.short(n)))
       
   198                 print len(filenodes[f].keys()), fl.count(), f
       
   199                 errors += 1
       
   200             else:
       
   201                 del filenodes[f][n]
       
   202 
       
   203             flr = fl.linkrev(n)
       
   204             if flr not in filelinkrevs[f]:
       
   205                 ui.warn("%s:%s points to unexpected changeset rev %d\n"
       
   206                         % (f, hg.short(n), fl.linkrev(n)))
       
   207                 errors += 1
       
   208             else:
       
   209                 filelinkrevs[f].remove(flr)
       
   210 
       
   211             # verify contents
       
   212             try:
       
   213                 t = fl.read(n)
       
   214             except Exception, inst:
       
   215                 ui.warn("unpacking file %s %s: %s\n" % (f, hg.short(n), inst))
       
   216                 errors += 1
       
   217             
       
   218             # verify parents
       
   219             (p1, p2) = fl.parents(n)
       
   220             if p1 not in nodes:
       
   221                 ui.warn("file %s:%s unknown parent 1 %s" %
       
   222                         (f, hg.short(n), hg.short(p1)))
       
   223                 errors += 1
       
   224             if p2 not in nodes:
       
   225                 ui.warn("file %s:%s unknown parent 2 %s" %
       
   226                         (f, hg.short(n), hg.short(p1)))
       
   227                 errors += 1
       
   228             nodes[n] = 1
       
   229 
       
   230         # cross-check
       
   231         for node in filenodes[f]:
       
   232             ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
       
   233             errors += 1
       
   234 
       
   235     ui.status("%d files, %d changesets, %d total revisions\n" %
       
   236               (files, changesets, revisions))
       
   237     
       
   238     if errors:
       
   239         ui.warn("%d integrity errors encountered!\n" % errors)
       
   240         sys.exit(1)
       
   241 
       
   242 else:
   119 else:
   243     if cmd: ui.warn("unknown command\n\n")
   120     if cmd: ui.warn("unknown command\n\n")
   244     sys.exit(1)
   121     sys.exit(1)