comparison mercurial/verify.py @ 28204:962921c330b0

verify: check for orphaned dirlogs We already report orphaned filelogs, i.e. revlogs for files that are not mentioned in any manifest. This change adds checking for orphaned dirlogs, i.e. revlogs that are not mentioned in any parent-directory dirlog. Note that, for fncachestore, only files mentioned in the fncache are considered, there's not check for files in .hg/store/meta that are not mentioned in the fncache. This is no different from the current situation for filelogs.
author Martin von Zweigbergk <martinvonz@google.com>
date Wed, 03 Feb 2016 15:35:15 -0800
parents 7297e9e13a8a
children 53f42c8d5f71
comparison
equal deleted inserted replaced
28203:7297e9e13a8a 28204:962921c330b0
195 self.refersmf = True 195 self.refersmf = True
196 self.exc(i, _("unpacking changeset %s") % short(n), inst) 196 self.exc(i, _("unpacking changeset %s") % short(n), inst)
197 ui.progress(_('checking'), None) 197 ui.progress(_('checking'), None)
198 return mflinkrevs, filelinkrevs 198 return mflinkrevs, filelinkrevs
199 199
200 def _verifymanifest(self, mflinkrevs, dir=""): 200 def _verifymanifest(self, mflinkrevs, dir="", storefiles=None):
201 repo = self.repo 201 repo = self.repo
202 ui = self.ui 202 ui = self.ui
203 mf = self.repo.manifest.dirlog(dir) 203 mf = self.repo.manifest.dirlog(dir)
204 204
205 if not dir: 205 if not dir:
209 subdirnodes = {} 209 subdirnodes = {}
210 seen = {} 210 seen = {}
211 label = "manifest" 211 label = "manifest"
212 if dir: 212 if dir:
213 label = dir 213 label = dir
214 revlogfiles = mf.files()
215 storefiles.difference_update(revlogfiles)
214 if self.refersmf: 216 if self.refersmf:
215 # Do not check manifest if there are only changelog entries with 217 # Do not check manifest if there are only changelog entries with
216 # null manifests. 218 # null manifests.
217 self.checklog(mf, label, 0) 219 self.checklog(mf, label, 0)
218 total = len(mf) 220 total = len(mf)
258 self.err(c, _("changeset refers to unknown revision %s") % 260 self.err(c, _("changeset refers to unknown revision %s") %
259 short(m), label) 261 short(m), label)
260 262
261 if not dir and subdirnodes: 263 if not dir and subdirnodes:
262 self.ui.status(_("checking directory manifests\n")) 264 self.ui.status(_("checking directory manifests\n"))
265 storefiles = set()
266 revlogv1 = self.revlogv1
267 for f, f2, size in repo.store.datafiles():
268 if not f:
269 self.err(None, _("cannot decode filename '%s'") % f2)
270 elif (size > 0 or not revlogv1) and f.startswith('meta/'):
271 storefiles.add(_normpath(f))
272
263 for subdir, linkrevs in subdirnodes.iteritems(): 273 for subdir, linkrevs in subdirnodes.iteritems():
264 subdirfilenodes = self._verifymanifest(linkrevs, subdir) 274 subdirfilenodes = self._verifymanifest(linkrevs, subdir, storefiles)
265 for f, onefilenodes in subdirfilenodes.iteritems(): 275 for f, onefilenodes in subdirfilenodes.iteritems():
266 filenodes.setdefault(f, {}).update(onefilenodes) 276 filenodes.setdefault(f, {}).update(onefilenodes)
277
278 if not dir and subdirnodes:
279 for f in sorted(storefiles):
280 self.warn(_("warning: orphan revlog '%s'") % f)
267 281
268 return filenodes 282 return filenodes
269 283
270 def _crosscheckfiles(self, filelinkrevs, filenodes): 284 def _crosscheckfiles(self, filelinkrevs, filenodes):
271 repo = self.repo 285 repo = self.repo
400 for lr, node in sorted(fns): 414 for lr, node in sorted(fns):
401 self.err(lr, _("manifest refers to unknown revision %s") % 415 self.err(lr, _("manifest refers to unknown revision %s") %
402 short(node), f) 416 short(node), f)
403 ui.progress(_('checking'), None) 417 ui.progress(_('checking'), None)
404 418
405 for f in storefiles: 419 for f in sorted(storefiles):
406 self.warn(_("warning: orphan revlog '%s'") % f) 420 self.warn(_("warning: orphan revlog '%s'") % f)
407 421
408 return len(files), revisions 422 return len(files), revisions