Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/verify.py @ 26900:d1c741644d25
verify: add a hook that can let extensions manipulate file lists
Without a hook of this nature, narrowhg[0] clones always result in 'hg
verify' reporting terrible damage to the entire repository
history. With this hook, we can ignore files that aren't supposed to
be in the clone, and then get an accurate report of any damage present
(or not) in the repo.
0: https://bitbucket.org/Google/narrowhg
author | Augie Fackler <augie@google.com> |
---|---|
date | Wed, 04 Nov 2015 12:14:18 -0500 |
parents | 56b2bcea2529 |
children | 937e73a6e4ff |
comparison
equal
deleted
inserted
replaced
26899:5f88e092f82c | 26900:d1c741644d25 |
---|---|
32 # under hg < 2.4, convert didn't sanitize paths properly, so a | 32 # under hg < 2.4, convert didn't sanitize paths properly, so a |
33 # converted repo may contain repeated slashes | 33 # converted repo may contain repeated slashes |
34 while '//' in f: | 34 while '//' in f: |
35 f = f.replace('//', '/') | 35 f = f.replace('//', '/') |
36 return f | 36 return f |
37 | |
38 def _validpath(repo, path): | |
39 """Returns False if a path should NOT be treated as part of a repo. | |
40 | |
41 For all in-core cases, this returns True, as we have no way for a | |
42 path to be mentioned in the history but not actually be | |
43 relevant. For narrow clones, this is important because many | |
44 filelogs will be missing, and changelog entries may mention | |
45 modified files that are outside the narrow scope. | |
46 """ | |
47 return True | |
37 | 48 |
38 def _verify(repo): | 49 def _verify(repo): |
39 repo = repo.unfiltered() | 50 repo = repo.unfiltered() |
40 mflinkrevs = {} | 51 mflinkrevs = {} |
41 filelinkrevs = {} | 52 filelinkrevs = {} |
152 changes = cl.read(n) | 163 changes = cl.read(n) |
153 if changes[0] != nullid: | 164 if changes[0] != nullid: |
154 mflinkrevs.setdefault(changes[0], []).append(i) | 165 mflinkrevs.setdefault(changes[0], []).append(i) |
155 refersmf = True | 166 refersmf = True |
156 for f in changes[3]: | 167 for f in changes[3]: |
157 filelinkrevs.setdefault(_normpath(f), []).append(i) | 168 if _validpath(repo, f): |
169 filelinkrevs.setdefault(_normpath(f), []).append(i) | |
158 except Exception as inst: | 170 except Exception as inst: |
159 refersmf = True | 171 refersmf = True |
160 exc(i, _("unpacking changeset %s") % short(n), inst) | 172 exc(i, _("unpacking changeset %s") % short(n), inst) |
161 ui.progress(_('checking'), None) | 173 ui.progress(_('checking'), None) |
162 | 174 |
179 try: | 191 try: |
180 for f, fn in mf.readdelta(n).iteritems(): | 192 for f, fn in mf.readdelta(n).iteritems(): |
181 if not f: | 193 if not f: |
182 err(lr, _("file without name in manifest")) | 194 err(lr, _("file without name in manifest")) |
183 elif f != "/dev/null": # ignore this in very old repos | 195 elif f != "/dev/null": # ignore this in very old repos |
184 filenodes.setdefault(_normpath(f), {}).setdefault(fn, lr) | 196 if _validpath(repo, f): |
197 filenodes.setdefault( | |
198 _normpath(f), {}).setdefault(fn, lr) | |
185 except Exception as inst: | 199 except Exception as inst: |
186 exc(lr, _("reading manifest delta %s") % short(n), inst) | 200 exc(lr, _("reading manifest delta %s") % short(n), inst) |
187 ui.progress(_('checking'), None) | 201 ui.progress(_('checking'), None) |
188 | 202 |
189 ui.status(_("crosschecking files in changesets and manifests\n")) | 203 ui.status(_("crosschecking files in changesets and manifests\n")) |