mercurial/verify.py
changeset 27643 62ce86fcfd06
parent 27642 f6457349985b
child 27644 331e5c28f5f0
equal deleted inserted replaced
27642:f6457349985b 27643:62ce86fcfd06
    95             if not self.revlogv1:
    95             if not self.revlogv1:
    96                 self.warn(_("warning: `%s' uses revlog format 1") % name)
    96                 self.warn(_("warning: `%s' uses revlog format 1") % name)
    97         elif self.revlogv1:
    97         elif self.revlogv1:
    98             self.warn(_("warning: `%s' uses revlog format 0") % name)
    98             self.warn(_("warning: `%s' uses revlog format 0") % name)
    99 
    99 
       
   100     def checkentry(self, obj, i, node, seen, linkrevs, f):
       
   101         lr = obj.linkrev(obj.rev(node))
       
   102         if lr < 0 or (self.havecl and lr not in linkrevs):
       
   103             if lr < 0 or lr >= len(self.repo.changelog):
       
   104                 msg = _("rev %d points to nonexistent changeset %d")
       
   105             else:
       
   106                 msg = _("rev %d points to unexpected changeset %d")
       
   107             self.err(None, msg % (i, lr), f)
       
   108             if linkrevs:
       
   109                 if f and len(linkrevs) > 1:
       
   110                     try:
       
   111                         # attempt to filter down to real linkrevs
       
   112                         linkrevs = [l for l in linkrevs
       
   113                                     if self.lrugetctx(l)[f].filenode() == node]
       
   114                     except Exception:
       
   115                         pass
       
   116                 self.warn(_(" (expected %s)") % " ".join(map(str, linkrevs)))
       
   117             lr = None # can't be trusted
       
   118 
       
   119         try:
       
   120             p1, p2 = obj.parents(node)
       
   121             if p1 not in seen and p1 != nullid:
       
   122                 self.err(lr, _("unknown parent 1 %s of %s") %
       
   123                     (short(p1), short(node)), f)
       
   124             if p2 not in seen and p2 != nullid:
       
   125                 self.err(lr, _("unknown parent 2 %s of %s") %
       
   126                     (short(p2), short(node)), f)
       
   127         except Exception as inst:
       
   128             self.exc(lr, _("checking parents of %s") % short(node), inst, f)
       
   129 
       
   130         if node in seen:
       
   131             self.err(lr, _("duplicate revision %d (%d)") % (i, seen[node]), f)
       
   132         seen[node] = i
       
   133         return lr
       
   134 
   100     def verify(self):
   135     def verify(self):
   101         repo = self.repo
   136         repo = self.repo
   102         mflinkrevs = {}
   137         mflinkrevs = {}
   103         filelinkrevs = {}
   138         filelinkrevs = {}
   104         filenodes = {}
   139         filenodes = {}
   110         lrugetctx = self.lrugetctx
   145         lrugetctx = self.lrugetctx
   111 
   146 
   112         if not repo.url().startswith('file:'):
   147         if not repo.url().startswith('file:'):
   113             raise error.Abort(_("cannot verify bundle or remote repos"))
   148             raise error.Abort(_("cannot verify bundle or remote repos"))
   114 
   149 
   115         def checkentry(obj, i, node, seen, linkrevs, f):
       
   116             lr = obj.linkrev(obj.rev(node))
       
   117             if lr < 0 or (havecl and lr not in linkrevs):
       
   118                 if lr < 0 or lr >= len(cl):
       
   119                     msg = _("rev %d points to nonexistent changeset %d")
       
   120                 else:
       
   121                     msg = _("rev %d points to unexpected changeset %d")
       
   122                 self.err(None, msg % (i, lr), f)
       
   123                 if linkrevs:
       
   124                     if f and len(linkrevs) > 1:
       
   125                         try:
       
   126                             # attempt to filter down to real linkrevs
       
   127                             linkrevs = [l for l in linkrevs
       
   128                                         if lrugetctx(l)[f].filenode() == node]
       
   129                         except Exception:
       
   130                             pass
       
   131                     self.warn(_(" (expected %s)") %
       
   132                               " ".join(map(str, linkrevs)))
       
   133                 lr = None # can't be trusted
       
   134 
       
   135             try:
       
   136                 p1, p2 = obj.parents(node)
       
   137                 if p1 not in seen and p1 != nullid:
       
   138                     self.err(lr, _("unknown parent 1 %s of %s") %
       
   139                              (short(p1), short(node)), f)
       
   140                 if p2 not in seen and p2 != nullid:
       
   141                     self.err(lr, _("unknown parent 2 %s of %s") %
       
   142                              (short(p2), short(node)), f)
       
   143             except Exception as inst:
       
   144                 self.exc(lr, _("checking parents of %s") % short(node), inst, f)
       
   145 
       
   146             if node in seen:
       
   147                 self.err(lr, _("duplicate revision %d (%d)") %
       
   148                          (i, seen[node]), f)
       
   149             seen[node] = i
       
   150             return lr
       
   151 
       
   152         if os.path.exists(repo.sjoin("journal")):
   150         if os.path.exists(repo.sjoin("journal")):
   153             ui.warn(_("abandoned transaction found - run hg recover\n"))
   151             ui.warn(_("abandoned transaction found - run hg recover\n"))
   154 
   152 
   155         revlogv1 = self.revlogv1
   153         revlogv1 = self.revlogv1
   156         if ui.verbose or not revlogv1:
   154         if ui.verbose or not revlogv1:
   165         self.checklog(cl, "changelog", 0)
   163         self.checklog(cl, "changelog", 0)
   166         total = len(repo)
   164         total = len(repo)
   167         for i in repo:
   165         for i in repo:
   168             ui.progress(_('checking'), i, total=total, unit=_('changesets'))
   166             ui.progress(_('checking'), i, total=total, unit=_('changesets'))
   169             n = cl.node(i)
   167             n = cl.node(i)
   170             checkentry(cl, i, n, seen, [i], "changelog")
   168             self.checkentry(cl, i, n, seen, [i], "changelog")
   171 
   169 
   172             try:
   170             try:
   173                 changes = cl.read(n)
   171                 changes = cl.read(n)
   174                 if changes[0] != nullid:
   172                 if changes[0] != nullid:
   175                     mflinkrevs.setdefault(changes[0], []).append(i)
   173                     mflinkrevs.setdefault(changes[0], []).append(i)
   190             self.checklog(mf, "manifest", 0)
   188             self.checklog(mf, "manifest", 0)
   191         total = len(mf)
   189         total = len(mf)
   192         for i in mf:
   190         for i in mf:
   193             ui.progress(_('checking'), i, total=total, unit=_('manifests'))
   191             ui.progress(_('checking'), i, total=total, unit=_('manifests'))
   194             n = mf.node(i)
   192             n = mf.node(i)
   195             lr = checkentry(mf, i, n, seen, mflinkrevs.get(n, []), "manifest")
   193             lr = self.checkentry(mf, i, n, seen, mflinkrevs.get(n, []),
       
   194                                  "manifest")
   196             if n in mflinkrevs:
   195             if n in mflinkrevs:
   197                 del mflinkrevs[n]
   196                 del mflinkrevs[n]
   198             else:
   197             else:
   199                 self.err(lr, _("%s not in changesets") % short(n), "manifest")
   198                 self.err(lr, _("%s not in changesets") % short(n), "manifest")
   200 
   199 
   287             seen = {}
   286             seen = {}
   288             rp = None
   287             rp = None
   289             for i in fl:
   288             for i in fl:
   290                 revisions += 1
   289                 revisions += 1
   291                 n = fl.node(i)
   290                 n = fl.node(i)
   292                 lr = checkentry(fl, i, n, seen, linkrevs, f)
   291                 lr = self.checkentry(fl, i, n, seen, linkrevs, f)
   293                 if f in filenodes:
   292                 if f in filenodes:
   294                     if havemf and n not in filenodes[f]:
   293                     if havemf and n not in filenodes[f]:
   295                         self.err(lr, _("%s not in manifests") % (short(n)), f)
   294                         self.err(lr, _("%s not in manifests") % (short(n)), f)
   296                     else:
   295                     else:
   297                         del filenodes[f][n]
   296                         del filenodes[f][n]