##// END OF EJS Templates
verify: check for orphaned dirlogs...
Martin von Zweigbergk -
r28204:962921c3 default
parent child Browse files
Show More
@@ -1,408 +1,422
1 # verify.py - repository integrity checking for Mercurial
1 # verify.py - repository integrity checking for Mercurial
2 #
2 #
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import os
10 import os
11
11
12 from .i18n import _
12 from .i18n import _
13 from .node import (
13 from .node import (
14 nullid,
14 nullid,
15 short,
15 short,
16 )
16 )
17
17
18 from . import (
18 from . import (
19 error,
19 error,
20 revlog,
20 revlog,
21 util,
21 util,
22 )
22 )
23
23
24 def verify(repo):
24 def verify(repo):
25 with repo.lock():
25 with repo.lock():
26 return verifier(repo).verify()
26 return verifier(repo).verify()
27
27
28 def _normpath(f):
28 def _normpath(f):
29 # under hg < 2.4, convert didn't sanitize paths properly, so a
29 # under hg < 2.4, convert didn't sanitize paths properly, so a
30 # converted repo may contain repeated slashes
30 # converted repo may contain repeated slashes
31 while '//' in f:
31 while '//' in f:
32 f = f.replace('//', '/')
32 f = f.replace('//', '/')
33 return f
33 return f
34
34
35 def _validpath(repo, path):
35 def _validpath(repo, path):
36 """Returns False if a path should NOT be treated as part of a repo.
36 """Returns False if a path should NOT be treated as part of a repo.
37
37
38 For all in-core cases, this returns True, as we have no way for a
38 For all in-core cases, this returns True, as we have no way for a
39 path to be mentioned in the history but not actually be
39 path to be mentioned in the history but not actually be
40 relevant. For narrow clones, this is important because many
40 relevant. For narrow clones, this is important because many
41 filelogs will be missing, and changelog entries may mention
41 filelogs will be missing, and changelog entries may mention
42 modified files that are outside the narrow scope.
42 modified files that are outside the narrow scope.
43 """
43 """
44 return True
44 return True
45
45
46 class verifier(object):
46 class verifier(object):
47 def __init__(self, repo):
47 def __init__(self, repo):
48 self.repo = repo.unfiltered()
48 self.repo = repo.unfiltered()
49 self.ui = repo.ui
49 self.ui = repo.ui
50 self.badrevs = set()
50 self.badrevs = set()
51 self.errors = 0
51 self.errors = 0
52 self.warnings = 0
52 self.warnings = 0
53 self.havecl = len(repo.changelog) > 0
53 self.havecl = len(repo.changelog) > 0
54 self.havemf = len(repo.manifest) > 0
54 self.havemf = len(repo.manifest) > 0
55 self.revlogv1 = repo.changelog.version != revlog.REVLOGV0
55 self.revlogv1 = repo.changelog.version != revlog.REVLOGV0
56 self.lrugetctx = util.lrucachefunc(repo.changectx)
56 self.lrugetctx = util.lrucachefunc(repo.changectx)
57 self.refersmf = False
57 self.refersmf = False
58 self.fncachewarned = False
58 self.fncachewarned = False
59
59
60 def warn(self, msg):
60 def warn(self, msg):
61 self.ui.warn(msg + "\n")
61 self.ui.warn(msg + "\n")
62 self.warnings += 1
62 self.warnings += 1
63
63
64 def err(self, linkrev, msg, filename=None):
64 def err(self, linkrev, msg, filename=None):
65 if linkrev is not None:
65 if linkrev is not None:
66 self.badrevs.add(linkrev)
66 self.badrevs.add(linkrev)
67 else:
67 else:
68 linkrev = '?'
68 linkrev = '?'
69 msg = "%s: %s" % (linkrev, msg)
69 msg = "%s: %s" % (linkrev, msg)
70 if filename:
70 if filename:
71 msg = "%s@%s" % (filename, msg)
71 msg = "%s@%s" % (filename, msg)
72 self.ui.warn(" " + msg + "\n")
72 self.ui.warn(" " + msg + "\n")
73 self.errors += 1
73 self.errors += 1
74
74
75 def exc(self, linkrev, msg, inst, filename=None):
75 def exc(self, linkrev, msg, inst, filename=None):
76 if not str(inst):
76 if not str(inst):
77 inst = repr(inst)
77 inst = repr(inst)
78 self.err(linkrev, "%s: %s" % (msg, inst), filename)
78 self.err(linkrev, "%s: %s" % (msg, inst), filename)
79
79
80 def checklog(self, obj, name, linkrev):
80 def checklog(self, obj, name, linkrev):
81 if not len(obj) and (self.havecl or self.havemf):
81 if not len(obj) and (self.havecl or self.havemf):
82 self.err(linkrev, _("empty or missing %s") % name)
82 self.err(linkrev, _("empty or missing %s") % name)
83 return
83 return
84
84
85 d = obj.checksize()
85 d = obj.checksize()
86 if d[0]:
86 if d[0]:
87 self.err(None, _("data length off by %d bytes") % d[0], name)
87 self.err(None, _("data length off by %d bytes") % d[0], name)
88 if d[1]:
88 if d[1]:
89 self.err(None, _("index contains %d extra bytes") % d[1], name)
89 self.err(None, _("index contains %d extra bytes") % d[1], name)
90
90
91 if obj.version != revlog.REVLOGV0:
91 if obj.version != revlog.REVLOGV0:
92 if not self.revlogv1:
92 if not self.revlogv1:
93 self.warn(_("warning: `%s' uses revlog format 1") % name)
93 self.warn(_("warning: `%s' uses revlog format 1") % name)
94 elif self.revlogv1:
94 elif self.revlogv1:
95 self.warn(_("warning: `%s' uses revlog format 0") % name)
95 self.warn(_("warning: `%s' uses revlog format 0") % name)
96
96
97 def checkentry(self, obj, i, node, seen, linkrevs, f):
97 def checkentry(self, obj, i, node, seen, linkrevs, f):
98 lr = obj.linkrev(obj.rev(node))
98 lr = obj.linkrev(obj.rev(node))
99 if lr < 0 or (self.havecl and lr not in linkrevs):
99 if lr < 0 or (self.havecl and lr not in linkrevs):
100 if lr < 0 or lr >= len(self.repo.changelog):
100 if lr < 0 or lr >= len(self.repo.changelog):
101 msg = _("rev %d points to nonexistent changeset %d")
101 msg = _("rev %d points to nonexistent changeset %d")
102 else:
102 else:
103 msg = _("rev %d points to unexpected changeset %d")
103 msg = _("rev %d points to unexpected changeset %d")
104 self.err(None, msg % (i, lr), f)
104 self.err(None, msg % (i, lr), f)
105 if linkrevs:
105 if linkrevs:
106 if f and len(linkrevs) > 1:
106 if f and len(linkrevs) > 1:
107 try:
107 try:
108 # attempt to filter down to real linkrevs
108 # attempt to filter down to real linkrevs
109 linkrevs = [l for l in linkrevs
109 linkrevs = [l for l in linkrevs
110 if self.lrugetctx(l)[f].filenode() == node]
110 if self.lrugetctx(l)[f].filenode() == node]
111 except Exception:
111 except Exception:
112 pass
112 pass
113 self.warn(_(" (expected %s)") % " ".join(map(str, linkrevs)))
113 self.warn(_(" (expected %s)") % " ".join(map(str, linkrevs)))
114 lr = None # can't be trusted
114 lr = None # can't be trusted
115
115
116 try:
116 try:
117 p1, p2 = obj.parents(node)
117 p1, p2 = obj.parents(node)
118 if p1 not in seen and p1 != nullid:
118 if p1 not in seen and p1 != nullid:
119 self.err(lr, _("unknown parent 1 %s of %s") %
119 self.err(lr, _("unknown parent 1 %s of %s") %
120 (short(p1), short(node)), f)
120 (short(p1), short(node)), f)
121 if p2 not in seen and p2 != nullid:
121 if p2 not in seen and p2 != nullid:
122 self.err(lr, _("unknown parent 2 %s of %s") %
122 self.err(lr, _("unknown parent 2 %s of %s") %
123 (short(p2), short(node)), f)
123 (short(p2), short(node)), f)
124 except Exception as inst:
124 except Exception as inst:
125 self.exc(lr, _("checking parents of %s") % short(node), inst, f)
125 self.exc(lr, _("checking parents of %s") % short(node), inst, f)
126
126
127 if node in seen:
127 if node in seen:
128 self.err(lr, _("duplicate revision %d (%d)") % (i, seen[node]), f)
128 self.err(lr, _("duplicate revision %d (%d)") % (i, seen[node]), f)
129 seen[node] = i
129 seen[node] = i
130 return lr
130 return lr
131
131
132 def verify(self):
132 def verify(self):
133 repo = self.repo
133 repo = self.repo
134
134
135 ui = repo.ui
135 ui = repo.ui
136
136
137 if not repo.url().startswith('file:'):
137 if not repo.url().startswith('file:'):
138 raise error.Abort(_("cannot verify bundle or remote repos"))
138 raise error.Abort(_("cannot verify bundle or remote repos"))
139
139
140 if os.path.exists(repo.sjoin("journal")):
140 if os.path.exists(repo.sjoin("journal")):
141 ui.warn(_("abandoned transaction found - run hg recover\n"))
141 ui.warn(_("abandoned transaction found - run hg recover\n"))
142
142
143 if ui.verbose or not self.revlogv1:
143 if ui.verbose or not self.revlogv1:
144 ui.status(_("repository uses revlog format %d\n") %
144 ui.status(_("repository uses revlog format %d\n") %
145 (self.revlogv1 and 1 or 0))
145 (self.revlogv1 and 1 or 0))
146
146
147 mflinkrevs, filelinkrevs = self._verifychangelog()
147 mflinkrevs, filelinkrevs = self._verifychangelog()
148
148
149 filenodes = self._verifymanifest(mflinkrevs)
149 filenodes = self._verifymanifest(mflinkrevs)
150 del mflinkrevs
150 del mflinkrevs
151
151
152 self._crosscheckfiles(filelinkrevs, filenodes)
152 self._crosscheckfiles(filelinkrevs, filenodes)
153
153
154 totalfiles, filerevisions = self._verifyfiles(filenodes, filelinkrevs)
154 totalfiles, filerevisions = self._verifyfiles(filenodes, filelinkrevs)
155
155
156 ui.status(_("%d files, %d changesets, %d total revisions\n") %
156 ui.status(_("%d files, %d changesets, %d total revisions\n") %
157 (totalfiles, len(repo.changelog), filerevisions))
157 (totalfiles, len(repo.changelog), filerevisions))
158 if self.warnings:
158 if self.warnings:
159 ui.warn(_("%d warnings encountered!\n") % self.warnings)
159 ui.warn(_("%d warnings encountered!\n") % self.warnings)
160 if self.fncachewarned:
160 if self.fncachewarned:
161 ui.warn(_('hint: run "hg debugrebuildfncache" to recover from '
161 ui.warn(_('hint: run "hg debugrebuildfncache" to recover from '
162 'corrupt fncache\n'))
162 'corrupt fncache\n'))
163 if self.errors:
163 if self.errors:
164 ui.warn(_("%d integrity errors encountered!\n") % self.errors)
164 ui.warn(_("%d integrity errors encountered!\n") % self.errors)
165 if self.badrevs:
165 if self.badrevs:
166 ui.warn(_("(first damaged changeset appears to be %d)\n")
166 ui.warn(_("(first damaged changeset appears to be %d)\n")
167 % min(self.badrevs))
167 % min(self.badrevs))
168 return 1
168 return 1
169
169
170 def _verifychangelog(self):
170 def _verifychangelog(self):
171 ui = self.ui
171 ui = self.ui
172 repo = self.repo
172 repo = self.repo
173 cl = repo.changelog
173 cl = repo.changelog
174
174
175 ui.status(_("checking changesets\n"))
175 ui.status(_("checking changesets\n"))
176 mflinkrevs = {}
176 mflinkrevs = {}
177 filelinkrevs = {}
177 filelinkrevs = {}
178 seen = {}
178 seen = {}
179 self.checklog(cl, "changelog", 0)
179 self.checklog(cl, "changelog", 0)
180 total = len(repo)
180 total = len(repo)
181 for i in repo:
181 for i in repo:
182 ui.progress(_('checking'), i, total=total, unit=_('changesets'))
182 ui.progress(_('checking'), i, total=total, unit=_('changesets'))
183 n = cl.node(i)
183 n = cl.node(i)
184 self.checkentry(cl, i, n, seen, [i], "changelog")
184 self.checkentry(cl, i, n, seen, [i], "changelog")
185
185
186 try:
186 try:
187 changes = cl.read(n)
187 changes = cl.read(n)
188 if changes[0] != nullid:
188 if changes[0] != nullid:
189 mflinkrevs.setdefault(changes[0], []).append(i)
189 mflinkrevs.setdefault(changes[0], []).append(i)
190 self.refersmf = True
190 self.refersmf = True
191 for f in changes[3]:
191 for f in changes[3]:
192 if _validpath(repo, f):
192 if _validpath(repo, f):
193 filelinkrevs.setdefault(_normpath(f), []).append(i)
193 filelinkrevs.setdefault(_normpath(f), []).append(i)
194 except Exception as inst:
194 except Exception as inst:
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:
206 self.ui.status(_("checking manifests\n"))
206 self.ui.status(_("checking manifests\n"))
207
207
208 filenodes = {}
208 filenodes = {}
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)
219 for i in mf:
221 for i in mf:
220 if not dir:
222 if not dir:
221 ui.progress(_('checking'), i, total=total, unit=_('manifests'))
223 ui.progress(_('checking'), i, total=total, unit=_('manifests'))
222 n = mf.node(i)
224 n = mf.node(i)
223 lr = self.checkentry(mf, i, n, seen, mflinkrevs.get(n, []), label)
225 lr = self.checkentry(mf, i, n, seen, mflinkrevs.get(n, []), label)
224 if n in mflinkrevs:
226 if n in mflinkrevs:
225 del mflinkrevs[n]
227 del mflinkrevs[n]
226 elif dir:
228 elif dir:
227 self.err(lr, _("%s not in parent-directory manifest") %
229 self.err(lr, _("%s not in parent-directory manifest") %
228 short(n), label)
230 short(n), label)
229 else:
231 else:
230 self.err(lr, _("%s not in changesets") % short(n), label)
232 self.err(lr, _("%s not in changesets") % short(n), label)
231
233
232 try:
234 try:
233 for f, fn, fl in mf.readshallowdelta(n).iterentries():
235 for f, fn, fl in mf.readshallowdelta(n).iterentries():
234 if not f:
236 if not f:
235 self.err(lr, _("entry without name in manifest"))
237 self.err(lr, _("entry without name in manifest"))
236 elif f == "/dev/null": # ignore this in very old repos
238 elif f == "/dev/null": # ignore this in very old repos
237 continue
239 continue
238 fullpath = dir + _normpath(f)
240 fullpath = dir + _normpath(f)
239 if not _validpath(repo, fullpath):
241 if not _validpath(repo, fullpath):
240 continue
242 continue
241 if fl == 't':
243 if fl == 't':
242 subdirnodes.setdefault(fullpath + '/', {}).setdefault(
244 subdirnodes.setdefault(fullpath + '/', {}).setdefault(
243 fn, []).append(lr)
245 fn, []).append(lr)
244 else:
246 else:
245 filenodes.setdefault(fullpath, {}).setdefault(fn, lr)
247 filenodes.setdefault(fullpath, {}).setdefault(fn, lr)
246 except Exception as inst:
248 except Exception as inst:
247 self.exc(lr, _("reading delta %s") % short(n), inst, label)
249 self.exc(lr, _("reading delta %s") % short(n), inst, label)
248 if not dir:
250 if not dir:
249 ui.progress(_('checking'), None)
251 ui.progress(_('checking'), None)
250
252
251 if self.havemf:
253 if self.havemf:
252 for c, m in sorted([(c, m) for m in mflinkrevs
254 for c, m in sorted([(c, m) for m in mflinkrevs
253 for c in mflinkrevs[m]]):
255 for c in mflinkrevs[m]]):
254 if dir:
256 if dir:
255 self.err(c, _("parent-directory manifest refers to unknown "
257 self.err(c, _("parent-directory manifest refers to unknown "
256 "revision %s") % short(m), label)
258 "revision %s") % short(m), label)
257 else:
259 else:
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)
267
277
278 if not dir and subdirnodes:
279 for f in sorted(storefiles):
280 self.warn(_("warning: orphan revlog '%s'") % f)
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
272 ui = self.ui
286 ui = self.ui
273 ui.status(_("crosschecking files in changesets and manifests\n"))
287 ui.status(_("crosschecking files in changesets and manifests\n"))
274
288
275 total = len(filelinkrevs) + len(filenodes)
289 total = len(filelinkrevs) + len(filenodes)
276 count = 0
290 count = 0
277 if self.havemf:
291 if self.havemf:
278 for f in sorted(filelinkrevs):
292 for f in sorted(filelinkrevs):
279 count += 1
293 count += 1
280 ui.progress(_('crosschecking'), count, total=total)
294 ui.progress(_('crosschecking'), count, total=total)
281 if f not in filenodes:
295 if f not in filenodes:
282 lr = filelinkrevs[f][0]
296 lr = filelinkrevs[f][0]
283 self.err(lr, _("in changeset but not in manifest"), f)
297 self.err(lr, _("in changeset but not in manifest"), f)
284
298
285 if self.havecl:
299 if self.havecl:
286 for f in sorted(filenodes):
300 for f in sorted(filenodes):
287 count += 1
301 count += 1
288 ui.progress(_('crosschecking'), count, total=total)
302 ui.progress(_('crosschecking'), count, total=total)
289 if f not in filelinkrevs:
303 if f not in filelinkrevs:
290 try:
304 try:
291 fl = repo.file(f)
305 fl = repo.file(f)
292 lr = min([fl.linkrev(fl.rev(n)) for n in filenodes[f]])
306 lr = min([fl.linkrev(fl.rev(n)) for n in filenodes[f]])
293 except Exception:
307 except Exception:
294 lr = None
308 lr = None
295 self.err(lr, _("in manifest but not in changeset"), f)
309 self.err(lr, _("in manifest but not in changeset"), f)
296
310
297 ui.progress(_('crosschecking'), None)
311 ui.progress(_('crosschecking'), None)
298
312
299 def _verifyfiles(self, filenodes, filelinkrevs):
313 def _verifyfiles(self, filenodes, filelinkrevs):
300 repo = self.repo
314 repo = self.repo
301 ui = self.ui
315 ui = self.ui
302 lrugetctx = self.lrugetctx
316 lrugetctx = self.lrugetctx
303 revlogv1 = self.revlogv1
317 revlogv1 = self.revlogv1
304 havemf = self.havemf
318 havemf = self.havemf
305 ui.status(_("checking files\n"))
319 ui.status(_("checking files\n"))
306
320
307 storefiles = set()
321 storefiles = set()
308 for f, f2, size in repo.store.datafiles():
322 for f, f2, size in repo.store.datafiles():
309 if not f:
323 if not f:
310 self.err(None, _("cannot decode filename '%s'") % f2)
324 self.err(None, _("cannot decode filename '%s'") % f2)
311 elif (size > 0 or not revlogv1) and f.startswith('data/'):
325 elif (size > 0 or not revlogv1) and f.startswith('data/'):
312 storefiles.add(_normpath(f))
326 storefiles.add(_normpath(f))
313
327
314 files = sorted(set(filenodes) | set(filelinkrevs))
328 files = sorted(set(filenodes) | set(filelinkrevs))
315 total = len(files)
329 total = len(files)
316 revisions = 0
330 revisions = 0
317 for i, f in enumerate(files):
331 for i, f in enumerate(files):
318 ui.progress(_('checking'), i, item=f, total=total)
332 ui.progress(_('checking'), i, item=f, total=total)
319 try:
333 try:
320 linkrevs = filelinkrevs[f]
334 linkrevs = filelinkrevs[f]
321 except KeyError:
335 except KeyError:
322 # in manifest but not in changelog
336 # in manifest but not in changelog
323 linkrevs = []
337 linkrevs = []
324
338
325 if linkrevs:
339 if linkrevs:
326 lr = linkrevs[0]
340 lr = linkrevs[0]
327 else:
341 else:
328 lr = None
342 lr = None
329
343
330 try:
344 try:
331 fl = repo.file(f)
345 fl = repo.file(f)
332 except error.RevlogError as e:
346 except error.RevlogError as e:
333 self.err(lr, _("broken revlog! (%s)") % e, f)
347 self.err(lr, _("broken revlog! (%s)") % e, f)
334 continue
348 continue
335
349
336 for ff in fl.files():
350 for ff in fl.files():
337 try:
351 try:
338 storefiles.remove(ff)
352 storefiles.remove(ff)
339 except KeyError:
353 except KeyError:
340 self.warn(_(" warning: revlog '%s' not in fncache!") % ff)
354 self.warn(_(" warning: revlog '%s' not in fncache!") % ff)
341 self.fncachewarned = True
355 self.fncachewarned = True
342
356
343 self.checklog(fl, f, lr)
357 self.checklog(fl, f, lr)
344 seen = {}
358 seen = {}
345 rp = None
359 rp = None
346 for i in fl:
360 for i in fl:
347 revisions += 1
361 revisions += 1
348 n = fl.node(i)
362 n = fl.node(i)
349 lr = self.checkentry(fl, i, n, seen, linkrevs, f)
363 lr = self.checkentry(fl, i, n, seen, linkrevs, f)
350 if f in filenodes:
364 if f in filenodes:
351 if havemf and n not in filenodes[f]:
365 if havemf and n not in filenodes[f]:
352 self.err(lr, _("%s not in manifests") % (short(n)), f)
366 self.err(lr, _("%s not in manifests") % (short(n)), f)
353 else:
367 else:
354 del filenodes[f][n]
368 del filenodes[f][n]
355
369
356 # verify contents
370 # verify contents
357 try:
371 try:
358 l = len(fl.read(n))
372 l = len(fl.read(n))
359 rp = fl.renamed(n)
373 rp = fl.renamed(n)
360 if l != fl.size(i):
374 if l != fl.size(i):
361 if len(fl.revision(n)) != fl.size(i):
375 if len(fl.revision(n)) != fl.size(i):
362 self.err(lr, _("unpacked size is %s, %s expected") %
376 self.err(lr, _("unpacked size is %s, %s expected") %
363 (l, fl.size(i)), f)
377 (l, fl.size(i)), f)
364 except error.CensoredNodeError:
378 except error.CensoredNodeError:
365 # experimental config: censor.policy
379 # experimental config: censor.policy
366 if ui.config("censor", "policy", "abort") == "abort":
380 if ui.config("censor", "policy", "abort") == "abort":
367 self.err(lr, _("censored file data"), f)
381 self.err(lr, _("censored file data"), f)
368 except Exception as inst:
382 except Exception as inst:
369 self.exc(lr, _("unpacking %s") % short(n), inst, f)
383 self.exc(lr, _("unpacking %s") % short(n), inst, f)
370
384
371 # check renames
385 # check renames
372 try:
386 try:
373 if rp:
387 if rp:
374 if lr is not None and ui.verbose:
388 if lr is not None and ui.verbose:
375 ctx = lrugetctx(lr)
389 ctx = lrugetctx(lr)
376 found = False
390 found = False
377 for pctx in ctx.parents():
391 for pctx in ctx.parents():
378 if rp[0] in pctx:
392 if rp[0] in pctx:
379 found = True
393 found = True
380 break
394 break
381 if not found:
395 if not found:
382 self.warn(_("warning: copy source of '%s' not"
396 self.warn(_("warning: copy source of '%s' not"
383 " in parents of %s") % (f, ctx))
397 " in parents of %s") % (f, ctx))
384 fl2 = repo.file(rp[0])
398 fl2 = repo.file(rp[0])
385 if not len(fl2):
399 if not len(fl2):
386 self.err(lr, _("empty or missing copy source "
400 self.err(lr, _("empty or missing copy source "
387 "revlog %s:%s") % (rp[0], short(rp[1])), f)
401 "revlog %s:%s") % (rp[0], short(rp[1])), f)
388 elif rp[1] == nullid:
402 elif rp[1] == nullid:
389 ui.note(_("warning: %s@%s: copy source"
403 ui.note(_("warning: %s@%s: copy source"
390 " revision is nullid %s:%s\n")
404 " revision is nullid %s:%s\n")
391 % (f, lr, rp[0], short(rp[1])))
405 % (f, lr, rp[0], short(rp[1])))
392 else:
406 else:
393 fl2.rev(rp[1])
407 fl2.rev(rp[1])
394 except Exception as inst:
408 except Exception as inst:
395 self.exc(lr, _("checking rename of %s") % short(n), inst, f)
409 self.exc(lr, _("checking rename of %s") % short(n), inst, f)
396
410
397 # cross-check
411 # cross-check
398 if f in filenodes:
412 if f in filenodes:
399 fns = [(lr, n) for n, lr in filenodes[f].iteritems()]
413 fns = [(lr, n) for n, lr in filenodes[f].iteritems()]
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
@@ -1,724 +1,731
1 #require killdaemons
1 #require killdaemons
2
2
3 $ cat << EOF >> $HGRCPATH
3 $ cat << EOF >> $HGRCPATH
4 > [format]
4 > [format]
5 > usegeneraldelta=yes
5 > usegeneraldelta=yes
6 > [ui]
6 > [ui]
7 > ssh=python "$TESTDIR/dummyssh"
7 > ssh=python "$TESTDIR/dummyssh"
8 > EOF
8 > EOF
9
9
10 Set up repo
10 Set up repo
11
11
12 $ hg --config experimental.treemanifest=True init repo
12 $ hg --config experimental.treemanifest=True init repo
13 $ cd repo
13 $ cd repo
14
14
15 Requirements get set on init
15 Requirements get set on init
16
16
17 $ grep treemanifest .hg/requires
17 $ grep treemanifest .hg/requires
18 treemanifest
18 treemanifest
19
19
20 Without directories, looks like any other repo
20 Without directories, looks like any other repo
21
21
22 $ echo 0 > a
22 $ echo 0 > a
23 $ echo 0 > b
23 $ echo 0 > b
24 $ hg ci -Aqm initial
24 $ hg ci -Aqm initial
25 $ hg debugdata -m 0
25 $ hg debugdata -m 0
26 a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
26 a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
27 b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
27 b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
28
28
29 Submanifest is stored in separate revlog
29 Submanifest is stored in separate revlog
30
30
31 $ mkdir dir1
31 $ mkdir dir1
32 $ echo 1 > dir1/a
32 $ echo 1 > dir1/a
33 $ echo 1 > dir1/b
33 $ echo 1 > dir1/b
34 $ echo 1 > e
34 $ echo 1 > e
35 $ hg ci -Aqm 'add dir1'
35 $ hg ci -Aqm 'add dir1'
36 $ hg debugdata -m 1
36 $ hg debugdata -m 1
37 a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
37 a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
38 b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
38 b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
39 dir1\x008b3ffd73f901e83304c83d33132c8e774ceac44et (esc)
39 dir1\x008b3ffd73f901e83304c83d33132c8e774ceac44et (esc)
40 e\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
40 e\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
41 $ hg debugdata --dir dir1 0
41 $ hg debugdata --dir dir1 0
42 a\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
42 a\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
43 b\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
43 b\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
44
44
45 Can add nested directories
45 Can add nested directories
46
46
47 $ mkdir dir1/dir1
47 $ mkdir dir1/dir1
48 $ echo 2 > dir1/dir1/a
48 $ echo 2 > dir1/dir1/a
49 $ echo 2 > dir1/dir1/b
49 $ echo 2 > dir1/dir1/b
50 $ mkdir dir1/dir2
50 $ mkdir dir1/dir2
51 $ echo 2 > dir1/dir2/a
51 $ echo 2 > dir1/dir2/a
52 $ echo 2 > dir1/dir2/b
52 $ echo 2 > dir1/dir2/b
53 $ hg ci -Aqm 'add dir1/dir1'
53 $ hg ci -Aqm 'add dir1/dir1'
54 $ hg files -r .
54 $ hg files -r .
55 a
55 a
56 b
56 b
57 dir1/a (glob)
57 dir1/a (glob)
58 dir1/b (glob)
58 dir1/b (glob)
59 dir1/dir1/a (glob)
59 dir1/dir1/a (glob)
60 dir1/dir1/b (glob)
60 dir1/dir1/b (glob)
61 dir1/dir2/a (glob)
61 dir1/dir2/a (glob)
62 dir1/dir2/b (glob)
62 dir1/dir2/b (glob)
63 e
63 e
64
64
65 Revision is not created for unchanged directory
65 Revision is not created for unchanged directory
66
66
67 $ mkdir dir2
67 $ mkdir dir2
68 $ echo 3 > dir2/a
68 $ echo 3 > dir2/a
69 $ hg add dir2
69 $ hg add dir2
70 adding dir2/a (glob)
70 adding dir2/a (glob)
71 $ hg debugindex --dir dir1 > before
71 $ hg debugindex --dir dir1 > before
72 $ hg ci -qm 'add dir2'
72 $ hg ci -qm 'add dir2'
73 $ hg debugindex --dir dir1 > after
73 $ hg debugindex --dir dir1 > after
74 $ diff before after
74 $ diff before after
75 $ rm before after
75 $ rm before after
76
76
77 Removing directory does not create an revlog entry
77 Removing directory does not create an revlog entry
78
78
79 $ hg rm dir1/dir1
79 $ hg rm dir1/dir1
80 removing dir1/dir1/a (glob)
80 removing dir1/dir1/a (glob)
81 removing dir1/dir1/b (glob)
81 removing dir1/dir1/b (glob)
82 $ hg debugindex --dir dir1/dir1 > before
82 $ hg debugindex --dir dir1/dir1 > before
83 $ hg ci -qm 'remove dir1/dir1'
83 $ hg ci -qm 'remove dir1/dir1'
84 $ hg debugindex --dir dir1/dir1 > after
84 $ hg debugindex --dir dir1/dir1 > after
85 $ diff before after
85 $ diff before after
86 $ rm before after
86 $ rm before after
87
87
88 Check that hg files (calls treemanifest.walk()) works
88 Check that hg files (calls treemanifest.walk()) works
89 without loading all directory revlogs
89 without loading all directory revlogs
90
90
91 $ hg co 'desc("add dir2")'
91 $ hg co 'desc("add dir2")'
92 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
93 $ mv .hg/store/meta/dir2 .hg/store/meta/dir2-backup
93 $ mv .hg/store/meta/dir2 .hg/store/meta/dir2-backup
94 $ hg files -r . dir1
94 $ hg files -r . dir1
95 dir1/a (glob)
95 dir1/a (glob)
96 dir1/b (glob)
96 dir1/b (glob)
97 dir1/dir1/a (glob)
97 dir1/dir1/a (glob)
98 dir1/dir1/b (glob)
98 dir1/dir1/b (glob)
99 dir1/dir2/a (glob)
99 dir1/dir2/a (glob)
100 dir1/dir2/b (glob)
100 dir1/dir2/b (glob)
101
101
102 Check that status between revisions works (calls treemanifest.matches())
102 Check that status between revisions works (calls treemanifest.matches())
103 without loading all directory revlogs
103 without loading all directory revlogs
104
104
105 $ hg status --rev 'desc("add dir1")' --rev . dir1
105 $ hg status --rev 'desc("add dir1")' --rev . dir1
106 A dir1/dir1/a
106 A dir1/dir1/a
107 A dir1/dir1/b
107 A dir1/dir1/b
108 A dir1/dir2/a
108 A dir1/dir2/a
109 A dir1/dir2/b
109 A dir1/dir2/b
110 $ mv .hg/store/meta/dir2-backup .hg/store/meta/dir2
110 $ mv .hg/store/meta/dir2-backup .hg/store/meta/dir2
111
111
112 Merge creates 2-parent revision of directory revlog
112 Merge creates 2-parent revision of directory revlog
113
113
114 $ echo 5 > dir1/a
114 $ echo 5 > dir1/a
115 $ hg ci -Aqm 'modify dir1/a'
115 $ hg ci -Aqm 'modify dir1/a'
116 $ hg co '.^'
116 $ hg co '.^'
117 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
117 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
118 $ echo 6 > dir1/b
118 $ echo 6 > dir1/b
119 $ hg ci -Aqm 'modify dir1/b'
119 $ hg ci -Aqm 'modify dir1/b'
120 $ hg merge 'desc("modify dir1/a")'
120 $ hg merge 'desc("modify dir1/a")'
121 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
121 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
122 (branch merge, don't forget to commit)
122 (branch merge, don't forget to commit)
123 $ hg ci -m 'conflict-free merge involving dir1/'
123 $ hg ci -m 'conflict-free merge involving dir1/'
124 $ cat dir1/a
124 $ cat dir1/a
125 5
125 5
126 $ cat dir1/b
126 $ cat dir1/b
127 6
127 6
128 $ hg debugindex --dir dir1
128 $ hg debugindex --dir dir1
129 rev offset length delta linkrev nodeid p1 p2
129 rev offset length delta linkrev nodeid p1 p2
130 0 0 54 -1 1 8b3ffd73f901 000000000000 000000000000
130 0 0 54 -1 1 8b3ffd73f901 000000000000 000000000000
131 1 54 68 0 2 68e9d057c5a8 8b3ffd73f901 000000000000
131 1 54 68 0 2 68e9d057c5a8 8b3ffd73f901 000000000000
132 2 122 12 1 4 4698198d2624 68e9d057c5a8 000000000000
132 2 122 12 1 4 4698198d2624 68e9d057c5a8 000000000000
133 3 134 55 1 5 44844058ccce 68e9d057c5a8 000000000000
133 3 134 55 1 5 44844058ccce 68e9d057c5a8 000000000000
134 4 189 55 1 6 bf3d9b744927 68e9d057c5a8 000000000000
134 4 189 55 1 6 bf3d9b744927 68e9d057c5a8 000000000000
135 5 244 55 4 7 dde7c0af2a03 bf3d9b744927 44844058ccce
135 5 244 55 4 7 dde7c0af2a03 bf3d9b744927 44844058ccce
136
136
137 Merge keeping directory from parent 1 does not create revlog entry. (Note that
137 Merge keeping directory from parent 1 does not create revlog entry. (Note that
138 dir1's manifest does change, but only because dir1/a's filelog changes.)
138 dir1's manifest does change, but only because dir1/a's filelog changes.)
139
139
140 $ hg co 'desc("add dir2")'
140 $ hg co 'desc("add dir2")'
141 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
142 $ echo 8 > dir2/a
142 $ echo 8 > dir2/a
143 $ hg ci -m 'modify dir2/a'
143 $ hg ci -m 'modify dir2/a'
144 created new head
144 created new head
145
145
146 $ hg debugindex --dir dir2 > before
146 $ hg debugindex --dir dir2 > before
147 $ hg merge 'desc("modify dir1/a")'
147 $ hg merge 'desc("modify dir1/a")'
148 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
148 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 (branch merge, don't forget to commit)
149 (branch merge, don't forget to commit)
150 $ hg revert -r 'desc("modify dir2/a")' .
150 $ hg revert -r 'desc("modify dir2/a")' .
151 reverting dir1/a (glob)
151 reverting dir1/a (glob)
152 $ hg ci -m 'merge, keeping parent 1'
152 $ hg ci -m 'merge, keeping parent 1'
153 $ hg debugindex --dir dir2 > after
153 $ hg debugindex --dir dir2 > after
154 $ diff before after
154 $ diff before after
155 $ rm before after
155 $ rm before after
156
156
157 Merge keeping directory from parent 2 does not create revlog entry. (Note that
157 Merge keeping directory from parent 2 does not create revlog entry. (Note that
158 dir2's manifest does change, but only because dir2/a's filelog changes.)
158 dir2's manifest does change, but only because dir2/a's filelog changes.)
159
159
160 $ hg co 'desc("modify dir2/a")'
160 $ hg co 'desc("modify dir2/a")'
161 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
161 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
162 $ hg debugindex --dir dir1 > before
162 $ hg debugindex --dir dir1 > before
163 $ hg merge 'desc("modify dir1/a")'
163 $ hg merge 'desc("modify dir1/a")'
164 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
164 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
165 (branch merge, don't forget to commit)
165 (branch merge, don't forget to commit)
166 $ hg revert -r 'desc("modify dir1/a")' .
166 $ hg revert -r 'desc("modify dir1/a")' .
167 reverting dir2/a (glob)
167 reverting dir2/a (glob)
168 $ hg ci -m 'merge, keeping parent 2'
168 $ hg ci -m 'merge, keeping parent 2'
169 created new head
169 created new head
170 $ hg debugindex --dir dir1 > after
170 $ hg debugindex --dir dir1 > after
171 $ diff before after
171 $ diff before after
172 $ rm before after
172 $ rm before after
173
173
174 Create flat source repo for tests with mixed flat/tree manifests
174 Create flat source repo for tests with mixed flat/tree manifests
175
175
176 $ cd ..
176 $ cd ..
177 $ hg init repo-flat
177 $ hg init repo-flat
178 $ cd repo-flat
178 $ cd repo-flat
179
179
180 Create a few commits with flat manifest
180 Create a few commits with flat manifest
181
181
182 $ echo 0 > a
182 $ echo 0 > a
183 $ echo 0 > b
183 $ echo 0 > b
184 $ echo 0 > e
184 $ echo 0 > e
185 $ for d in dir1 dir1/dir1 dir1/dir2 dir2
185 $ for d in dir1 dir1/dir1 dir1/dir2 dir2
186 > do
186 > do
187 > mkdir $d
187 > mkdir $d
188 > echo 0 > $d/a
188 > echo 0 > $d/a
189 > echo 0 > $d/b
189 > echo 0 > $d/b
190 > done
190 > done
191 $ hg ci -Aqm initial
191 $ hg ci -Aqm initial
192
192
193 $ echo 1 > a
193 $ echo 1 > a
194 $ echo 1 > dir1/a
194 $ echo 1 > dir1/a
195 $ echo 1 > dir1/dir1/a
195 $ echo 1 > dir1/dir1/a
196 $ hg ci -Aqm 'modify on branch 1'
196 $ hg ci -Aqm 'modify on branch 1'
197
197
198 $ hg co 0
198 $ hg co 0
199 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
199 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
200 $ echo 2 > b
200 $ echo 2 > b
201 $ echo 2 > dir1/b
201 $ echo 2 > dir1/b
202 $ echo 2 > dir1/dir1/b
202 $ echo 2 > dir1/dir1/b
203 $ hg ci -Aqm 'modify on branch 2'
203 $ hg ci -Aqm 'modify on branch 2'
204
204
205 $ hg merge 1
205 $ hg merge 1
206 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
206 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
207 (branch merge, don't forget to commit)
207 (branch merge, don't forget to commit)
208 $ hg ci -m 'merge of flat manifests to new flat manifest'
208 $ hg ci -m 'merge of flat manifests to new flat manifest'
209
209
210 $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log
210 $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log
211 $ cat hg.pid >> $DAEMON_PIDS
211 $ cat hg.pid >> $DAEMON_PIDS
212
212
213 Create clone with tree manifests enabled
213 Create clone with tree manifests enabled
214
214
215 $ cd ..
215 $ cd ..
216 $ hg clone --config experimental.treemanifest=1 \
216 $ hg clone --config experimental.treemanifest=1 \
217 > http://localhost:$HGPORT repo-mixed -r 1
217 > http://localhost:$HGPORT repo-mixed -r 1
218 adding changesets
218 adding changesets
219 adding manifests
219 adding manifests
220 adding file changes
220 adding file changes
221 added 2 changesets with 14 changes to 11 files
221 added 2 changesets with 14 changes to 11 files
222 updating to branch default
222 updating to branch default
223 11 files updated, 0 files merged, 0 files removed, 0 files unresolved
223 11 files updated, 0 files merged, 0 files removed, 0 files unresolved
224 $ cd repo-mixed
224 $ cd repo-mixed
225 $ test -d .hg/store/meta
225 $ test -d .hg/store/meta
226 [1]
226 [1]
227 $ grep treemanifest .hg/requires
227 $ grep treemanifest .hg/requires
228 treemanifest
228 treemanifest
229
229
230 Should be possible to push updates from flat to tree manifest repo
230 Should be possible to push updates from flat to tree manifest repo
231
231
232 $ hg -R ../repo-flat push ssh://user@dummy/repo-mixed
232 $ hg -R ../repo-flat push ssh://user@dummy/repo-mixed
233 pushing to ssh://user@dummy/repo-mixed
233 pushing to ssh://user@dummy/repo-mixed
234 searching for changes
234 searching for changes
235 remote: adding changesets
235 remote: adding changesets
236 remote: adding manifests
236 remote: adding manifests
237 remote: adding file changes
237 remote: adding file changes
238 remote: added 2 changesets with 3 changes to 3 files
238 remote: added 2 changesets with 3 changes to 3 files
239
239
240 Commit should store revlog per directory
240 Commit should store revlog per directory
241
241
242 $ hg co 1
242 $ hg co 1
243 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
243 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
244 $ echo 3 > a
244 $ echo 3 > a
245 $ echo 3 > dir1/a
245 $ echo 3 > dir1/a
246 $ echo 3 > dir1/dir1/a
246 $ echo 3 > dir1/dir1/a
247 $ hg ci -m 'first tree'
247 $ hg ci -m 'first tree'
248 created new head
248 created new head
249 $ find .hg/store/meta | sort
249 $ find .hg/store/meta | sort
250 .hg/store/meta
250 .hg/store/meta
251 .hg/store/meta/dir1
251 .hg/store/meta/dir1
252 .hg/store/meta/dir1/00manifest.i
252 .hg/store/meta/dir1/00manifest.i
253 .hg/store/meta/dir1/dir1
253 .hg/store/meta/dir1/dir1
254 .hg/store/meta/dir1/dir1/00manifest.i
254 .hg/store/meta/dir1/dir1/00manifest.i
255 .hg/store/meta/dir1/dir2
255 .hg/store/meta/dir1/dir2
256 .hg/store/meta/dir1/dir2/00manifest.i
256 .hg/store/meta/dir1/dir2/00manifest.i
257 .hg/store/meta/dir2
257 .hg/store/meta/dir2
258 .hg/store/meta/dir2/00manifest.i
258 .hg/store/meta/dir2/00manifest.i
259
259
260 Merge of two trees
260 Merge of two trees
261
261
262 $ hg co 2
262 $ hg co 2
263 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
263 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
264 $ hg merge 1
264 $ hg merge 1
265 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
265 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
266 (branch merge, don't forget to commit)
266 (branch merge, don't forget to commit)
267 $ hg ci -m 'merge of flat manifests to new tree manifest'
267 $ hg ci -m 'merge of flat manifests to new tree manifest'
268 created new head
268 created new head
269 $ hg diff -r 3
269 $ hg diff -r 3
270
270
271 Parent of tree root manifest should be flat manifest, and two for merge
271 Parent of tree root manifest should be flat manifest, and two for merge
272
272
273 $ hg debugindex -m
273 $ hg debugindex -m
274 rev offset length delta linkrev nodeid p1 p2
274 rev offset length delta linkrev nodeid p1 p2
275 0 0 80 -1 0 40536115ed9e 000000000000 000000000000
275 0 0 80 -1 0 40536115ed9e 000000000000 000000000000
276 1 80 83 0 1 f3376063c255 40536115ed9e 000000000000
276 1 80 83 0 1 f3376063c255 40536115ed9e 000000000000
277 2 163 89 0 2 5d9b9da231a2 40536115ed9e 000000000000
277 2 163 89 0 2 5d9b9da231a2 40536115ed9e 000000000000
278 3 252 83 2 3 d17d663cbd8a 5d9b9da231a2 f3376063c255
278 3 252 83 2 3 d17d663cbd8a 5d9b9da231a2 f3376063c255
279 4 335 124 1 4 51e32a8c60ee f3376063c255 000000000000
279 4 335 124 1 4 51e32a8c60ee f3376063c255 000000000000
280 5 459 126 2 5 cc5baa78b230 5d9b9da231a2 f3376063c255
280 5 459 126 2 5 cc5baa78b230 5d9b9da231a2 f3376063c255
281
281
282
282
283 Status across flat/tree boundary should work
283 Status across flat/tree boundary should work
284
284
285 $ hg status --rev '.^' --rev .
285 $ hg status --rev '.^' --rev .
286 M a
286 M a
287 M dir1/a
287 M dir1/a
288 M dir1/dir1/a
288 M dir1/dir1/a
289
289
290
290
291 Turning off treemanifest config has no effect
291 Turning off treemanifest config has no effect
292
292
293 $ hg debugindex --dir dir1
293 $ hg debugindex --dir dir1
294 rev offset length delta linkrev nodeid p1 p2
294 rev offset length delta linkrev nodeid p1 p2
295 0 0 127 -1 4 064927a0648a 000000000000 000000000000
295 0 0 127 -1 4 064927a0648a 000000000000 000000000000
296 1 127 111 0 5 25ecb8cb8618 000000000000 000000000000
296 1 127 111 0 5 25ecb8cb8618 000000000000 000000000000
297 $ echo 2 > dir1/a
297 $ echo 2 > dir1/a
298 $ hg --config experimental.treemanifest=False ci -qm 'modify dir1/a'
298 $ hg --config experimental.treemanifest=False ci -qm 'modify dir1/a'
299 $ hg debugindex --dir dir1
299 $ hg debugindex --dir dir1
300 rev offset length delta linkrev nodeid p1 p2
300 rev offset length delta linkrev nodeid p1 p2
301 0 0 127 -1 4 064927a0648a 000000000000 000000000000
301 0 0 127 -1 4 064927a0648a 000000000000 000000000000
302 1 127 111 0 5 25ecb8cb8618 000000000000 000000000000
302 1 127 111 0 5 25ecb8cb8618 000000000000 000000000000
303 2 238 55 1 6 5b16163a30c6 25ecb8cb8618 000000000000
303 2 238 55 1 6 5b16163a30c6 25ecb8cb8618 000000000000
304
304
305 Stripping and recovering changes should work
305 Stripping and recovering changes should work
306
306
307 $ hg st --change tip
307 $ hg st --change tip
308 M dir1/a
308 M dir1/a
309 $ hg --config extensions.strip= strip tip
309 $ hg --config extensions.strip= strip tip
310 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
310 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
311 saved backup bundle to $TESTTMP/repo-mixed/.hg/strip-backup/51cfd7b1e13b-78a2f3ed-backup.hg (glob)
311 saved backup bundle to $TESTTMP/repo-mixed/.hg/strip-backup/51cfd7b1e13b-78a2f3ed-backup.hg (glob)
312 $ hg unbundle -q .hg/strip-backup/*
312 $ hg unbundle -q .hg/strip-backup/*
313 $ hg st --change tip
313 $ hg st --change tip
314 M dir1/a
314 M dir1/a
315
315
316 Shelving and unshelving should work
316 Shelving and unshelving should work
317
317
318 $ echo foo >> dir1/a
318 $ echo foo >> dir1/a
319 $ hg --config extensions.shelve= shelve
319 $ hg --config extensions.shelve= shelve
320 shelved as default
320 shelved as default
321 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
321 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
322 $ hg --config extensions.shelve= unshelve
322 $ hg --config extensions.shelve= unshelve
323 unshelving change 'default'
323 unshelving change 'default'
324 $ hg diff --nodates
324 $ hg diff --nodates
325 diff -r 708a273da119 dir1/a
325 diff -r 708a273da119 dir1/a
326 --- a/dir1/a
326 --- a/dir1/a
327 +++ b/dir1/a
327 +++ b/dir1/a
328 @@ -1,1 +1,2 @@
328 @@ -1,1 +1,2 @@
329 1
329 1
330 +foo
330 +foo
331
331
332 Pushing from treemanifest repo to an empty repo makes that a treemanifest repo
332 Pushing from treemanifest repo to an empty repo makes that a treemanifest repo
333
333
334 $ cd ..
334 $ cd ..
335 $ hg init empty-repo
335 $ hg init empty-repo
336 $ cat << EOF >> empty-repo/.hg/hgrc
336 $ cat << EOF >> empty-repo/.hg/hgrc
337 > [experimental]
337 > [experimental]
338 > changegroup3=yes
338 > changegroup3=yes
339 > EOF
339 > EOF
340 $ grep treemanifest empty-repo/.hg/requires
340 $ grep treemanifest empty-repo/.hg/requires
341 [1]
341 [1]
342 $ hg push -R repo -r 0 empty-repo
342 $ hg push -R repo -r 0 empty-repo
343 pushing to empty-repo
343 pushing to empty-repo
344 searching for changes
344 searching for changes
345 adding changesets
345 adding changesets
346 adding manifests
346 adding manifests
347 adding file changes
347 adding file changes
348 added 1 changesets with 2 changes to 2 files
348 added 1 changesets with 2 changes to 2 files
349 $ grep treemanifest empty-repo/.hg/requires
349 $ grep treemanifest empty-repo/.hg/requires
350 treemanifest
350 treemanifest
351
351
352 Pushing to an empty repo works
352 Pushing to an empty repo works
353
353
354 $ hg --config experimental.treemanifest=1 init clone
354 $ hg --config experimental.treemanifest=1 init clone
355 $ grep treemanifest clone/.hg/requires
355 $ grep treemanifest clone/.hg/requires
356 treemanifest
356 treemanifest
357 $ hg push -R repo clone
357 $ hg push -R repo clone
358 pushing to clone
358 pushing to clone
359 searching for changes
359 searching for changes
360 adding changesets
360 adding changesets
361 adding manifests
361 adding manifests
362 adding file changes
362 adding file changes
363 added 11 changesets with 15 changes to 10 files (+3 heads)
363 added 11 changesets with 15 changes to 10 files (+3 heads)
364 $ grep treemanifest clone/.hg/requires
364 $ grep treemanifest clone/.hg/requires
365 treemanifest
365 treemanifest
366
366
367 Create deeper repo with tree manifests.
367 Create deeper repo with tree manifests.
368
368
369 $ hg --config experimental.treemanifest=True init deeprepo
369 $ hg --config experimental.treemanifest=True init deeprepo
370 $ cd deeprepo
370 $ cd deeprepo
371
371
372 $ mkdir .A
372 $ mkdir .A
373 $ mkdir b
373 $ mkdir b
374 $ mkdir b/bar
374 $ mkdir b/bar
375 $ mkdir b/bar/orange
375 $ mkdir b/bar/orange
376 $ mkdir b/bar/orange/fly
376 $ mkdir b/bar/orange/fly
377 $ mkdir b/foo
377 $ mkdir b/foo
378 $ mkdir b/foo/apple
378 $ mkdir b/foo/apple
379 $ mkdir b/foo/apple/bees
379 $ mkdir b/foo/apple/bees
380
380
381 $ touch .A/one.txt
381 $ touch .A/one.txt
382 $ touch .A/two.txt
382 $ touch .A/two.txt
383 $ touch b/bar/fruits.txt
383 $ touch b/bar/fruits.txt
384 $ touch b/bar/orange/fly/gnat.py
384 $ touch b/bar/orange/fly/gnat.py
385 $ touch b/bar/orange/fly/housefly.txt
385 $ touch b/bar/orange/fly/housefly.txt
386 $ touch b/foo/apple/bees/flower.py
386 $ touch b/foo/apple/bees/flower.py
387 $ touch c.txt
387 $ touch c.txt
388 $ touch d.py
388 $ touch d.py
389
389
390 $ hg ci -Aqm 'initial'
390 $ hg ci -Aqm 'initial'
391
391
392 We'll see that visitdir works by removing some treemanifest revlogs and running
392 We'll see that visitdir works by removing some treemanifest revlogs and running
393 the files command with various parameters.
393 the files command with various parameters.
394
394
395 Test files from the root.
395 Test files from the root.
396
396
397 $ hg files -r .
397 $ hg files -r .
398 .A/one.txt (glob)
398 .A/one.txt (glob)
399 .A/two.txt (glob)
399 .A/two.txt (glob)
400 b/bar/fruits.txt (glob)
400 b/bar/fruits.txt (glob)
401 b/bar/orange/fly/gnat.py (glob)
401 b/bar/orange/fly/gnat.py (glob)
402 b/bar/orange/fly/housefly.txt (glob)
402 b/bar/orange/fly/housefly.txt (glob)
403 b/foo/apple/bees/flower.py (glob)
403 b/foo/apple/bees/flower.py (glob)
404 c.txt
404 c.txt
405 d.py
405 d.py
406
406
407 Excludes with a glob should not exclude everything from the glob's root
407 Excludes with a glob should not exclude everything from the glob's root
408
408
409 $ hg files -r . -X 'b/fo?' b
409 $ hg files -r . -X 'b/fo?' b
410 b/bar/fruits.txt (glob)
410 b/bar/fruits.txt (glob)
411 b/bar/orange/fly/gnat.py (glob)
411 b/bar/orange/fly/gnat.py (glob)
412 b/bar/orange/fly/housefly.txt (glob)
412 b/bar/orange/fly/housefly.txt (glob)
413 $ cp -r .hg/store .hg/store-copy
413 $ cp -r .hg/store .hg/store-copy
414
414
415 Test files for a subdirectory.
415 Test files for a subdirectory.
416
416
417 $ rm -r .hg/store/meta/~2e_a
417 $ rm -r .hg/store/meta/~2e_a
418 $ hg files -r . b
418 $ hg files -r . b
419 b/bar/fruits.txt (glob)
419 b/bar/fruits.txt (glob)
420 b/bar/orange/fly/gnat.py (glob)
420 b/bar/orange/fly/gnat.py (glob)
421 b/bar/orange/fly/housefly.txt (glob)
421 b/bar/orange/fly/housefly.txt (glob)
422 b/foo/apple/bees/flower.py (glob)
422 b/foo/apple/bees/flower.py (glob)
423 $ cp -r .hg/store-copy/* .hg/store
423 $ cp -r .hg/store-copy/* .hg/store
424
424
425 Test files with just includes and excludes.
425 Test files with just includes and excludes.
426
426
427 $ rm -r .hg/store/meta/~2e_a
427 $ rm -r .hg/store/meta/~2e_a
428 $ rm -r .hg/store/meta/b/bar/orange/fly
428 $ rm -r .hg/store/meta/b/bar/orange/fly
429 $ rm -r .hg/store/meta/b/foo/apple/bees
429 $ rm -r .hg/store/meta/b/foo/apple/bees
430 $ hg files -r . -I path:b/bar -X path:b/bar/orange/fly -I path:b/foo -X path:b/foo/apple/bees
430 $ hg files -r . -I path:b/bar -X path:b/bar/orange/fly -I path:b/foo -X path:b/foo/apple/bees
431 b/bar/fruits.txt (glob)
431 b/bar/fruits.txt (glob)
432 $ cp -r .hg/store-copy/* .hg/store
432 $ cp -r .hg/store-copy/* .hg/store
433
433
434 Test files for a subdirectory, excluding a directory within it.
434 Test files for a subdirectory, excluding a directory within it.
435
435
436 $ rm -r .hg/store/meta/~2e_a
436 $ rm -r .hg/store/meta/~2e_a
437 $ rm -r .hg/store/meta/b/foo
437 $ rm -r .hg/store/meta/b/foo
438 $ hg files -r . -X path:b/foo b
438 $ hg files -r . -X path:b/foo b
439 b/bar/fruits.txt (glob)
439 b/bar/fruits.txt (glob)
440 b/bar/orange/fly/gnat.py (glob)
440 b/bar/orange/fly/gnat.py (glob)
441 b/bar/orange/fly/housefly.txt (glob)
441 b/bar/orange/fly/housefly.txt (glob)
442 $ cp -r .hg/store-copy/* .hg/store
442 $ cp -r .hg/store-copy/* .hg/store
443
443
444 Test files for a sub directory, including only a directory within it, and
444 Test files for a sub directory, including only a directory within it, and
445 including an unrelated directory.
445 including an unrelated directory.
446
446
447 $ rm -r .hg/store/meta/~2e_a
447 $ rm -r .hg/store/meta/~2e_a
448 $ rm -r .hg/store/meta/b/foo
448 $ rm -r .hg/store/meta/b/foo
449 $ hg files -r . -I path:b/bar/orange -I path:a b
449 $ hg files -r . -I path:b/bar/orange -I path:a b
450 b/bar/orange/fly/gnat.py (glob)
450 b/bar/orange/fly/gnat.py (glob)
451 b/bar/orange/fly/housefly.txt (glob)
451 b/bar/orange/fly/housefly.txt (glob)
452 $ cp -r .hg/store-copy/* .hg/store
452 $ cp -r .hg/store-copy/* .hg/store
453
453
454 Test files for a pattern, including a directory, and excluding a directory
454 Test files for a pattern, including a directory, and excluding a directory
455 within that.
455 within that.
456
456
457 $ rm -r .hg/store/meta/~2e_a
457 $ rm -r .hg/store/meta/~2e_a
458 $ rm -r .hg/store/meta/b/foo
458 $ rm -r .hg/store/meta/b/foo
459 $ rm -r .hg/store/meta/b/bar/orange
459 $ rm -r .hg/store/meta/b/bar/orange
460 $ hg files -r . glob:**.txt -I path:b/bar -X path:b/bar/orange
460 $ hg files -r . glob:**.txt -I path:b/bar -X path:b/bar/orange
461 b/bar/fruits.txt (glob)
461 b/bar/fruits.txt (glob)
462 $ cp -r .hg/store-copy/* .hg/store
462 $ cp -r .hg/store-copy/* .hg/store
463
463
464 Add some more changes to the deep repo
464 Add some more changes to the deep repo
465 $ echo narf >> b/bar/fruits.txt
465 $ echo narf >> b/bar/fruits.txt
466 $ hg ci -m narf
466 $ hg ci -m narf
467 $ echo troz >> b/bar/orange/fly/gnat.py
467 $ echo troz >> b/bar/orange/fly/gnat.py
468 $ hg ci -m troz
468 $ hg ci -m troz
469
469
470 Verify works
470 Verify works
471 $ hg verify
471 $ hg verify
472 checking changesets
472 checking changesets
473 checking manifests
473 checking manifests
474 checking directory manifests
474 checking directory manifests
475 crosschecking files in changesets and manifests
475 crosschecking files in changesets and manifests
476 checking files
476 checking files
477 8 files, 3 changesets, 10 total revisions
477 8 files, 3 changesets, 10 total revisions
478
478
479 Dirlogs are included in fncache
479 Dirlogs are included in fncache
480 $ grep meta/.A/00manifest.i .hg/store/fncache
480 $ grep meta/.A/00manifest.i .hg/store/fncache
481 meta/.A/00manifest.i
481 meta/.A/00manifest.i
482
482
483 Rebuilt fncache includes dirlogs
483 Rebuilt fncache includes dirlogs
484 $ rm .hg/store/fncache
484 $ rm .hg/store/fncache
485 $ hg debugrebuildfncache
485 $ hg debugrebuildfncache
486 adding data/.A/one.txt.i
486 adding data/.A/one.txt.i
487 adding data/.A/two.txt.i
487 adding data/.A/two.txt.i
488 adding data/b/bar/fruits.txt.i
488 adding data/b/bar/fruits.txt.i
489 adding data/b/bar/orange/fly/gnat.py.i
489 adding data/b/bar/orange/fly/gnat.py.i
490 adding data/b/bar/orange/fly/housefly.txt.i
490 adding data/b/bar/orange/fly/housefly.txt.i
491 adding data/b/foo/apple/bees/flower.py.i
491 adding data/b/foo/apple/bees/flower.py.i
492 adding data/c.txt.i
492 adding data/c.txt.i
493 adding data/d.py.i
493 adding data/d.py.i
494 adding meta/.A/00manifest.i
494 adding meta/.A/00manifest.i
495 adding meta/b/00manifest.i
495 adding meta/b/00manifest.i
496 adding meta/b/bar/00manifest.i
496 adding meta/b/bar/00manifest.i
497 adding meta/b/bar/orange/00manifest.i
497 adding meta/b/bar/orange/00manifest.i
498 adding meta/b/bar/orange/fly/00manifest.i
498 adding meta/b/bar/orange/fly/00manifest.i
499 adding meta/b/foo/00manifest.i
499 adding meta/b/foo/00manifest.i
500 adding meta/b/foo/apple/00manifest.i
500 adding meta/b/foo/apple/00manifest.i
501 adding meta/b/foo/apple/bees/00manifest.i
501 adding meta/b/foo/apple/bees/00manifest.i
502 16 items added, 0 removed from fncache
502 16 items added, 0 removed from fncache
503
503
504 Finish first server
504 Finish first server
505 $ killdaemons.py
505 $ killdaemons.py
506
506
507 Back up the recently added revlogs
507 Back up the recently added revlogs
508 $ cp -r .hg/store .hg/store-newcopy
508 $ cp -r .hg/store .hg/store-newcopy
509
509
510 Verify reports missing dirlog
510 Verify reports missing dirlog
511 $ rm .hg/store/meta/b/00manifest.*
511 $ rm .hg/store/meta/b/00manifest.*
512 $ hg verify
512 $ hg verify
513 checking changesets
513 checking changesets
514 checking manifests
514 checking manifests
515 checking directory manifests
515 checking directory manifests
516 0: empty or missing b/
516 0: empty or missing b/
517 b/@0: parent-directory manifest refers to unknown revision 67688a370455
517 b/@0: parent-directory manifest refers to unknown revision 67688a370455
518 b/@1: parent-directory manifest refers to unknown revision f38e85d334c5
518 b/@1: parent-directory manifest refers to unknown revision f38e85d334c5
519 b/@2: parent-directory manifest refers to unknown revision 99c9792fd4b0
519 b/@2: parent-directory manifest refers to unknown revision 99c9792fd4b0
520 warning: orphan revlog 'meta/b/bar/00manifest.i'
521 warning: orphan revlog 'meta/b/bar/orange/00manifest.i'
522 warning: orphan revlog 'meta/b/bar/orange/fly/00manifest.i'
523 warning: orphan revlog 'meta/b/foo/00manifest.i'
524 warning: orphan revlog 'meta/b/foo/apple/00manifest.i'
525 warning: orphan revlog 'meta/b/foo/apple/bees/00manifest.i'
520 crosschecking files in changesets and manifests
526 crosschecking files in changesets and manifests
521 b/bar/fruits.txt@0: in changeset but not in manifest
527 b/bar/fruits.txt@0: in changeset but not in manifest
522 b/bar/orange/fly/gnat.py@0: in changeset but not in manifest
528 b/bar/orange/fly/gnat.py@0: in changeset but not in manifest
523 b/bar/orange/fly/housefly.txt@0: in changeset but not in manifest
529 b/bar/orange/fly/housefly.txt@0: in changeset but not in manifest
524 b/foo/apple/bees/flower.py@0: in changeset but not in manifest
530 b/foo/apple/bees/flower.py@0: in changeset but not in manifest
525 checking files
531 checking files
526 8 files, 3 changesets, 10 total revisions
532 8 files, 3 changesets, 10 total revisions
533 6 warnings encountered!
527 8 integrity errors encountered!
534 8 integrity errors encountered!
528 (first damaged changeset appears to be 0)
535 (first damaged changeset appears to be 0)
529 [1]
536 [1]
530 $ cp -rT .hg/store-newcopy .hg/store
537 $ cp -rT .hg/store-newcopy .hg/store
531
538
532 Verify reports missing dirlog entry
539 Verify reports missing dirlog entry
533 $ mv -f .hg/store-copy/meta/b/00manifest.* .hg/store/meta/b/
540 $ mv -f .hg/store-copy/meta/b/00manifest.* .hg/store/meta/b/
534 $ hg verify
541 $ hg verify
535 checking changesets
542 checking changesets
536 checking manifests
543 checking manifests
537 checking directory manifests
544 checking directory manifests
538 b/@1: parent-directory manifest refers to unknown revision f38e85d334c5
545 b/@1: parent-directory manifest refers to unknown revision f38e85d334c5
539 b/@2: parent-directory manifest refers to unknown revision 99c9792fd4b0
546 b/@2: parent-directory manifest refers to unknown revision 99c9792fd4b0
540 b/bar/@?: rev 1 points to unexpected changeset 1
547 b/bar/@?: rev 1 points to unexpected changeset 1
541 b/bar/@?: 5e03c4ee5e4a not in parent-directory manifest
548 b/bar/@?: 5e03c4ee5e4a not in parent-directory manifest
542 b/bar/@?: rev 2 points to unexpected changeset 2
549 b/bar/@?: rev 2 points to unexpected changeset 2
543 b/bar/@?: 1b16940d66d6 not in parent-directory manifest
550 b/bar/@?: 1b16940d66d6 not in parent-directory manifest
544 b/bar/orange/@?: rev 1 points to unexpected changeset 2
551 b/bar/orange/@?: rev 1 points to unexpected changeset 2
545 (expected None)
552 (expected None)
546 b/bar/orange/fly/@?: rev 1 points to unexpected changeset 2
553 b/bar/orange/fly/@?: rev 1 points to unexpected changeset 2
547 (expected None)
554 (expected None)
548 crosschecking files in changesets and manifests
555 crosschecking files in changesets and manifests
549 checking files
556 checking files
550 8 files, 3 changesets, 10 total revisions
557 8 files, 3 changesets, 10 total revisions
551 2 warnings encountered!
558 2 warnings encountered!
552 8 integrity errors encountered!
559 8 integrity errors encountered!
553 (first damaged changeset appears to be 1)
560 (first damaged changeset appears to be 1)
554 [1]
561 [1]
555 $ cp -rT .hg/store-newcopy .hg/store
562 $ cp -rT .hg/store-newcopy .hg/store
556
563
557 Test cloning a treemanifest repo over http.
564 Test cloning a treemanifest repo over http.
558 $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log
565 $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log
559 $ cat hg.pid >> $DAEMON_PIDS
566 $ cat hg.pid >> $DAEMON_PIDS
560 $ cd ..
567 $ cd ..
561 We can clone even with the knob turned off and we'll get a treemanifest repo.
568 We can clone even with the knob turned off and we'll get a treemanifest repo.
562 $ hg clone --config experimental.treemanifest=False \
569 $ hg clone --config experimental.treemanifest=False \
563 > --config experimental.changegroup3=True \
570 > --config experimental.changegroup3=True \
564 > http://localhost:$HGPORT deepclone
571 > http://localhost:$HGPORT deepclone
565 requesting all changes
572 requesting all changes
566 adding changesets
573 adding changesets
567 adding manifests
574 adding manifests
568 adding file changes
575 adding file changes
569 added 3 changesets with 10 changes to 8 files
576 added 3 changesets with 10 changes to 8 files
570 updating to branch default
577 updating to branch default
571 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
578 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
572 No server errors.
579 No server errors.
573 $ cat deeprepo/errors.log
580 $ cat deeprepo/errors.log
574 requires got updated to include treemanifest
581 requires got updated to include treemanifest
575 $ cat deepclone/.hg/requires | grep treemanifest
582 $ cat deepclone/.hg/requires | grep treemanifest
576 treemanifest
583 treemanifest
577 Tree manifest revlogs exist.
584 Tree manifest revlogs exist.
578 $ find deepclone/.hg/store/meta | sort
585 $ find deepclone/.hg/store/meta | sort
579 deepclone/.hg/store/meta
586 deepclone/.hg/store/meta
580 deepclone/.hg/store/meta/b
587 deepclone/.hg/store/meta/b
581 deepclone/.hg/store/meta/b/00manifest.i
588 deepclone/.hg/store/meta/b/00manifest.i
582 deepclone/.hg/store/meta/b/bar
589 deepclone/.hg/store/meta/b/bar
583 deepclone/.hg/store/meta/b/bar/00manifest.i
590 deepclone/.hg/store/meta/b/bar/00manifest.i
584 deepclone/.hg/store/meta/b/bar/orange
591 deepclone/.hg/store/meta/b/bar/orange
585 deepclone/.hg/store/meta/b/bar/orange/00manifest.i
592 deepclone/.hg/store/meta/b/bar/orange/00manifest.i
586 deepclone/.hg/store/meta/b/bar/orange/fly
593 deepclone/.hg/store/meta/b/bar/orange/fly
587 deepclone/.hg/store/meta/b/bar/orange/fly/00manifest.i
594 deepclone/.hg/store/meta/b/bar/orange/fly/00manifest.i
588 deepclone/.hg/store/meta/b/foo
595 deepclone/.hg/store/meta/b/foo
589 deepclone/.hg/store/meta/b/foo/00manifest.i
596 deepclone/.hg/store/meta/b/foo/00manifest.i
590 deepclone/.hg/store/meta/b/foo/apple
597 deepclone/.hg/store/meta/b/foo/apple
591 deepclone/.hg/store/meta/b/foo/apple/00manifest.i
598 deepclone/.hg/store/meta/b/foo/apple/00manifest.i
592 deepclone/.hg/store/meta/b/foo/apple/bees
599 deepclone/.hg/store/meta/b/foo/apple/bees
593 deepclone/.hg/store/meta/b/foo/apple/bees/00manifest.i
600 deepclone/.hg/store/meta/b/foo/apple/bees/00manifest.i
594 deepclone/.hg/store/meta/~2e_a
601 deepclone/.hg/store/meta/~2e_a
595 deepclone/.hg/store/meta/~2e_a/00manifest.i
602 deepclone/.hg/store/meta/~2e_a/00manifest.i
596 Verify passes.
603 Verify passes.
597 $ cd deepclone
604 $ cd deepclone
598 $ hg verify
605 $ hg verify
599 checking changesets
606 checking changesets
600 checking manifests
607 checking manifests
601 checking directory manifests
608 checking directory manifests
602 crosschecking files in changesets and manifests
609 crosschecking files in changesets and manifests
603 checking files
610 checking files
604 8 files, 3 changesets, 10 total revisions
611 8 files, 3 changesets, 10 total revisions
605 $ cd ..
612 $ cd ..
606
613
607 Create clones using old repo formats to use in later tests
614 Create clones using old repo formats to use in later tests
608 $ hg clone --config format.usestore=False \
615 $ hg clone --config format.usestore=False \
609 > --config experimental.changegroup3=True \
616 > --config experimental.changegroup3=True \
610 > http://localhost:$HGPORT deeprepo-basicstore
617 > http://localhost:$HGPORT deeprepo-basicstore
611 requesting all changes
618 requesting all changes
612 adding changesets
619 adding changesets
613 adding manifests
620 adding manifests
614 adding file changes
621 adding file changes
615 added 3 changesets with 10 changes to 8 files
622 added 3 changesets with 10 changes to 8 files
616 updating to branch default
623 updating to branch default
617 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
624 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
618 $ cd deeprepo-basicstore
625 $ cd deeprepo-basicstore
619 $ grep store .hg/requires
626 $ grep store .hg/requires
620 [1]
627 [1]
621 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --errorlog=errors.log
628 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --errorlog=errors.log
622 $ cat hg.pid >> $DAEMON_PIDS
629 $ cat hg.pid >> $DAEMON_PIDS
623 $ cd ..
630 $ cd ..
624 $ hg clone --config format.usefncache=False \
631 $ hg clone --config format.usefncache=False \
625 > --config experimental.changegroup3=True \
632 > --config experimental.changegroup3=True \
626 > http://localhost:$HGPORT deeprepo-encodedstore
633 > http://localhost:$HGPORT deeprepo-encodedstore
627 requesting all changes
634 requesting all changes
628 adding changesets
635 adding changesets
629 adding manifests
636 adding manifests
630 adding file changes
637 adding file changes
631 added 3 changesets with 10 changes to 8 files
638 added 3 changesets with 10 changes to 8 files
632 updating to branch default
639 updating to branch default
633 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
640 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
634 $ cd deeprepo-encodedstore
641 $ cd deeprepo-encodedstore
635 $ grep fncache .hg/requires
642 $ grep fncache .hg/requires
636 [1]
643 [1]
637 $ hg serve -p $HGPORT2 -d --pid-file=hg.pid --errorlog=errors.log
644 $ hg serve -p $HGPORT2 -d --pid-file=hg.pid --errorlog=errors.log
638 $ cat hg.pid >> $DAEMON_PIDS
645 $ cat hg.pid >> $DAEMON_PIDS
639 $ cd ..
646 $ cd ..
640
647
641 Local clone with basicstore
648 Local clone with basicstore
642 $ hg clone -U deeprepo-basicstore local-clone-basicstore
649 $ hg clone -U deeprepo-basicstore local-clone-basicstore
643 $ hg -R local-clone-basicstore verify
650 $ hg -R local-clone-basicstore verify
644 checking changesets
651 checking changesets
645 checking manifests
652 checking manifests
646 checking directory manifests
653 checking directory manifests
647 crosschecking files in changesets and manifests
654 crosschecking files in changesets and manifests
648 checking files
655 checking files
649 8 files, 3 changesets, 10 total revisions
656 8 files, 3 changesets, 10 total revisions
650
657
651 Local clone with encodedstore
658 Local clone with encodedstore
652 $ hg clone -U deeprepo-encodedstore local-clone-encodedstore
659 $ hg clone -U deeprepo-encodedstore local-clone-encodedstore
653 $ hg -R local-clone-encodedstore verify
660 $ hg -R local-clone-encodedstore verify
654 checking changesets
661 checking changesets
655 checking manifests
662 checking manifests
656 checking directory manifests
663 checking directory manifests
657 crosschecking files in changesets and manifests
664 crosschecking files in changesets and manifests
658 checking files
665 checking files
659 8 files, 3 changesets, 10 total revisions
666 8 files, 3 changesets, 10 total revisions
660
667
661 Local clone with fncachestore
668 Local clone with fncachestore
662 $ hg clone -U deeprepo local-clone-fncachestore
669 $ hg clone -U deeprepo local-clone-fncachestore
663 $ hg -R local-clone-fncachestore verify
670 $ hg -R local-clone-fncachestore verify
664 checking changesets
671 checking changesets
665 checking manifests
672 checking manifests
666 checking directory manifests
673 checking directory manifests
667 crosschecking files in changesets and manifests
674 crosschecking files in changesets and manifests
668 checking files
675 checking files
669 8 files, 3 changesets, 10 total revisions
676 8 files, 3 changesets, 10 total revisions
670
677
671 Stream clone with basicstore
678 Stream clone with basicstore
672 $ hg clone --config experimental.changegroup3=True --uncompressed -U \
679 $ hg clone --config experimental.changegroup3=True --uncompressed -U \
673 > http://localhost:$HGPORT1 stream-clone-basicstore
680 > http://localhost:$HGPORT1 stream-clone-basicstore
674 streaming all changes
681 streaming all changes
675 18 files to transfer, * of data (glob)
682 18 files to transfer, * of data (glob)
676 transferred * in * seconds (*) (glob)
683 transferred * in * seconds (*) (glob)
677 searching for changes
684 searching for changes
678 no changes found
685 no changes found
679 $ hg -R stream-clone-basicstore verify
686 $ hg -R stream-clone-basicstore verify
680 checking changesets
687 checking changesets
681 checking manifests
688 checking manifests
682 checking directory manifests
689 checking directory manifests
683 crosschecking files in changesets and manifests
690 crosschecking files in changesets and manifests
684 checking files
691 checking files
685 8 files, 3 changesets, 10 total revisions
692 8 files, 3 changesets, 10 total revisions
686
693
687 Stream clone with encodedstore
694 Stream clone with encodedstore
688 $ hg clone --config experimental.changegroup3=True --uncompressed -U \
695 $ hg clone --config experimental.changegroup3=True --uncompressed -U \
689 > http://localhost:$HGPORT2 stream-clone-encodedstore
696 > http://localhost:$HGPORT2 stream-clone-encodedstore
690 streaming all changes
697 streaming all changes
691 18 files to transfer, * of data (glob)
698 18 files to transfer, * of data (glob)
692 transferred * in * seconds (*) (glob)
699 transferred * in * seconds (*) (glob)
693 searching for changes
700 searching for changes
694 no changes found
701 no changes found
695 $ hg -R stream-clone-encodedstore verify
702 $ hg -R stream-clone-encodedstore verify
696 checking changesets
703 checking changesets
697 checking manifests
704 checking manifests
698 checking directory manifests
705 checking directory manifests
699 crosschecking files in changesets and manifests
706 crosschecking files in changesets and manifests
700 checking files
707 checking files
701 8 files, 3 changesets, 10 total revisions
708 8 files, 3 changesets, 10 total revisions
702
709
703 Stream clone with fncachestore
710 Stream clone with fncachestore
704 $ hg clone --config experimental.changegroup3=True --uncompressed -U \
711 $ hg clone --config experimental.changegroup3=True --uncompressed -U \
705 > http://localhost:$HGPORT stream-clone-fncachestore
712 > http://localhost:$HGPORT stream-clone-fncachestore
706 streaming all changes
713 streaming all changes
707 18 files to transfer, * of data (glob)
714 18 files to transfer, * of data (glob)
708 transferred * in * seconds (*) (glob)
715 transferred * in * seconds (*) (glob)
709 searching for changes
716 searching for changes
710 no changes found
717 no changes found
711 $ hg -R stream-clone-fncachestore verify
718 $ hg -R stream-clone-fncachestore verify
712 checking changesets
719 checking changesets
713 checking manifests
720 checking manifests
714 checking directory manifests
721 checking directory manifests
715 crosschecking files in changesets and manifests
722 crosschecking files in changesets and manifests
716 checking files
723 checking files
717 8 files, 3 changesets, 10 total revisions
724 8 files, 3 changesets, 10 total revisions
718
725
719 Packed bundle
726 Packed bundle
720 $ hg -R deeprepo debugcreatestreamclonebundle repo-packed.hg
727 $ hg -R deeprepo debugcreatestreamclonebundle repo-packed.hg
721 writing 3349 bytes for 18 files
728 writing 3349 bytes for 18 files
722 bundle requirements: generaldelta, revlogv1, treemanifest
729 bundle requirements: generaldelta, revlogv1, treemanifest
723 $ hg debugbundle --spec repo-packed.hg
730 $ hg debugbundle --spec repo-packed.hg
724 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1%2Ctreemanifest
731 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1%2Ctreemanifest
General Comments 0
You need to be logged in to leave comments. Login now