##// END OF EJS Templates
changegroup: remove reordering control (BC)...
Gregory Szorc -
r39897:db5501d9 default
parent child Browse files
Show More
@@ -1,1411 +1,1389 b''
1 # changegroup.py - Mercurial changegroup manipulation functions
1 # changegroup.py - Mercurial changegroup manipulation functions
2 #
2 #
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006 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 import struct
11 import struct
12 import weakref
12 import weakref
13
13
14 from .i18n import _
14 from .i18n import _
15 from .node import (
15 from .node import (
16 hex,
16 hex,
17 nullid,
17 nullid,
18 nullrev,
18 nullrev,
19 short,
19 short,
20 )
20 )
21
21
22 from .thirdparty import (
22 from .thirdparty import (
23 attr,
23 attr,
24 )
24 )
25
25
26 from . import (
26 from . import (
27 dagop,
27 dagop,
28 error,
28 error,
29 match as matchmod,
29 match as matchmod,
30 mdiff,
30 mdiff,
31 phases,
31 phases,
32 pycompat,
32 pycompat,
33 repository,
33 repository,
34 util,
34 util,
35 )
35 )
36
36
37 from .utils import (
37 from .utils import (
38 interfaceutil,
38 interfaceutil,
39 stringutil,
40 )
39 )
41
40
42 _CHANGEGROUPV1_DELTA_HEADER = struct.Struct("20s20s20s20s")
41 _CHANGEGROUPV1_DELTA_HEADER = struct.Struct("20s20s20s20s")
43 _CHANGEGROUPV2_DELTA_HEADER = struct.Struct("20s20s20s20s20s")
42 _CHANGEGROUPV2_DELTA_HEADER = struct.Struct("20s20s20s20s20s")
44 _CHANGEGROUPV3_DELTA_HEADER = struct.Struct(">20s20s20s20s20sH")
43 _CHANGEGROUPV3_DELTA_HEADER = struct.Struct(">20s20s20s20s20sH")
45
44
46 LFS_REQUIREMENT = 'lfs'
45 LFS_REQUIREMENT = 'lfs'
47
46
48 readexactly = util.readexactly
47 readexactly = util.readexactly
49
48
50 def getchunk(stream):
49 def getchunk(stream):
51 """return the next chunk from stream as a string"""
50 """return the next chunk from stream as a string"""
52 d = readexactly(stream, 4)
51 d = readexactly(stream, 4)
53 l = struct.unpack(">l", d)[0]
52 l = struct.unpack(">l", d)[0]
54 if l <= 4:
53 if l <= 4:
55 if l:
54 if l:
56 raise error.Abort(_("invalid chunk length %d") % l)
55 raise error.Abort(_("invalid chunk length %d") % l)
57 return ""
56 return ""
58 return readexactly(stream, l - 4)
57 return readexactly(stream, l - 4)
59
58
60 def chunkheader(length):
59 def chunkheader(length):
61 """return a changegroup chunk header (string)"""
60 """return a changegroup chunk header (string)"""
62 return struct.pack(">l", length + 4)
61 return struct.pack(">l", length + 4)
63
62
64 def closechunk():
63 def closechunk():
65 """return a changegroup chunk header (string) for a zero-length chunk"""
64 """return a changegroup chunk header (string) for a zero-length chunk"""
66 return struct.pack(">l", 0)
65 return struct.pack(">l", 0)
67
66
68 def _fileheader(path):
67 def _fileheader(path):
69 """Obtain a changegroup chunk header for a named path."""
68 """Obtain a changegroup chunk header for a named path."""
70 return chunkheader(len(path)) + path
69 return chunkheader(len(path)) + path
71
70
72 def writechunks(ui, chunks, filename, vfs=None):
71 def writechunks(ui, chunks, filename, vfs=None):
73 """Write chunks to a file and return its filename.
72 """Write chunks to a file and return its filename.
74
73
75 The stream is assumed to be a bundle file.
74 The stream is assumed to be a bundle file.
76 Existing files will not be overwritten.
75 Existing files will not be overwritten.
77 If no filename is specified, a temporary file is created.
76 If no filename is specified, a temporary file is created.
78 """
77 """
79 fh = None
78 fh = None
80 cleanup = None
79 cleanup = None
81 try:
80 try:
82 if filename:
81 if filename:
83 if vfs:
82 if vfs:
84 fh = vfs.open(filename, "wb")
83 fh = vfs.open(filename, "wb")
85 else:
84 else:
86 # Increase default buffer size because default is usually
85 # Increase default buffer size because default is usually
87 # small (4k is common on Linux).
86 # small (4k is common on Linux).
88 fh = open(filename, "wb", 131072)
87 fh = open(filename, "wb", 131072)
89 else:
88 else:
90 fd, filename = pycompat.mkstemp(prefix="hg-bundle-", suffix=".hg")
89 fd, filename = pycompat.mkstemp(prefix="hg-bundle-", suffix=".hg")
91 fh = os.fdopen(fd, r"wb")
90 fh = os.fdopen(fd, r"wb")
92 cleanup = filename
91 cleanup = filename
93 for c in chunks:
92 for c in chunks:
94 fh.write(c)
93 fh.write(c)
95 cleanup = None
94 cleanup = None
96 return filename
95 return filename
97 finally:
96 finally:
98 if fh is not None:
97 if fh is not None:
99 fh.close()
98 fh.close()
100 if cleanup is not None:
99 if cleanup is not None:
101 if filename and vfs:
100 if filename and vfs:
102 vfs.unlink(cleanup)
101 vfs.unlink(cleanup)
103 else:
102 else:
104 os.unlink(cleanup)
103 os.unlink(cleanup)
105
104
106 class cg1unpacker(object):
105 class cg1unpacker(object):
107 """Unpacker for cg1 changegroup streams.
106 """Unpacker for cg1 changegroup streams.
108
107
109 A changegroup unpacker handles the framing of the revision data in
108 A changegroup unpacker handles the framing of the revision data in
110 the wire format. Most consumers will want to use the apply()
109 the wire format. Most consumers will want to use the apply()
111 method to add the changes from the changegroup to a repository.
110 method to add the changes from the changegroup to a repository.
112
111
113 If you're forwarding a changegroup unmodified to another consumer,
112 If you're forwarding a changegroup unmodified to another consumer,
114 use getchunks(), which returns an iterator of changegroup
113 use getchunks(), which returns an iterator of changegroup
115 chunks. This is mostly useful for cases where you need to know the
114 chunks. This is mostly useful for cases where you need to know the
116 data stream has ended by observing the end of the changegroup.
115 data stream has ended by observing the end of the changegroup.
117
116
118 deltachunk() is useful only if you're applying delta data. Most
117 deltachunk() is useful only if you're applying delta data. Most
119 consumers should prefer apply() instead.
118 consumers should prefer apply() instead.
120
119
121 A few other public methods exist. Those are used only for
120 A few other public methods exist. Those are used only for
122 bundlerepo and some debug commands - their use is discouraged.
121 bundlerepo and some debug commands - their use is discouraged.
123 """
122 """
124 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
123 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
125 deltaheadersize = deltaheader.size
124 deltaheadersize = deltaheader.size
126 version = '01'
125 version = '01'
127 _grouplistcount = 1 # One list of files after the manifests
126 _grouplistcount = 1 # One list of files after the manifests
128
127
129 def __init__(self, fh, alg, extras=None):
128 def __init__(self, fh, alg, extras=None):
130 if alg is None:
129 if alg is None:
131 alg = 'UN'
130 alg = 'UN'
132 if alg not in util.compengines.supportedbundletypes:
131 if alg not in util.compengines.supportedbundletypes:
133 raise error.Abort(_('unknown stream compression type: %s')
132 raise error.Abort(_('unknown stream compression type: %s')
134 % alg)
133 % alg)
135 if alg == 'BZ':
134 if alg == 'BZ':
136 alg = '_truncatedBZ'
135 alg = '_truncatedBZ'
137
136
138 compengine = util.compengines.forbundletype(alg)
137 compengine = util.compengines.forbundletype(alg)
139 self._stream = compengine.decompressorreader(fh)
138 self._stream = compengine.decompressorreader(fh)
140 self._type = alg
139 self._type = alg
141 self.extras = extras or {}
140 self.extras = extras or {}
142 self.callback = None
141 self.callback = None
143
142
144 # These methods (compressed, read, seek, tell) all appear to only
143 # These methods (compressed, read, seek, tell) all appear to only
145 # be used by bundlerepo, but it's a little hard to tell.
144 # be used by bundlerepo, but it's a little hard to tell.
146 def compressed(self):
145 def compressed(self):
147 return self._type is not None and self._type != 'UN'
146 return self._type is not None and self._type != 'UN'
148 def read(self, l):
147 def read(self, l):
149 return self._stream.read(l)
148 return self._stream.read(l)
150 def seek(self, pos):
149 def seek(self, pos):
151 return self._stream.seek(pos)
150 return self._stream.seek(pos)
152 def tell(self):
151 def tell(self):
153 return self._stream.tell()
152 return self._stream.tell()
154 def close(self):
153 def close(self):
155 return self._stream.close()
154 return self._stream.close()
156
155
157 def _chunklength(self):
156 def _chunklength(self):
158 d = readexactly(self._stream, 4)
157 d = readexactly(self._stream, 4)
159 l = struct.unpack(">l", d)[0]
158 l = struct.unpack(">l", d)[0]
160 if l <= 4:
159 if l <= 4:
161 if l:
160 if l:
162 raise error.Abort(_("invalid chunk length %d") % l)
161 raise error.Abort(_("invalid chunk length %d") % l)
163 return 0
162 return 0
164 if self.callback:
163 if self.callback:
165 self.callback()
164 self.callback()
166 return l - 4
165 return l - 4
167
166
168 def changelogheader(self):
167 def changelogheader(self):
169 """v10 does not have a changelog header chunk"""
168 """v10 does not have a changelog header chunk"""
170 return {}
169 return {}
171
170
172 def manifestheader(self):
171 def manifestheader(self):
173 """v10 does not have a manifest header chunk"""
172 """v10 does not have a manifest header chunk"""
174 return {}
173 return {}
175
174
176 def filelogheader(self):
175 def filelogheader(self):
177 """return the header of the filelogs chunk, v10 only has the filename"""
176 """return the header of the filelogs chunk, v10 only has the filename"""
178 l = self._chunklength()
177 l = self._chunklength()
179 if not l:
178 if not l:
180 return {}
179 return {}
181 fname = readexactly(self._stream, l)
180 fname = readexactly(self._stream, l)
182 return {'filename': fname}
181 return {'filename': fname}
183
182
184 def _deltaheader(self, headertuple, prevnode):
183 def _deltaheader(self, headertuple, prevnode):
185 node, p1, p2, cs = headertuple
184 node, p1, p2, cs = headertuple
186 if prevnode is None:
185 if prevnode is None:
187 deltabase = p1
186 deltabase = p1
188 else:
187 else:
189 deltabase = prevnode
188 deltabase = prevnode
190 flags = 0
189 flags = 0
191 return node, p1, p2, deltabase, cs, flags
190 return node, p1, p2, deltabase, cs, flags
192
191
193 def deltachunk(self, prevnode):
192 def deltachunk(self, prevnode):
194 l = self._chunklength()
193 l = self._chunklength()
195 if not l:
194 if not l:
196 return {}
195 return {}
197 headerdata = readexactly(self._stream, self.deltaheadersize)
196 headerdata = readexactly(self._stream, self.deltaheadersize)
198 header = self.deltaheader.unpack(headerdata)
197 header = self.deltaheader.unpack(headerdata)
199 delta = readexactly(self._stream, l - self.deltaheadersize)
198 delta = readexactly(self._stream, l - self.deltaheadersize)
200 node, p1, p2, deltabase, cs, flags = self._deltaheader(header, prevnode)
199 node, p1, p2, deltabase, cs, flags = self._deltaheader(header, prevnode)
201 return (node, p1, p2, cs, deltabase, delta, flags)
200 return (node, p1, p2, cs, deltabase, delta, flags)
202
201
203 def getchunks(self):
202 def getchunks(self):
204 """returns all the chunks contains in the bundle
203 """returns all the chunks contains in the bundle
205
204
206 Used when you need to forward the binary stream to a file or another
205 Used when you need to forward the binary stream to a file or another
207 network API. To do so, it parse the changegroup data, otherwise it will
206 network API. To do so, it parse the changegroup data, otherwise it will
208 block in case of sshrepo because it don't know the end of the stream.
207 block in case of sshrepo because it don't know the end of the stream.
209 """
208 """
210 # For changegroup 1 and 2, we expect 3 parts: changelog, manifestlog,
209 # For changegroup 1 and 2, we expect 3 parts: changelog, manifestlog,
211 # and a list of filelogs. For changegroup 3, we expect 4 parts:
210 # and a list of filelogs. For changegroup 3, we expect 4 parts:
212 # changelog, manifestlog, a list of tree manifestlogs, and a list of
211 # changelog, manifestlog, a list of tree manifestlogs, and a list of
213 # filelogs.
212 # filelogs.
214 #
213 #
215 # Changelog and manifestlog parts are terminated with empty chunks. The
214 # Changelog and manifestlog parts are terminated with empty chunks. The
216 # tree and file parts are a list of entry sections. Each entry section
215 # tree and file parts are a list of entry sections. Each entry section
217 # is a series of chunks terminating in an empty chunk. The list of these
216 # is a series of chunks terminating in an empty chunk. The list of these
218 # entry sections is terminated in yet another empty chunk, so we know
217 # entry sections is terminated in yet another empty chunk, so we know
219 # we've reached the end of the tree/file list when we reach an empty
218 # we've reached the end of the tree/file list when we reach an empty
220 # chunk that was proceeded by no non-empty chunks.
219 # chunk that was proceeded by no non-empty chunks.
221
220
222 parts = 0
221 parts = 0
223 while parts < 2 + self._grouplistcount:
222 while parts < 2 + self._grouplistcount:
224 noentries = True
223 noentries = True
225 while True:
224 while True:
226 chunk = getchunk(self)
225 chunk = getchunk(self)
227 if not chunk:
226 if not chunk:
228 # The first two empty chunks represent the end of the
227 # The first two empty chunks represent the end of the
229 # changelog and the manifestlog portions. The remaining
228 # changelog and the manifestlog portions. The remaining
230 # empty chunks represent either A) the end of individual
229 # empty chunks represent either A) the end of individual
231 # tree or file entries in the file list, or B) the end of
230 # tree or file entries in the file list, or B) the end of
232 # the entire list. It's the end of the entire list if there
231 # the entire list. It's the end of the entire list if there
233 # were no entries (i.e. noentries is True).
232 # were no entries (i.e. noentries is True).
234 if parts < 2:
233 if parts < 2:
235 parts += 1
234 parts += 1
236 elif noentries:
235 elif noentries:
237 parts += 1
236 parts += 1
238 break
237 break
239 noentries = False
238 noentries = False
240 yield chunkheader(len(chunk))
239 yield chunkheader(len(chunk))
241 pos = 0
240 pos = 0
242 while pos < len(chunk):
241 while pos < len(chunk):
243 next = pos + 2**20
242 next = pos + 2**20
244 yield chunk[pos:next]
243 yield chunk[pos:next]
245 pos = next
244 pos = next
246 yield closechunk()
245 yield closechunk()
247
246
248 def _unpackmanifests(self, repo, revmap, trp, prog):
247 def _unpackmanifests(self, repo, revmap, trp, prog):
249 self.callback = prog.increment
248 self.callback = prog.increment
250 # no need to check for empty manifest group here:
249 # no need to check for empty manifest group here:
251 # if the result of the merge of 1 and 2 is the same in 3 and 4,
250 # if the result of the merge of 1 and 2 is the same in 3 and 4,
252 # no new manifest will be created and the manifest group will
251 # no new manifest will be created and the manifest group will
253 # be empty during the pull
252 # be empty during the pull
254 self.manifestheader()
253 self.manifestheader()
255 deltas = self.deltaiter()
254 deltas = self.deltaiter()
256 repo.manifestlog.getstorage(b'').addgroup(deltas, revmap, trp)
255 repo.manifestlog.getstorage(b'').addgroup(deltas, revmap, trp)
257 prog.complete()
256 prog.complete()
258 self.callback = None
257 self.callback = None
259
258
260 def apply(self, repo, tr, srctype, url, targetphase=phases.draft,
259 def apply(self, repo, tr, srctype, url, targetphase=phases.draft,
261 expectedtotal=None):
260 expectedtotal=None):
262 """Add the changegroup returned by source.read() to this repo.
261 """Add the changegroup returned by source.read() to this repo.
263 srctype is a string like 'push', 'pull', or 'unbundle'. url is
262 srctype is a string like 'push', 'pull', or 'unbundle'. url is
264 the URL of the repo where this changegroup is coming from.
263 the URL of the repo where this changegroup is coming from.
265
264
266 Return an integer summarizing the change to this repo:
265 Return an integer summarizing the change to this repo:
267 - nothing changed or no source: 0
266 - nothing changed or no source: 0
268 - more heads than before: 1+added heads (2..n)
267 - more heads than before: 1+added heads (2..n)
269 - fewer heads than before: -1-removed heads (-2..-n)
268 - fewer heads than before: -1-removed heads (-2..-n)
270 - number of heads stays the same: 1
269 - number of heads stays the same: 1
271 """
270 """
272 repo = repo.unfiltered()
271 repo = repo.unfiltered()
273 def csmap(x):
272 def csmap(x):
274 repo.ui.debug("add changeset %s\n" % short(x))
273 repo.ui.debug("add changeset %s\n" % short(x))
275 return len(cl)
274 return len(cl)
276
275
277 def revmap(x):
276 def revmap(x):
278 return cl.rev(x)
277 return cl.rev(x)
279
278
280 changesets = files = revisions = 0
279 changesets = files = revisions = 0
281
280
282 try:
281 try:
283 # The transaction may already carry source information. In this
282 # The transaction may already carry source information. In this
284 # case we use the top level data. We overwrite the argument
283 # case we use the top level data. We overwrite the argument
285 # because we need to use the top level value (if they exist)
284 # because we need to use the top level value (if they exist)
286 # in this function.
285 # in this function.
287 srctype = tr.hookargs.setdefault('source', srctype)
286 srctype = tr.hookargs.setdefault('source', srctype)
288 url = tr.hookargs.setdefault('url', url)
287 url = tr.hookargs.setdefault('url', url)
289 repo.hook('prechangegroup',
288 repo.hook('prechangegroup',
290 throw=True, **pycompat.strkwargs(tr.hookargs))
289 throw=True, **pycompat.strkwargs(tr.hookargs))
291
290
292 # write changelog data to temp files so concurrent readers
291 # write changelog data to temp files so concurrent readers
293 # will not see an inconsistent view
292 # will not see an inconsistent view
294 cl = repo.changelog
293 cl = repo.changelog
295 cl.delayupdate(tr)
294 cl.delayupdate(tr)
296 oldheads = set(cl.heads())
295 oldheads = set(cl.heads())
297
296
298 trp = weakref.proxy(tr)
297 trp = weakref.proxy(tr)
299 # pull off the changeset group
298 # pull off the changeset group
300 repo.ui.status(_("adding changesets\n"))
299 repo.ui.status(_("adding changesets\n"))
301 clstart = len(cl)
300 clstart = len(cl)
302 progress = repo.ui.makeprogress(_('changesets'), unit=_('chunks'),
301 progress = repo.ui.makeprogress(_('changesets'), unit=_('chunks'),
303 total=expectedtotal)
302 total=expectedtotal)
304 self.callback = progress.increment
303 self.callback = progress.increment
305
304
306 efiles = set()
305 efiles = set()
307 def onchangelog(cl, node):
306 def onchangelog(cl, node):
308 efiles.update(cl.readfiles(node))
307 efiles.update(cl.readfiles(node))
309
308
310 self.changelogheader()
309 self.changelogheader()
311 deltas = self.deltaiter()
310 deltas = self.deltaiter()
312 cgnodes = cl.addgroup(deltas, csmap, trp, addrevisioncb=onchangelog)
311 cgnodes = cl.addgroup(deltas, csmap, trp, addrevisioncb=onchangelog)
313 efiles = len(efiles)
312 efiles = len(efiles)
314
313
315 if not cgnodes:
314 if not cgnodes:
316 repo.ui.develwarn('applied empty changelog from changegroup',
315 repo.ui.develwarn('applied empty changelog from changegroup',
317 config='warn-empty-changegroup')
316 config='warn-empty-changegroup')
318 clend = len(cl)
317 clend = len(cl)
319 changesets = clend - clstart
318 changesets = clend - clstart
320 progress.complete()
319 progress.complete()
321 self.callback = None
320 self.callback = None
322
321
323 # pull off the manifest group
322 # pull off the manifest group
324 repo.ui.status(_("adding manifests\n"))
323 repo.ui.status(_("adding manifests\n"))
325 # We know that we'll never have more manifests than we had
324 # We know that we'll never have more manifests than we had
326 # changesets.
325 # changesets.
327 progress = repo.ui.makeprogress(_('manifests'), unit=_('chunks'),
326 progress = repo.ui.makeprogress(_('manifests'), unit=_('chunks'),
328 total=changesets)
327 total=changesets)
329 self._unpackmanifests(repo, revmap, trp, progress)
328 self._unpackmanifests(repo, revmap, trp, progress)
330
329
331 needfiles = {}
330 needfiles = {}
332 if repo.ui.configbool('server', 'validate'):
331 if repo.ui.configbool('server', 'validate'):
333 cl = repo.changelog
332 cl = repo.changelog
334 ml = repo.manifestlog
333 ml = repo.manifestlog
335 # validate incoming csets have their manifests
334 # validate incoming csets have their manifests
336 for cset in pycompat.xrange(clstart, clend):
335 for cset in pycompat.xrange(clstart, clend):
337 mfnode = cl.changelogrevision(cset).manifest
336 mfnode = cl.changelogrevision(cset).manifest
338 mfest = ml[mfnode].readdelta()
337 mfest = ml[mfnode].readdelta()
339 # store file cgnodes we must see
338 # store file cgnodes we must see
340 for f, n in mfest.iteritems():
339 for f, n in mfest.iteritems():
341 needfiles.setdefault(f, set()).add(n)
340 needfiles.setdefault(f, set()).add(n)
342
341
343 # process the files
342 # process the files
344 repo.ui.status(_("adding file changes\n"))
343 repo.ui.status(_("adding file changes\n"))
345 newrevs, newfiles = _addchangegroupfiles(
344 newrevs, newfiles = _addchangegroupfiles(
346 repo, self, revmap, trp, efiles, needfiles)
345 repo, self, revmap, trp, efiles, needfiles)
347 revisions += newrevs
346 revisions += newrevs
348 files += newfiles
347 files += newfiles
349
348
350 deltaheads = 0
349 deltaheads = 0
351 if oldheads:
350 if oldheads:
352 heads = cl.heads()
351 heads = cl.heads()
353 deltaheads = len(heads) - len(oldheads)
352 deltaheads = len(heads) - len(oldheads)
354 for h in heads:
353 for h in heads:
355 if h not in oldheads and repo[h].closesbranch():
354 if h not in oldheads and repo[h].closesbranch():
356 deltaheads -= 1
355 deltaheads -= 1
357 htext = ""
356 htext = ""
358 if deltaheads:
357 if deltaheads:
359 htext = _(" (%+d heads)") % deltaheads
358 htext = _(" (%+d heads)") % deltaheads
360
359
361 repo.ui.status(_("added %d changesets"
360 repo.ui.status(_("added %d changesets"
362 " with %d changes to %d files%s\n")
361 " with %d changes to %d files%s\n")
363 % (changesets, revisions, files, htext))
362 % (changesets, revisions, files, htext))
364 repo.invalidatevolatilesets()
363 repo.invalidatevolatilesets()
365
364
366 if changesets > 0:
365 if changesets > 0:
367 if 'node' not in tr.hookargs:
366 if 'node' not in tr.hookargs:
368 tr.hookargs['node'] = hex(cl.node(clstart))
367 tr.hookargs['node'] = hex(cl.node(clstart))
369 tr.hookargs['node_last'] = hex(cl.node(clend - 1))
368 tr.hookargs['node_last'] = hex(cl.node(clend - 1))
370 hookargs = dict(tr.hookargs)
369 hookargs = dict(tr.hookargs)
371 else:
370 else:
372 hookargs = dict(tr.hookargs)
371 hookargs = dict(tr.hookargs)
373 hookargs['node'] = hex(cl.node(clstart))
372 hookargs['node'] = hex(cl.node(clstart))
374 hookargs['node_last'] = hex(cl.node(clend - 1))
373 hookargs['node_last'] = hex(cl.node(clend - 1))
375 repo.hook('pretxnchangegroup',
374 repo.hook('pretxnchangegroup',
376 throw=True, **pycompat.strkwargs(hookargs))
375 throw=True, **pycompat.strkwargs(hookargs))
377
376
378 added = [cl.node(r) for r in pycompat.xrange(clstart, clend)]
377 added = [cl.node(r) for r in pycompat.xrange(clstart, clend)]
379 phaseall = None
378 phaseall = None
380 if srctype in ('push', 'serve'):
379 if srctype in ('push', 'serve'):
381 # Old servers can not push the boundary themselves.
380 # Old servers can not push the boundary themselves.
382 # New servers won't push the boundary if changeset already
381 # New servers won't push the boundary if changeset already
383 # exists locally as secret
382 # exists locally as secret
384 #
383 #
385 # We should not use added here but the list of all change in
384 # We should not use added here but the list of all change in
386 # the bundle
385 # the bundle
387 if repo.publishing():
386 if repo.publishing():
388 targetphase = phaseall = phases.public
387 targetphase = phaseall = phases.public
389 else:
388 else:
390 # closer target phase computation
389 # closer target phase computation
391
390
392 # Those changesets have been pushed from the
391 # Those changesets have been pushed from the
393 # outside, their phases are going to be pushed
392 # outside, their phases are going to be pushed
394 # alongside. Therefor `targetphase` is
393 # alongside. Therefor `targetphase` is
395 # ignored.
394 # ignored.
396 targetphase = phaseall = phases.draft
395 targetphase = phaseall = phases.draft
397 if added:
396 if added:
398 phases.registernew(repo, tr, targetphase, added)
397 phases.registernew(repo, tr, targetphase, added)
399 if phaseall is not None:
398 if phaseall is not None:
400 phases.advanceboundary(repo, tr, phaseall, cgnodes)
399 phases.advanceboundary(repo, tr, phaseall, cgnodes)
401
400
402 if changesets > 0:
401 if changesets > 0:
403
402
404 def runhooks():
403 def runhooks():
405 # These hooks run when the lock releases, not when the
404 # These hooks run when the lock releases, not when the
406 # transaction closes. So it's possible for the changelog
405 # transaction closes. So it's possible for the changelog
407 # to have changed since we last saw it.
406 # to have changed since we last saw it.
408 if clstart >= len(repo):
407 if clstart >= len(repo):
409 return
408 return
410
409
411 repo.hook("changegroup", **pycompat.strkwargs(hookargs))
410 repo.hook("changegroup", **pycompat.strkwargs(hookargs))
412
411
413 for n in added:
412 for n in added:
414 args = hookargs.copy()
413 args = hookargs.copy()
415 args['node'] = hex(n)
414 args['node'] = hex(n)
416 del args['node_last']
415 del args['node_last']
417 repo.hook("incoming", **pycompat.strkwargs(args))
416 repo.hook("incoming", **pycompat.strkwargs(args))
418
417
419 newheads = [h for h in repo.heads()
418 newheads = [h for h in repo.heads()
420 if h not in oldheads]
419 if h not in oldheads]
421 repo.ui.log("incoming",
420 repo.ui.log("incoming",
422 "%d incoming changes - new heads: %s\n",
421 "%d incoming changes - new heads: %s\n",
423 len(added),
422 len(added),
424 ', '.join([hex(c[:6]) for c in newheads]))
423 ', '.join([hex(c[:6]) for c in newheads]))
425
424
426 tr.addpostclose('changegroup-runhooks-%020i' % clstart,
425 tr.addpostclose('changegroup-runhooks-%020i' % clstart,
427 lambda tr: repo._afterlock(runhooks))
426 lambda tr: repo._afterlock(runhooks))
428 finally:
427 finally:
429 repo.ui.flush()
428 repo.ui.flush()
430 # never return 0 here:
429 # never return 0 here:
431 if deltaheads < 0:
430 if deltaheads < 0:
432 ret = deltaheads - 1
431 ret = deltaheads - 1
433 else:
432 else:
434 ret = deltaheads + 1
433 ret = deltaheads + 1
435 return ret
434 return ret
436
435
437 def deltaiter(self):
436 def deltaiter(self):
438 """
437 """
439 returns an iterator of the deltas in this changegroup
438 returns an iterator of the deltas in this changegroup
440
439
441 Useful for passing to the underlying storage system to be stored.
440 Useful for passing to the underlying storage system to be stored.
442 """
441 """
443 chain = None
442 chain = None
444 for chunkdata in iter(lambda: self.deltachunk(chain), {}):
443 for chunkdata in iter(lambda: self.deltachunk(chain), {}):
445 # Chunkdata: (node, p1, p2, cs, deltabase, delta, flags)
444 # Chunkdata: (node, p1, p2, cs, deltabase, delta, flags)
446 yield chunkdata
445 yield chunkdata
447 chain = chunkdata[0]
446 chain = chunkdata[0]
448
447
449 class cg2unpacker(cg1unpacker):
448 class cg2unpacker(cg1unpacker):
450 """Unpacker for cg2 streams.
449 """Unpacker for cg2 streams.
451
450
452 cg2 streams add support for generaldelta, so the delta header
451 cg2 streams add support for generaldelta, so the delta header
453 format is slightly different. All other features about the data
452 format is slightly different. All other features about the data
454 remain the same.
453 remain the same.
455 """
454 """
456 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
455 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
457 deltaheadersize = deltaheader.size
456 deltaheadersize = deltaheader.size
458 version = '02'
457 version = '02'
459
458
460 def _deltaheader(self, headertuple, prevnode):
459 def _deltaheader(self, headertuple, prevnode):
461 node, p1, p2, deltabase, cs = headertuple
460 node, p1, p2, deltabase, cs = headertuple
462 flags = 0
461 flags = 0
463 return node, p1, p2, deltabase, cs, flags
462 return node, p1, p2, deltabase, cs, flags
464
463
465 class cg3unpacker(cg2unpacker):
464 class cg3unpacker(cg2unpacker):
466 """Unpacker for cg3 streams.
465 """Unpacker for cg3 streams.
467
466
468 cg3 streams add support for exchanging treemanifests and revlog
467 cg3 streams add support for exchanging treemanifests and revlog
469 flags. It adds the revlog flags to the delta header and an empty chunk
468 flags. It adds the revlog flags to the delta header and an empty chunk
470 separating manifests and files.
469 separating manifests and files.
471 """
470 """
472 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
471 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
473 deltaheadersize = deltaheader.size
472 deltaheadersize = deltaheader.size
474 version = '03'
473 version = '03'
475 _grouplistcount = 2 # One list of manifests and one list of files
474 _grouplistcount = 2 # One list of manifests and one list of files
476
475
477 def _deltaheader(self, headertuple, prevnode):
476 def _deltaheader(self, headertuple, prevnode):
478 node, p1, p2, deltabase, cs, flags = headertuple
477 node, p1, p2, deltabase, cs, flags = headertuple
479 return node, p1, p2, deltabase, cs, flags
478 return node, p1, p2, deltabase, cs, flags
480
479
481 def _unpackmanifests(self, repo, revmap, trp, prog):
480 def _unpackmanifests(self, repo, revmap, trp, prog):
482 super(cg3unpacker, self)._unpackmanifests(repo, revmap, trp, prog)
481 super(cg3unpacker, self)._unpackmanifests(repo, revmap, trp, prog)
483 for chunkdata in iter(self.filelogheader, {}):
482 for chunkdata in iter(self.filelogheader, {}):
484 # If we get here, there are directory manifests in the changegroup
483 # If we get here, there are directory manifests in the changegroup
485 d = chunkdata["filename"]
484 d = chunkdata["filename"]
486 repo.ui.debug("adding %s revisions\n" % d)
485 repo.ui.debug("adding %s revisions\n" % d)
487 deltas = self.deltaiter()
486 deltas = self.deltaiter()
488 if not repo.manifestlog.getstorage(d).addgroup(deltas, revmap, trp):
487 if not repo.manifestlog.getstorage(d).addgroup(deltas, revmap, trp):
489 raise error.Abort(_("received dir revlog group is empty"))
488 raise error.Abort(_("received dir revlog group is empty"))
490
489
491 class headerlessfixup(object):
490 class headerlessfixup(object):
492 def __init__(self, fh, h):
491 def __init__(self, fh, h):
493 self._h = h
492 self._h = h
494 self._fh = fh
493 self._fh = fh
495 def read(self, n):
494 def read(self, n):
496 if self._h:
495 if self._h:
497 d, self._h = self._h[:n], self._h[n:]
496 d, self._h = self._h[:n], self._h[n:]
498 if len(d) < n:
497 if len(d) < n:
499 d += readexactly(self._fh, n - len(d))
498 d += readexactly(self._fh, n - len(d))
500 return d
499 return d
501 return readexactly(self._fh, n)
500 return readexactly(self._fh, n)
502
501
503 @interfaceutil.implementer(repository.irevisiondeltarequest)
502 @interfaceutil.implementer(repository.irevisiondeltarequest)
504 @attr.s(slots=True, frozen=True)
503 @attr.s(slots=True, frozen=True)
505 class revisiondeltarequest(object):
504 class revisiondeltarequest(object):
506 node = attr.ib()
505 node = attr.ib()
507 linknode = attr.ib()
506 linknode = attr.ib()
508 p1node = attr.ib()
507 p1node = attr.ib()
509 p2node = attr.ib()
508 p2node = attr.ib()
510 basenode = attr.ib()
509 basenode = attr.ib()
511 ellipsis = attr.ib(default=False)
510 ellipsis = attr.ib(default=False)
512
511
513 def _revisiondeltatochunks(delta, headerfn):
512 def _revisiondeltatochunks(delta, headerfn):
514 """Serialize a revisiondelta to changegroup chunks."""
513 """Serialize a revisiondelta to changegroup chunks."""
515
514
516 # The captured revision delta may be encoded as a delta against
515 # The captured revision delta may be encoded as a delta against
517 # a base revision or as a full revision. The changegroup format
516 # a base revision or as a full revision. The changegroup format
518 # requires that everything on the wire be deltas. So for full
517 # requires that everything on the wire be deltas. So for full
519 # revisions, we need to invent a header that says to rewrite
518 # revisions, we need to invent a header that says to rewrite
520 # data.
519 # data.
521
520
522 if delta.delta is not None:
521 if delta.delta is not None:
523 prefix, data = b'', delta.delta
522 prefix, data = b'', delta.delta
524 elif delta.basenode == nullid:
523 elif delta.basenode == nullid:
525 data = delta.revision
524 data = delta.revision
526 prefix = mdiff.trivialdiffheader(len(data))
525 prefix = mdiff.trivialdiffheader(len(data))
527 else:
526 else:
528 data = delta.revision
527 data = delta.revision
529 prefix = mdiff.replacediffheader(delta.baserevisionsize,
528 prefix = mdiff.replacediffheader(delta.baserevisionsize,
530 len(data))
529 len(data))
531
530
532 meta = headerfn(delta)
531 meta = headerfn(delta)
533
532
534 yield chunkheader(len(meta) + len(prefix) + len(data))
533 yield chunkheader(len(meta) + len(prefix) + len(data))
535 yield meta
534 yield meta
536 if prefix:
535 if prefix:
537 yield prefix
536 yield prefix
538 yield data
537 yield data
539
538
540 def _sortnodesnormal(store, nodes, reorder):
539 def _sortnodesnormal(store, nodes):
541 """Sort nodes for changegroup generation and turn into revnums."""
540 """Sort nodes for changegroup generation and turn into revnums."""
542 # for generaldelta revlogs, we linearize the revs; this will both be
541 # for generaldelta revlogs, we linearize the revs; this will both be
543 # much quicker and generate a much smaller bundle
542 # much quicker and generate a much smaller bundle
544 if (store._generaldelta and reorder is None) or reorder:
543 if store._generaldelta:
545 revs = set(store.rev(n) for n in nodes)
544 revs = set(store.rev(n) for n in nodes)
546 return dagop.linearize(revs, store.parentrevs)
545 return dagop.linearize(revs, store.parentrevs)
547 else:
546 else:
548 return sorted([store.rev(n) for n in nodes])
547 return sorted([store.rev(n) for n in nodes])
549
548
550 def _sortnodesellipsis(store, nodes, cl, lookup):
549 def _sortnodesellipsis(store, nodes, cl, lookup):
551 """Sort nodes for changegroup generation and turn into revnums."""
550 """Sort nodes for changegroup generation and turn into revnums."""
552 # Ellipses serving mode.
551 # Ellipses serving mode.
553 #
552 #
554 # In a perfect world, we'd generate better ellipsis-ified graphs
553 # In a perfect world, we'd generate better ellipsis-ified graphs
555 # for non-changelog revlogs. In practice, we haven't started doing
554 # for non-changelog revlogs. In practice, we haven't started doing
556 # that yet, so the resulting DAGs for the manifestlog and filelogs
555 # that yet, so the resulting DAGs for the manifestlog and filelogs
557 # are actually full of bogus parentage on all the ellipsis
556 # are actually full of bogus parentage on all the ellipsis
558 # nodes. This has the side effect that, while the contents are
557 # nodes. This has the side effect that, while the contents are
559 # correct, the individual DAGs might be completely out of whack in
558 # correct, the individual DAGs might be completely out of whack in
560 # a case like 882681bc3166 and its ancestors (back about 10
559 # a case like 882681bc3166 and its ancestors (back about 10
561 # revisions or so) in the main hg repo.
560 # revisions or so) in the main hg repo.
562 #
561 #
563 # The one invariant we *know* holds is that the new (potentially
562 # The one invariant we *know* holds is that the new (potentially
564 # bogus) DAG shape will be valid if we order the nodes in the
563 # bogus) DAG shape will be valid if we order the nodes in the
565 # order that they're introduced in dramatis personae by the
564 # order that they're introduced in dramatis personae by the
566 # changelog, so what we do is we sort the non-changelog histories
565 # changelog, so what we do is we sort the non-changelog histories
567 # by the order in which they are used by the changelog.
566 # by the order in which they are used by the changelog.
568 key = lambda n: cl.rev(lookup(n))
567 key = lambda n: cl.rev(lookup(n))
569 return [store.rev(n) for n in sorted(nodes, key=key)]
568 return [store.rev(n) for n in sorted(nodes, key=key)]
570
569
571 def _makenarrowdeltarequest(cl, store, ischangelog, rev, node, linkrev,
570 def _makenarrowdeltarequest(cl, store, ischangelog, rev, node, linkrev,
572 linknode, clrevtolocalrev, fullclnodes,
571 linknode, clrevtolocalrev, fullclnodes,
573 precomputedellipsis):
572 precomputedellipsis):
574 linkparents = precomputedellipsis[linkrev]
573 linkparents = precomputedellipsis[linkrev]
575 def local(clrev):
574 def local(clrev):
576 """Turn a changelog revnum into a local revnum.
575 """Turn a changelog revnum into a local revnum.
577
576
578 The ellipsis dag is stored as revnums on the changelog,
577 The ellipsis dag is stored as revnums on the changelog,
579 but when we're producing ellipsis entries for
578 but when we're producing ellipsis entries for
580 non-changelog revlogs, we need to turn those numbers into
579 non-changelog revlogs, we need to turn those numbers into
581 something local. This does that for us, and during the
580 something local. This does that for us, and during the
582 changelog sending phase will also expand the stored
581 changelog sending phase will also expand the stored
583 mappings as needed.
582 mappings as needed.
584 """
583 """
585 if clrev == nullrev:
584 if clrev == nullrev:
586 return nullrev
585 return nullrev
587
586
588 if ischangelog:
587 if ischangelog:
589 return clrev
588 return clrev
590
589
591 # Walk the ellipsis-ized changelog breadth-first looking for a
590 # Walk the ellipsis-ized changelog breadth-first looking for a
592 # change that has been linked from the current revlog.
591 # change that has been linked from the current revlog.
593 #
592 #
594 # For a flat manifest revlog only a single step should be necessary
593 # For a flat manifest revlog only a single step should be necessary
595 # as all relevant changelog entries are relevant to the flat
594 # as all relevant changelog entries are relevant to the flat
596 # manifest.
595 # manifest.
597 #
596 #
598 # For a filelog or tree manifest dirlog however not every changelog
597 # For a filelog or tree manifest dirlog however not every changelog
599 # entry will have been relevant, so we need to skip some changelog
598 # entry will have been relevant, so we need to skip some changelog
600 # nodes even after ellipsis-izing.
599 # nodes even after ellipsis-izing.
601 walk = [clrev]
600 walk = [clrev]
602 while walk:
601 while walk:
603 p = walk[0]
602 p = walk[0]
604 walk = walk[1:]
603 walk = walk[1:]
605 if p in clrevtolocalrev:
604 if p in clrevtolocalrev:
606 return clrevtolocalrev[p]
605 return clrevtolocalrev[p]
607 elif p in fullclnodes:
606 elif p in fullclnodes:
608 walk.extend([pp for pp in cl.parentrevs(p)
607 walk.extend([pp for pp in cl.parentrevs(p)
609 if pp != nullrev])
608 if pp != nullrev])
610 elif p in precomputedellipsis:
609 elif p in precomputedellipsis:
611 walk.extend([pp for pp in precomputedellipsis[p]
610 walk.extend([pp for pp in precomputedellipsis[p]
612 if pp != nullrev])
611 if pp != nullrev])
613 else:
612 else:
614 # In this case, we've got an ellipsis with parents
613 # In this case, we've got an ellipsis with parents
615 # outside the current bundle (likely an
614 # outside the current bundle (likely an
616 # incremental pull). We "know" that we can use the
615 # incremental pull). We "know" that we can use the
617 # value of this same revlog at whatever revision
616 # value of this same revlog at whatever revision
618 # is pointed to by linknode. "Know" is in scare
617 # is pointed to by linknode. "Know" is in scare
619 # quotes because I haven't done enough examination
618 # quotes because I haven't done enough examination
620 # of edge cases to convince myself this is really
619 # of edge cases to convince myself this is really
621 # a fact - it works for all the (admittedly
620 # a fact - it works for all the (admittedly
622 # thorough) cases in our testsuite, but I would be
621 # thorough) cases in our testsuite, but I would be
623 # somewhat unsurprised to find a case in the wild
622 # somewhat unsurprised to find a case in the wild
624 # where this breaks down a bit. That said, I don't
623 # where this breaks down a bit. That said, I don't
625 # know if it would hurt anything.
624 # know if it would hurt anything.
626 for i in pycompat.xrange(rev, 0, -1):
625 for i in pycompat.xrange(rev, 0, -1):
627 if store.linkrev(i) == clrev:
626 if store.linkrev(i) == clrev:
628 return i
627 return i
629 # We failed to resolve a parent for this node, so
628 # We failed to resolve a parent for this node, so
630 # we crash the changegroup construction.
629 # we crash the changegroup construction.
631 raise error.Abort(
630 raise error.Abort(
632 'unable to resolve parent while packing %r %r'
631 'unable to resolve parent while packing %r %r'
633 ' for changeset %r' % (store.indexfile, rev, clrev))
632 ' for changeset %r' % (store.indexfile, rev, clrev))
634
633
635 return nullrev
634 return nullrev
636
635
637 if not linkparents or (
636 if not linkparents or (
638 store.parentrevs(rev) == (nullrev, nullrev)):
637 store.parentrevs(rev) == (nullrev, nullrev)):
639 p1, p2 = nullrev, nullrev
638 p1, p2 = nullrev, nullrev
640 elif len(linkparents) == 1:
639 elif len(linkparents) == 1:
641 p1, = sorted(local(p) for p in linkparents)
640 p1, = sorted(local(p) for p in linkparents)
642 p2 = nullrev
641 p2 = nullrev
643 else:
642 else:
644 p1, p2 = sorted(local(p) for p in linkparents)
643 p1, p2 = sorted(local(p) for p in linkparents)
645
644
646 p1node, p2node = store.node(p1), store.node(p2)
645 p1node, p2node = store.node(p1), store.node(p2)
647
646
648 # TODO: try and actually send deltas for ellipsis data blocks
647 # TODO: try and actually send deltas for ellipsis data blocks
649 return revisiondeltarequest(
648 return revisiondeltarequest(
650 node=node,
649 node=node,
651 p1node=p1node,
650 p1node=p1node,
652 p2node=p2node,
651 p2node=p2node,
653 linknode=linknode,
652 linknode=linknode,
654 basenode=nullid,
653 basenode=nullid,
655 ellipsis=True,
654 ellipsis=True,
656 )
655 )
657
656
658 def deltagroup(repo, store, nodes, ischangelog, lookup, forcedeltaparentprev,
657 def deltagroup(repo, store, nodes, ischangelog, lookup, forcedeltaparentprev,
659 allowreorder,
660 topic=None,
658 topic=None,
661 ellipses=False, clrevtolocalrev=None, fullclnodes=None,
659 ellipses=False, clrevtolocalrev=None, fullclnodes=None,
662 precomputedellipsis=None):
660 precomputedellipsis=None):
663 """Calculate deltas for a set of revisions.
661 """Calculate deltas for a set of revisions.
664
662
665 Is a generator of ``revisiondelta`` instances.
663 Is a generator of ``revisiondelta`` instances.
666
664
667 If topic is not None, progress detail will be generated using this
665 If topic is not None, progress detail will be generated using this
668 topic name (e.g. changesets, manifests, etc).
666 topic name (e.g. changesets, manifests, etc).
669 """
667 """
670 if not nodes:
668 if not nodes:
671 return
669 return
672
670
673 # We perform two passes over the revisions whose data we will emit.
671 # We perform two passes over the revisions whose data we will emit.
674 #
672 #
675 # In the first pass, we obtain information about the deltas that will
673 # In the first pass, we obtain information about the deltas that will
676 # be generated. This involves computing linknodes and adjusting the
674 # be generated. This involves computing linknodes and adjusting the
677 # request to take shallow fetching into account. The end result of
675 # request to take shallow fetching into account. The end result of
678 # this pass is a list of "request" objects stating which deltas
676 # this pass is a list of "request" objects stating which deltas
679 # to obtain.
677 # to obtain.
680 #
678 #
681 # The second pass is simply resolving the requested deltas.
679 # The second pass is simply resolving the requested deltas.
682
680
683 cl = repo.changelog
681 cl = repo.changelog
684
682
685 if ischangelog:
683 if ischangelog:
686 # Changelog doesn't benefit from reordering revisions. So send
684 # Changelog doesn't benefit from reordering revisions. So send
687 # out revisions in store order.
685 # out revisions in store order.
688 # TODO the API would be cleaner if this were controlled by the
686 # TODO the API would be cleaner if this were controlled by the
689 # store producing the deltas.
687 # store producing the deltas.
690 revs = sorted(cl.rev(n) for n in nodes)
688 revs = sorted(cl.rev(n) for n in nodes)
691 elif ellipses:
689 elif ellipses:
692 revs = _sortnodesellipsis(store, nodes, cl, lookup)
690 revs = _sortnodesellipsis(store, nodes, cl, lookup)
693 else:
691 else:
694 revs = _sortnodesnormal(store, nodes, allowreorder)
692 revs = _sortnodesnormal(store, nodes)
695
693
696 # In the first pass, collect info about the deltas we'll be
694 # In the first pass, collect info about the deltas we'll be
697 # generating.
695 # generating.
698 requests = []
696 requests = []
699
697
700 # Add the parent of the first rev.
698 # Add the parent of the first rev.
701 revs.insert(0, store.parentrevs(revs[0])[0])
699 revs.insert(0, store.parentrevs(revs[0])[0])
702
700
703 for i in pycompat.xrange(len(revs) - 1):
701 for i in pycompat.xrange(len(revs) - 1):
704 prev = revs[i]
702 prev = revs[i]
705 curr = revs[i + 1]
703 curr = revs[i + 1]
706
704
707 node = store.node(curr)
705 node = store.node(curr)
708 linknode = lookup(node)
706 linknode = lookup(node)
709 p1node, p2node = store.parents(node)
707 p1node, p2node = store.parents(node)
710
708
711 if ellipses:
709 if ellipses:
712 linkrev = cl.rev(linknode)
710 linkrev = cl.rev(linknode)
713 clrevtolocalrev[linkrev] = curr
711 clrevtolocalrev[linkrev] = curr
714
712
715 # This is a node to send in full, because the changeset it
713 # This is a node to send in full, because the changeset it
716 # corresponds to was a full changeset.
714 # corresponds to was a full changeset.
717 if linknode in fullclnodes:
715 if linknode in fullclnodes:
718 requests.append(revisiondeltarequest(
716 requests.append(revisiondeltarequest(
719 node=node,
717 node=node,
720 p1node=p1node,
718 p1node=p1node,
721 p2node=p2node,
719 p2node=p2node,
722 linknode=linknode,
720 linknode=linknode,
723 basenode=None,
721 basenode=None,
724 ))
722 ))
725
723
726 elif linkrev not in precomputedellipsis:
724 elif linkrev not in precomputedellipsis:
727 pass
725 pass
728 else:
726 else:
729 requests.append(_makenarrowdeltarequest(
727 requests.append(_makenarrowdeltarequest(
730 cl, store, ischangelog, curr, node, linkrev, linknode,
728 cl, store, ischangelog, curr, node, linkrev, linknode,
731 clrevtolocalrev, fullclnodes,
729 clrevtolocalrev, fullclnodes,
732 precomputedellipsis))
730 precomputedellipsis))
733 else:
731 else:
734 requests.append(revisiondeltarequest(
732 requests.append(revisiondeltarequest(
735 node=node,
733 node=node,
736 p1node=p1node,
734 p1node=p1node,
737 p2node=p2node,
735 p2node=p2node,
738 linknode=linknode,
736 linknode=linknode,
739 basenode=store.node(prev) if forcedeltaparentprev else None,
737 basenode=store.node(prev) if forcedeltaparentprev else None,
740 ))
738 ))
741
739
742 # We expect the first pass to be fast, so we only engage the progress
740 # We expect the first pass to be fast, so we only engage the progress
743 # meter for constructing the revision deltas.
741 # meter for constructing the revision deltas.
744 progress = None
742 progress = None
745 if topic is not None:
743 if topic is not None:
746 progress = repo.ui.makeprogress(topic, unit=_('chunks'),
744 progress = repo.ui.makeprogress(topic, unit=_('chunks'),
747 total=len(requests))
745 total=len(requests))
748
746
749 for i, delta in enumerate(store.emitrevisiondeltas(requests)):
747 for i, delta in enumerate(store.emitrevisiondeltas(requests)):
750 if progress:
748 if progress:
751 progress.update(i + 1)
749 progress.update(i + 1)
752
750
753 yield delta
751 yield delta
754
752
755 if progress:
753 if progress:
756 progress.complete()
754 progress.complete()
757
755
758 class cgpacker(object):
756 class cgpacker(object):
759 def __init__(self, repo, filematcher, version, allowreorder,
757 def __init__(self, repo, filematcher, version,
760 builddeltaheader, manifestsend,
758 builddeltaheader, manifestsend,
761 forcedeltaparentprev=False,
759 forcedeltaparentprev=False,
762 bundlecaps=None, ellipses=False,
760 bundlecaps=None, ellipses=False,
763 shallow=False, ellipsisroots=None, fullnodes=None):
761 shallow=False, ellipsisroots=None, fullnodes=None):
764 """Given a source repo, construct a bundler.
762 """Given a source repo, construct a bundler.
765
763
766 filematcher is a matcher that matches on files to include in the
764 filematcher is a matcher that matches on files to include in the
767 changegroup. Used to facilitate sparse changegroups.
765 changegroup. Used to facilitate sparse changegroups.
768
766
769 allowreorder controls whether reordering of revisions is allowed.
770 This value is used when ``bundle.reorder`` is ``auto`` or isn't
771 set.
772
773 forcedeltaparentprev indicates whether delta parents must be against
767 forcedeltaparentprev indicates whether delta parents must be against
774 the previous revision in a delta group. This should only be used for
768 the previous revision in a delta group. This should only be used for
775 compatibility with changegroup version 1.
769 compatibility with changegroup version 1.
776
770
777 builddeltaheader is a callable that constructs the header for a group
771 builddeltaheader is a callable that constructs the header for a group
778 delta.
772 delta.
779
773
780 manifestsend is a chunk to send after manifests have been fully emitted.
774 manifestsend is a chunk to send after manifests have been fully emitted.
781
775
782 ellipses indicates whether ellipsis serving mode is enabled.
776 ellipses indicates whether ellipsis serving mode is enabled.
783
777
784 bundlecaps is optional and can be used to specify the set of
778 bundlecaps is optional and can be used to specify the set of
785 capabilities which can be used to build the bundle. While bundlecaps is
779 capabilities which can be used to build the bundle. While bundlecaps is
786 unused in core Mercurial, extensions rely on this feature to communicate
780 unused in core Mercurial, extensions rely on this feature to communicate
787 capabilities to customize the changegroup packer.
781 capabilities to customize the changegroup packer.
788
782
789 shallow indicates whether shallow data might be sent. The packer may
783 shallow indicates whether shallow data might be sent. The packer may
790 need to pack file contents not introduced by the changes being packed.
784 need to pack file contents not introduced by the changes being packed.
791
785
792 fullnodes is the set of changelog nodes which should not be ellipsis
786 fullnodes is the set of changelog nodes which should not be ellipsis
793 nodes. We store this rather than the set of nodes that should be
787 nodes. We store this rather than the set of nodes that should be
794 ellipsis because for very large histories we expect this to be
788 ellipsis because for very large histories we expect this to be
795 significantly smaller.
789 significantly smaller.
796 """
790 """
797 assert filematcher
791 assert filematcher
798 self._filematcher = filematcher
792 self._filematcher = filematcher
799
793
800 self.version = version
794 self.version = version
801 self._forcedeltaparentprev = forcedeltaparentprev
795 self._forcedeltaparentprev = forcedeltaparentprev
802 self._builddeltaheader = builddeltaheader
796 self._builddeltaheader = builddeltaheader
803 self._manifestsend = manifestsend
797 self._manifestsend = manifestsend
804 self._ellipses = ellipses
798 self._ellipses = ellipses
805
799
806 # Set of capabilities we can use to build the bundle.
800 # Set of capabilities we can use to build the bundle.
807 if bundlecaps is None:
801 if bundlecaps is None:
808 bundlecaps = set()
802 bundlecaps = set()
809 self._bundlecaps = bundlecaps
803 self._bundlecaps = bundlecaps
810 self._isshallow = shallow
804 self._isshallow = shallow
811 self._fullclnodes = fullnodes
805 self._fullclnodes = fullnodes
812
806
813 # Maps ellipsis revs to their roots at the changelog level.
807 # Maps ellipsis revs to their roots at the changelog level.
814 self._precomputedellipsis = ellipsisroots
808 self._precomputedellipsis = ellipsisroots
815
809
816 # experimental config: bundle.reorder
817 reorder = repo.ui.config('bundle', 'reorder')
818 if reorder == 'auto':
819 self._reorder = allowreorder
820 else:
821 self._reorder = stringutil.parsebool(reorder)
822
823 self._repo = repo
810 self._repo = repo
824
811
825 if self._repo.ui.verbose and not self._repo.ui.debugflag:
812 if self._repo.ui.verbose and not self._repo.ui.debugflag:
826 self._verbosenote = self._repo.ui.note
813 self._verbosenote = self._repo.ui.note
827 else:
814 else:
828 self._verbosenote = lambda s: None
815 self._verbosenote = lambda s: None
829
816
830 def generate(self, commonrevs, clnodes, fastpathlinkrev, source,
817 def generate(self, commonrevs, clnodes, fastpathlinkrev, source,
831 changelog=True):
818 changelog=True):
832 """Yield a sequence of changegroup byte chunks.
819 """Yield a sequence of changegroup byte chunks.
833 If changelog is False, changelog data won't be added to changegroup
820 If changelog is False, changelog data won't be added to changegroup
834 """
821 """
835
822
836 repo = self._repo
823 repo = self._repo
837 cl = repo.changelog
824 cl = repo.changelog
838
825
839 self._verbosenote(_('uncompressed size of bundle content:\n'))
826 self._verbosenote(_('uncompressed size of bundle content:\n'))
840 size = 0
827 size = 0
841
828
842 clstate, deltas = self._generatechangelog(cl, clnodes)
829 clstate, deltas = self._generatechangelog(cl, clnodes)
843 for delta in deltas:
830 for delta in deltas:
844 if changelog:
831 if changelog:
845 for chunk in _revisiondeltatochunks(delta,
832 for chunk in _revisiondeltatochunks(delta,
846 self._builddeltaheader):
833 self._builddeltaheader):
847 size += len(chunk)
834 size += len(chunk)
848 yield chunk
835 yield chunk
849
836
850 close = closechunk()
837 close = closechunk()
851 size += len(close)
838 size += len(close)
852 yield closechunk()
839 yield closechunk()
853
840
854 self._verbosenote(_('%8.i (changelog)\n') % size)
841 self._verbosenote(_('%8.i (changelog)\n') % size)
855
842
856 clrevorder = clstate['clrevorder']
843 clrevorder = clstate['clrevorder']
857 manifests = clstate['manifests']
844 manifests = clstate['manifests']
858 changedfiles = clstate['changedfiles']
845 changedfiles = clstate['changedfiles']
859
846
860 # We need to make sure that the linkrev in the changegroup refers to
847 # We need to make sure that the linkrev in the changegroup refers to
861 # the first changeset that introduced the manifest or file revision.
848 # the first changeset that introduced the manifest or file revision.
862 # The fastpath is usually safer than the slowpath, because the filelogs
849 # The fastpath is usually safer than the slowpath, because the filelogs
863 # are walked in revlog order.
850 # are walked in revlog order.
864 #
851 #
865 # When taking the slowpath with reorder=None and the manifest revlog
852 # When taking the slowpath when the manifest revlog uses generaldelta,
866 # uses generaldelta, the manifest may be walked in the "wrong" order.
853 # the manifest may be walked in the "wrong" order. Without 'clrevorder',
867 # Without 'clrevorder', we would get an incorrect linkrev (see fix in
854 # we would get an incorrect linkrev (see fix in cc0ff93d0c0c).
868 # cc0ff93d0c0c).
869 #
855 #
870 # When taking the fastpath, we are only vulnerable to reordering
856 # When taking the fastpath, we are only vulnerable to reordering
871 # of the changelog itself. The changelog never uses generaldelta, so
857 # of the changelog itself. The changelog never uses generaldelta and is
872 # it is only reordered when reorder=True. To handle this case, we
858 # never reordered. To handle this case, we simply take the slowpath,
873 # simply take the slowpath, which already has the 'clrevorder' logic.
859 # which already has the 'clrevorder' logic. This was also fixed in
874 # This was also fixed in cc0ff93d0c0c.
860 # cc0ff93d0c0c.
875 fastpathlinkrev = fastpathlinkrev and not self._reorder
861
876 # Treemanifests don't work correctly with fastpathlinkrev
862 # Treemanifests don't work correctly with fastpathlinkrev
877 # either, because we don't discover which directory nodes to
863 # either, because we don't discover which directory nodes to
878 # send along with files. This could probably be fixed.
864 # send along with files. This could probably be fixed.
879 fastpathlinkrev = fastpathlinkrev and (
865 fastpathlinkrev = fastpathlinkrev and (
880 'treemanifest' not in repo.requirements)
866 'treemanifest' not in repo.requirements)
881
867
882 fnodes = {} # needed file nodes
868 fnodes = {} # needed file nodes
883
869
884 size = 0
870 size = 0
885 it = self.generatemanifests(
871 it = self.generatemanifests(
886 commonrevs, clrevorder, fastpathlinkrev, manifests, fnodes, source,
872 commonrevs, clrevorder, fastpathlinkrev, manifests, fnodes, source,
887 clstate['clrevtomanifestrev'])
873 clstate['clrevtomanifestrev'])
888
874
889 for tree, deltas in it:
875 for tree, deltas in it:
890 if tree:
876 if tree:
891 assert self.version == b'03'
877 assert self.version == b'03'
892 chunk = _fileheader(tree)
878 chunk = _fileheader(tree)
893 size += len(chunk)
879 size += len(chunk)
894 yield chunk
880 yield chunk
895
881
896 for delta in deltas:
882 for delta in deltas:
897 chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
883 chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
898 for chunk in chunks:
884 for chunk in chunks:
899 size += len(chunk)
885 size += len(chunk)
900 yield chunk
886 yield chunk
901
887
902 close = closechunk()
888 close = closechunk()
903 size += len(close)
889 size += len(close)
904 yield close
890 yield close
905
891
906 self._verbosenote(_('%8.i (manifests)\n') % size)
892 self._verbosenote(_('%8.i (manifests)\n') % size)
907 yield self._manifestsend
893 yield self._manifestsend
908
894
909 mfdicts = None
895 mfdicts = None
910 if self._ellipses and self._isshallow:
896 if self._ellipses and self._isshallow:
911 mfdicts = [(self._repo.manifestlog[n].read(), lr)
897 mfdicts = [(self._repo.manifestlog[n].read(), lr)
912 for (n, lr) in manifests.iteritems()]
898 for (n, lr) in manifests.iteritems()]
913
899
914 manifests.clear()
900 manifests.clear()
915 clrevs = set(cl.rev(x) for x in clnodes)
901 clrevs = set(cl.rev(x) for x in clnodes)
916
902
917 it = self.generatefiles(changedfiles, commonrevs,
903 it = self.generatefiles(changedfiles, commonrevs,
918 source, mfdicts, fastpathlinkrev,
904 source, mfdicts, fastpathlinkrev,
919 fnodes, clrevs)
905 fnodes, clrevs)
920
906
921 for path, deltas in it:
907 for path, deltas in it:
922 h = _fileheader(path)
908 h = _fileheader(path)
923 size = len(h)
909 size = len(h)
924 yield h
910 yield h
925
911
926 for delta in deltas:
912 for delta in deltas:
927 chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
913 chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
928 for chunk in chunks:
914 for chunk in chunks:
929 size += len(chunk)
915 size += len(chunk)
930 yield chunk
916 yield chunk
931
917
932 close = closechunk()
918 close = closechunk()
933 size += len(close)
919 size += len(close)
934 yield close
920 yield close
935
921
936 self._verbosenote(_('%8.i %s\n') % (size, path))
922 self._verbosenote(_('%8.i %s\n') % (size, path))
937
923
938 yield closechunk()
924 yield closechunk()
939
925
940 if clnodes:
926 if clnodes:
941 repo.hook('outgoing', node=hex(clnodes[0]), source=source)
927 repo.hook('outgoing', node=hex(clnodes[0]), source=source)
942
928
943 def _generatechangelog(self, cl, nodes):
929 def _generatechangelog(self, cl, nodes):
944 """Generate data for changelog chunks.
930 """Generate data for changelog chunks.
945
931
946 Returns a 2-tuple of a dict containing state and an iterable of
932 Returns a 2-tuple of a dict containing state and an iterable of
947 byte chunks. The state will not be fully populated until the
933 byte chunks. The state will not be fully populated until the
948 chunk stream has been fully consumed.
934 chunk stream has been fully consumed.
949 """
935 """
950 clrevorder = {}
936 clrevorder = {}
951 manifests = {}
937 manifests = {}
952 mfl = self._repo.manifestlog
938 mfl = self._repo.manifestlog
953 changedfiles = set()
939 changedfiles = set()
954 clrevtomanifestrev = {}
940 clrevtomanifestrev = {}
955
941
956 # Callback for the changelog, used to collect changed files and
942 # Callback for the changelog, used to collect changed files and
957 # manifest nodes.
943 # manifest nodes.
958 # Returns the linkrev node (identity in the changelog case).
944 # Returns the linkrev node (identity in the changelog case).
959 def lookupcl(x):
945 def lookupcl(x):
960 c = cl.changelogrevision(x)
946 c = cl.changelogrevision(x)
961 clrevorder[x] = len(clrevorder)
947 clrevorder[x] = len(clrevorder)
962
948
963 if self._ellipses:
949 if self._ellipses:
964 # Only update manifests if x is going to be sent. Otherwise we
950 # Only update manifests if x is going to be sent. Otherwise we
965 # end up with bogus linkrevs specified for manifests and
951 # end up with bogus linkrevs specified for manifests and
966 # we skip some manifest nodes that we should otherwise
952 # we skip some manifest nodes that we should otherwise
967 # have sent.
953 # have sent.
968 if (x in self._fullclnodes
954 if (x in self._fullclnodes
969 or cl.rev(x) in self._precomputedellipsis):
955 or cl.rev(x) in self._precomputedellipsis):
970
956
971 manifestnode = c.manifest
957 manifestnode = c.manifest
972 # Record the first changeset introducing this manifest
958 # Record the first changeset introducing this manifest
973 # version.
959 # version.
974 manifests.setdefault(manifestnode, x)
960 manifests.setdefault(manifestnode, x)
975 # Set this narrow-specific dict so we have the lowest
961 # Set this narrow-specific dict so we have the lowest
976 # manifest revnum to look up for this cl revnum. (Part of
962 # manifest revnum to look up for this cl revnum. (Part of
977 # mapping changelog ellipsis parents to manifest ellipsis
963 # mapping changelog ellipsis parents to manifest ellipsis
978 # parents)
964 # parents)
979 clrevtomanifestrev.setdefault(
965 clrevtomanifestrev.setdefault(
980 cl.rev(x), mfl.rev(manifestnode))
966 cl.rev(x), mfl.rev(manifestnode))
981 # We can't trust the changed files list in the changeset if the
967 # We can't trust the changed files list in the changeset if the
982 # client requested a shallow clone.
968 # client requested a shallow clone.
983 if self._isshallow:
969 if self._isshallow:
984 changedfiles.update(mfl[c.manifest].read().keys())
970 changedfiles.update(mfl[c.manifest].read().keys())
985 else:
971 else:
986 changedfiles.update(c.files)
972 changedfiles.update(c.files)
987 else:
973 else:
988 # record the first changeset introducing this manifest version
974 # record the first changeset introducing this manifest version
989 manifests.setdefault(c.manifest, x)
975 manifests.setdefault(c.manifest, x)
990 # Record a complete list of potentially-changed files in
976 # Record a complete list of potentially-changed files in
991 # this manifest.
977 # this manifest.
992 changedfiles.update(c.files)
978 changedfiles.update(c.files)
993
979
994 return x
980 return x
995
981
996 state = {
982 state = {
997 'clrevorder': clrevorder,
983 'clrevorder': clrevorder,
998 'manifests': manifests,
984 'manifests': manifests,
999 'changedfiles': changedfiles,
985 'changedfiles': changedfiles,
1000 'clrevtomanifestrev': clrevtomanifestrev,
986 'clrevtomanifestrev': clrevtomanifestrev,
1001 }
987 }
1002
988
1003 gen = deltagroup(
989 gen = deltagroup(
1004 self._repo, cl, nodes, True, lookupcl,
990 self._repo, cl, nodes, True, lookupcl,
1005 self._forcedeltaparentprev,
991 self._forcedeltaparentprev,
1006 # Reorder settings are currently ignored for changelog.
1007 True,
1008 ellipses=self._ellipses,
992 ellipses=self._ellipses,
1009 topic=_('changesets'),
993 topic=_('changesets'),
1010 clrevtolocalrev={},
994 clrevtolocalrev={},
1011 fullclnodes=self._fullclnodes,
995 fullclnodes=self._fullclnodes,
1012 precomputedellipsis=self._precomputedellipsis)
996 precomputedellipsis=self._precomputedellipsis)
1013
997
1014 return state, gen
998 return state, gen
1015
999
1016 def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev,
1000 def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev,
1017 manifests, fnodes, source, clrevtolocalrev):
1001 manifests, fnodes, source, clrevtolocalrev):
1018 """Returns an iterator of changegroup chunks containing manifests.
1002 """Returns an iterator of changegroup chunks containing manifests.
1019
1003
1020 `source` is unused here, but is used by extensions like remotefilelog to
1004 `source` is unused here, but is used by extensions like remotefilelog to
1021 change what is sent based in pulls vs pushes, etc.
1005 change what is sent based in pulls vs pushes, etc.
1022 """
1006 """
1023 repo = self._repo
1007 repo = self._repo
1024 mfl = repo.manifestlog
1008 mfl = repo.manifestlog
1025 tmfnodes = {'': manifests}
1009 tmfnodes = {'': manifests}
1026
1010
1027 # Callback for the manifest, used to collect linkrevs for filelog
1011 # Callback for the manifest, used to collect linkrevs for filelog
1028 # revisions.
1012 # revisions.
1029 # Returns the linkrev node (collected in lookupcl).
1013 # Returns the linkrev node (collected in lookupcl).
1030 def makelookupmflinknode(tree, nodes):
1014 def makelookupmflinknode(tree, nodes):
1031 if fastpathlinkrev:
1015 if fastpathlinkrev:
1032 assert not tree
1016 assert not tree
1033 return manifests.__getitem__
1017 return manifests.__getitem__
1034
1018
1035 def lookupmflinknode(x):
1019 def lookupmflinknode(x):
1036 """Callback for looking up the linknode for manifests.
1020 """Callback for looking up the linknode for manifests.
1037
1021
1038 Returns the linkrev node for the specified manifest.
1022 Returns the linkrev node for the specified manifest.
1039
1023
1040 SIDE EFFECT:
1024 SIDE EFFECT:
1041
1025
1042 1) fclnodes gets populated with the list of relevant
1026 1) fclnodes gets populated with the list of relevant
1043 file nodes if we're not using fastpathlinkrev
1027 file nodes if we're not using fastpathlinkrev
1044 2) When treemanifests are in use, collects treemanifest nodes
1028 2) When treemanifests are in use, collects treemanifest nodes
1045 to send
1029 to send
1046
1030
1047 Note that this means manifests must be completely sent to
1031 Note that this means manifests must be completely sent to
1048 the client before you can trust the list of files and
1032 the client before you can trust the list of files and
1049 treemanifests to send.
1033 treemanifests to send.
1050 """
1034 """
1051 clnode = nodes[x]
1035 clnode = nodes[x]
1052 mdata = mfl.get(tree, x).readfast(shallow=True)
1036 mdata = mfl.get(tree, x).readfast(shallow=True)
1053 for p, n, fl in mdata.iterentries():
1037 for p, n, fl in mdata.iterentries():
1054 if fl == 't': # subdirectory manifest
1038 if fl == 't': # subdirectory manifest
1055 subtree = tree + p + '/'
1039 subtree = tree + p + '/'
1056 tmfclnodes = tmfnodes.setdefault(subtree, {})
1040 tmfclnodes = tmfnodes.setdefault(subtree, {})
1057 tmfclnode = tmfclnodes.setdefault(n, clnode)
1041 tmfclnode = tmfclnodes.setdefault(n, clnode)
1058 if clrevorder[clnode] < clrevorder[tmfclnode]:
1042 if clrevorder[clnode] < clrevorder[tmfclnode]:
1059 tmfclnodes[n] = clnode
1043 tmfclnodes[n] = clnode
1060 else:
1044 else:
1061 f = tree + p
1045 f = tree + p
1062 fclnodes = fnodes.setdefault(f, {})
1046 fclnodes = fnodes.setdefault(f, {})
1063 fclnode = fclnodes.setdefault(n, clnode)
1047 fclnode = fclnodes.setdefault(n, clnode)
1064 if clrevorder[clnode] < clrevorder[fclnode]:
1048 if clrevorder[clnode] < clrevorder[fclnode]:
1065 fclnodes[n] = clnode
1049 fclnodes[n] = clnode
1066 return clnode
1050 return clnode
1067 return lookupmflinknode
1051 return lookupmflinknode
1068
1052
1069 while tmfnodes:
1053 while tmfnodes:
1070 tree, nodes = tmfnodes.popitem()
1054 tree, nodes = tmfnodes.popitem()
1071 store = mfl.getstorage(tree)
1055 store = mfl.getstorage(tree)
1072
1056
1073 if not self._filematcher.visitdir(store.tree[:-1] or '.'):
1057 if not self._filematcher.visitdir(store.tree[:-1] or '.'):
1074 # No nodes to send because this directory is out of
1058 # No nodes to send because this directory is out of
1075 # the client's view of the repository (probably
1059 # the client's view of the repository (probably
1076 # because of narrow clones).
1060 # because of narrow clones).
1077 prunednodes = []
1061 prunednodes = []
1078 else:
1062 else:
1079 # Avoid sending any manifest nodes we can prove the
1063 # Avoid sending any manifest nodes we can prove the
1080 # client already has by checking linkrevs. See the
1064 # client already has by checking linkrevs. See the
1081 # related comment in generatefiles().
1065 # related comment in generatefiles().
1082 prunednodes = self._prunemanifests(store, nodes, commonrevs)
1066 prunednodes = self._prunemanifests(store, nodes, commonrevs)
1083 if tree and not prunednodes:
1067 if tree and not prunednodes:
1084 continue
1068 continue
1085
1069
1086 lookupfn = makelookupmflinknode(tree, nodes)
1070 lookupfn = makelookupmflinknode(tree, nodes)
1087
1071
1088 deltas = deltagroup(
1072 deltas = deltagroup(
1089 self._repo, store, prunednodes, False, lookupfn,
1073 self._repo, store, prunednodes, False, lookupfn,
1090 self._forcedeltaparentprev, self._reorder,
1074 self._forcedeltaparentprev,
1091 ellipses=self._ellipses,
1075 ellipses=self._ellipses,
1092 topic=_('manifests'),
1076 topic=_('manifests'),
1093 clrevtolocalrev=clrevtolocalrev,
1077 clrevtolocalrev=clrevtolocalrev,
1094 fullclnodes=self._fullclnodes,
1078 fullclnodes=self._fullclnodes,
1095 precomputedellipsis=self._precomputedellipsis)
1079 precomputedellipsis=self._precomputedellipsis)
1096
1080
1097 yield tree, deltas
1081 yield tree, deltas
1098
1082
1099 def _prunemanifests(self, store, nodes, commonrevs):
1083 def _prunemanifests(self, store, nodes, commonrevs):
1100 # This is split out as a separate method to allow filtering
1084 # This is split out as a separate method to allow filtering
1101 # commonrevs in extension code.
1085 # commonrevs in extension code.
1102 #
1086 #
1103 # TODO(augie): this shouldn't be required, instead we should
1087 # TODO(augie): this shouldn't be required, instead we should
1104 # make filtering of revisions to send delegated to the store
1088 # make filtering of revisions to send delegated to the store
1105 # layer.
1089 # layer.
1106 frev, flr = store.rev, store.linkrev
1090 frev, flr = store.rev, store.linkrev
1107 return [n for n in nodes if flr(frev(n)) not in commonrevs]
1091 return [n for n in nodes if flr(frev(n)) not in commonrevs]
1108
1092
1109 # The 'source' parameter is useful for extensions
1093 # The 'source' parameter is useful for extensions
1110 def generatefiles(self, changedfiles, commonrevs, source,
1094 def generatefiles(self, changedfiles, commonrevs, source,
1111 mfdicts, fastpathlinkrev, fnodes, clrevs):
1095 mfdicts, fastpathlinkrev, fnodes, clrevs):
1112 changedfiles = list(filter(self._filematcher, changedfiles))
1096 changedfiles = list(filter(self._filematcher, changedfiles))
1113
1097
1114 if not fastpathlinkrev:
1098 if not fastpathlinkrev:
1115 def normallinknodes(unused, fname):
1099 def normallinknodes(unused, fname):
1116 return fnodes.get(fname, {})
1100 return fnodes.get(fname, {})
1117 else:
1101 else:
1118 cln = self._repo.changelog.node
1102 cln = self._repo.changelog.node
1119
1103
1120 def normallinknodes(store, fname):
1104 def normallinknodes(store, fname):
1121 flinkrev = store.linkrev
1105 flinkrev = store.linkrev
1122 fnode = store.node
1106 fnode = store.node
1123 revs = ((r, flinkrev(r)) for r in store)
1107 revs = ((r, flinkrev(r)) for r in store)
1124 return dict((fnode(r), cln(lr))
1108 return dict((fnode(r), cln(lr))
1125 for r, lr in revs if lr in clrevs)
1109 for r, lr in revs if lr in clrevs)
1126
1110
1127 clrevtolocalrev = {}
1111 clrevtolocalrev = {}
1128
1112
1129 if self._isshallow:
1113 if self._isshallow:
1130 # In a shallow clone, the linknodes callback needs to also include
1114 # In a shallow clone, the linknodes callback needs to also include
1131 # those file nodes that are in the manifests we sent but weren't
1115 # those file nodes that are in the manifests we sent but weren't
1132 # introduced by those manifests.
1116 # introduced by those manifests.
1133 commonctxs = [self._repo[c] for c in commonrevs]
1117 commonctxs = [self._repo[c] for c in commonrevs]
1134 clrev = self._repo.changelog.rev
1118 clrev = self._repo.changelog.rev
1135
1119
1136 def linknodes(flog, fname):
1120 def linknodes(flog, fname):
1137 for c in commonctxs:
1121 for c in commonctxs:
1138 try:
1122 try:
1139 fnode = c.filenode(fname)
1123 fnode = c.filenode(fname)
1140 clrevtolocalrev[c.rev()] = flog.rev(fnode)
1124 clrevtolocalrev[c.rev()] = flog.rev(fnode)
1141 except error.ManifestLookupError:
1125 except error.ManifestLookupError:
1142 pass
1126 pass
1143 links = normallinknodes(flog, fname)
1127 links = normallinknodes(flog, fname)
1144 if len(links) != len(mfdicts):
1128 if len(links) != len(mfdicts):
1145 for mf, lr in mfdicts:
1129 for mf, lr in mfdicts:
1146 fnode = mf.get(fname, None)
1130 fnode = mf.get(fname, None)
1147 if fnode in links:
1131 if fnode in links:
1148 links[fnode] = min(links[fnode], lr, key=clrev)
1132 links[fnode] = min(links[fnode], lr, key=clrev)
1149 elif fnode:
1133 elif fnode:
1150 links[fnode] = lr
1134 links[fnode] = lr
1151 return links
1135 return links
1152 else:
1136 else:
1153 linknodes = normallinknodes
1137 linknodes = normallinknodes
1154
1138
1155 repo = self._repo
1139 repo = self._repo
1156 progress = repo.ui.makeprogress(_('files'), unit=_('files'),
1140 progress = repo.ui.makeprogress(_('files'), unit=_('files'),
1157 total=len(changedfiles))
1141 total=len(changedfiles))
1158 for i, fname in enumerate(sorted(changedfiles)):
1142 for i, fname in enumerate(sorted(changedfiles)):
1159 filerevlog = repo.file(fname)
1143 filerevlog = repo.file(fname)
1160 if not filerevlog:
1144 if not filerevlog:
1161 raise error.Abort(_("empty or missing file data for %s") %
1145 raise error.Abort(_("empty or missing file data for %s") %
1162 fname)
1146 fname)
1163
1147
1164 clrevtolocalrev.clear()
1148 clrevtolocalrev.clear()
1165
1149
1166 linkrevnodes = linknodes(filerevlog, fname)
1150 linkrevnodes = linknodes(filerevlog, fname)
1167 # Lookup for filenodes, we collected the linkrev nodes above in the
1151 # Lookup for filenodes, we collected the linkrev nodes above in the
1168 # fastpath case and with lookupmf in the slowpath case.
1152 # fastpath case and with lookupmf in the slowpath case.
1169 def lookupfilelog(x):
1153 def lookupfilelog(x):
1170 return linkrevnodes[x]
1154 return linkrevnodes[x]
1171
1155
1172 frev, flr = filerevlog.rev, filerevlog.linkrev
1156 frev, flr = filerevlog.rev, filerevlog.linkrev
1173 # Skip sending any filenode we know the client already
1157 # Skip sending any filenode we know the client already
1174 # has. This avoids over-sending files relatively
1158 # has. This avoids over-sending files relatively
1175 # inexpensively, so it's not a problem if we under-filter
1159 # inexpensively, so it's not a problem if we under-filter
1176 # here.
1160 # here.
1177 filenodes = [n for n in linkrevnodes
1161 filenodes = [n for n in linkrevnodes
1178 if flr(frev(n)) not in commonrevs]
1162 if flr(frev(n)) not in commonrevs]
1179
1163
1180 if not filenodes:
1164 if not filenodes:
1181 continue
1165 continue
1182
1166
1183 progress.update(i + 1, item=fname)
1167 progress.update(i + 1, item=fname)
1184
1168
1185 deltas = deltagroup(
1169 deltas = deltagroup(
1186 self._repo, filerevlog, filenodes, False, lookupfilelog,
1170 self._repo, filerevlog, filenodes, False, lookupfilelog,
1187 self._forcedeltaparentprev, self._reorder,
1171 self._forcedeltaparentprev,
1188 ellipses=self._ellipses,
1172 ellipses=self._ellipses,
1189 clrevtolocalrev=clrevtolocalrev,
1173 clrevtolocalrev=clrevtolocalrev,
1190 fullclnodes=self._fullclnodes,
1174 fullclnodes=self._fullclnodes,
1191 precomputedellipsis=self._precomputedellipsis)
1175 precomputedellipsis=self._precomputedellipsis)
1192
1176
1193 yield fname, deltas
1177 yield fname, deltas
1194
1178
1195 progress.complete()
1179 progress.complete()
1196
1180
1197 def _makecg1packer(repo, filematcher, bundlecaps, ellipses=False,
1181 def _makecg1packer(repo, filematcher, bundlecaps, ellipses=False,
1198 shallow=False, ellipsisroots=None, fullnodes=None):
1182 shallow=False, ellipsisroots=None, fullnodes=None):
1199 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
1183 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
1200 d.node, d.p1node, d.p2node, d.linknode)
1184 d.node, d.p1node, d.p2node, d.linknode)
1201
1185
1202 return cgpacker(repo, filematcher, b'01',
1186 return cgpacker(repo, filematcher, b'01',
1203 allowreorder=None,
1204 builddeltaheader=builddeltaheader,
1187 builddeltaheader=builddeltaheader,
1205 manifestsend=b'',
1188 manifestsend=b'',
1206 forcedeltaparentprev=True,
1189 forcedeltaparentprev=True,
1207 bundlecaps=bundlecaps,
1190 bundlecaps=bundlecaps,
1208 ellipses=ellipses,
1191 ellipses=ellipses,
1209 shallow=shallow,
1192 shallow=shallow,
1210 ellipsisroots=ellipsisroots,
1193 ellipsisroots=ellipsisroots,
1211 fullnodes=fullnodes)
1194 fullnodes=fullnodes)
1212
1195
1213 def _makecg2packer(repo, filematcher, bundlecaps, ellipses=False,
1196 def _makecg2packer(repo, filematcher, bundlecaps, ellipses=False,
1214 shallow=False, ellipsisroots=None, fullnodes=None):
1197 shallow=False, ellipsisroots=None, fullnodes=None):
1215 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack(
1198 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack(
1216 d.node, d.p1node, d.p2node, d.basenode, d.linknode)
1199 d.node, d.p1node, d.p2node, d.basenode, d.linknode)
1217
1200
1218 # Since generaldelta is directly supported by cg2, reordering
1219 # generally doesn't help, so we disable it by default (treating
1220 # bundle.reorder=auto just like bundle.reorder=False).
1221 return cgpacker(repo, filematcher, b'02',
1201 return cgpacker(repo, filematcher, b'02',
1222 allowreorder=False,
1223 builddeltaheader=builddeltaheader,
1202 builddeltaheader=builddeltaheader,
1224 manifestsend=b'',
1203 manifestsend=b'',
1225 bundlecaps=bundlecaps,
1204 bundlecaps=bundlecaps,
1226 ellipses=ellipses,
1205 ellipses=ellipses,
1227 shallow=shallow,
1206 shallow=shallow,
1228 ellipsisroots=ellipsisroots,
1207 ellipsisroots=ellipsisroots,
1229 fullnodes=fullnodes)
1208 fullnodes=fullnodes)
1230
1209
1231 def _makecg3packer(repo, filematcher, bundlecaps, ellipses=False,
1210 def _makecg3packer(repo, filematcher, bundlecaps, ellipses=False,
1232 shallow=False, ellipsisroots=None, fullnodes=None):
1211 shallow=False, ellipsisroots=None, fullnodes=None):
1233 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1212 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1234 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags)
1213 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags)
1235
1214
1236 return cgpacker(repo, filematcher, b'03',
1215 return cgpacker(repo, filematcher, b'03',
1237 allowreorder=False,
1238 builddeltaheader=builddeltaheader,
1216 builddeltaheader=builddeltaheader,
1239 manifestsend=closechunk(),
1217 manifestsend=closechunk(),
1240 bundlecaps=bundlecaps,
1218 bundlecaps=bundlecaps,
1241 ellipses=ellipses,
1219 ellipses=ellipses,
1242 shallow=shallow,
1220 shallow=shallow,
1243 ellipsisroots=ellipsisroots,
1221 ellipsisroots=ellipsisroots,
1244 fullnodes=fullnodes)
1222 fullnodes=fullnodes)
1245
1223
1246 _packermap = {'01': (_makecg1packer, cg1unpacker),
1224 _packermap = {'01': (_makecg1packer, cg1unpacker),
1247 # cg2 adds support for exchanging generaldelta
1225 # cg2 adds support for exchanging generaldelta
1248 '02': (_makecg2packer, cg2unpacker),
1226 '02': (_makecg2packer, cg2unpacker),
1249 # cg3 adds support for exchanging revlog flags and treemanifests
1227 # cg3 adds support for exchanging revlog flags and treemanifests
1250 '03': (_makecg3packer, cg3unpacker),
1228 '03': (_makecg3packer, cg3unpacker),
1251 }
1229 }
1252
1230
1253 def allsupportedversions(repo):
1231 def allsupportedversions(repo):
1254 versions = set(_packermap.keys())
1232 versions = set(_packermap.keys())
1255 if not (repo.ui.configbool('experimental', 'changegroup3') or
1233 if not (repo.ui.configbool('experimental', 'changegroup3') or
1256 repo.ui.configbool('experimental', 'treemanifest') or
1234 repo.ui.configbool('experimental', 'treemanifest') or
1257 'treemanifest' in repo.requirements):
1235 'treemanifest' in repo.requirements):
1258 versions.discard('03')
1236 versions.discard('03')
1259 return versions
1237 return versions
1260
1238
1261 # Changegroup versions that can be applied to the repo
1239 # Changegroup versions that can be applied to the repo
1262 def supportedincomingversions(repo):
1240 def supportedincomingversions(repo):
1263 return allsupportedversions(repo)
1241 return allsupportedversions(repo)
1264
1242
1265 # Changegroup versions that can be created from the repo
1243 # Changegroup versions that can be created from the repo
1266 def supportedoutgoingversions(repo):
1244 def supportedoutgoingversions(repo):
1267 versions = allsupportedversions(repo)
1245 versions = allsupportedversions(repo)
1268 if 'treemanifest' in repo.requirements:
1246 if 'treemanifest' in repo.requirements:
1269 # Versions 01 and 02 support only flat manifests and it's just too
1247 # Versions 01 and 02 support only flat manifests and it's just too
1270 # expensive to convert between the flat manifest and tree manifest on
1248 # expensive to convert between the flat manifest and tree manifest on
1271 # the fly. Since tree manifests are hashed differently, all of history
1249 # the fly. Since tree manifests are hashed differently, all of history
1272 # would have to be converted. Instead, we simply don't even pretend to
1250 # would have to be converted. Instead, we simply don't even pretend to
1273 # support versions 01 and 02.
1251 # support versions 01 and 02.
1274 versions.discard('01')
1252 versions.discard('01')
1275 versions.discard('02')
1253 versions.discard('02')
1276 if repository.NARROW_REQUIREMENT in repo.requirements:
1254 if repository.NARROW_REQUIREMENT in repo.requirements:
1277 # Versions 01 and 02 don't support revlog flags, and we need to
1255 # Versions 01 and 02 don't support revlog flags, and we need to
1278 # support that for stripping and unbundling to work.
1256 # support that for stripping and unbundling to work.
1279 versions.discard('01')
1257 versions.discard('01')
1280 versions.discard('02')
1258 versions.discard('02')
1281 if LFS_REQUIREMENT in repo.requirements:
1259 if LFS_REQUIREMENT in repo.requirements:
1282 # Versions 01 and 02 don't support revlog flags, and we need to
1260 # Versions 01 and 02 don't support revlog flags, and we need to
1283 # mark LFS entries with REVIDX_EXTSTORED.
1261 # mark LFS entries with REVIDX_EXTSTORED.
1284 versions.discard('01')
1262 versions.discard('01')
1285 versions.discard('02')
1263 versions.discard('02')
1286
1264
1287 return versions
1265 return versions
1288
1266
1289 def localversion(repo):
1267 def localversion(repo):
1290 # Finds the best version to use for bundles that are meant to be used
1268 # Finds the best version to use for bundles that are meant to be used
1291 # locally, such as those from strip and shelve, and temporary bundles.
1269 # locally, such as those from strip and shelve, and temporary bundles.
1292 return max(supportedoutgoingversions(repo))
1270 return max(supportedoutgoingversions(repo))
1293
1271
1294 def safeversion(repo):
1272 def safeversion(repo):
1295 # Finds the smallest version that it's safe to assume clients of the repo
1273 # Finds the smallest version that it's safe to assume clients of the repo
1296 # will support. For example, all hg versions that support generaldelta also
1274 # will support. For example, all hg versions that support generaldelta also
1297 # support changegroup 02.
1275 # support changegroup 02.
1298 versions = supportedoutgoingversions(repo)
1276 versions = supportedoutgoingversions(repo)
1299 if 'generaldelta' in repo.requirements:
1277 if 'generaldelta' in repo.requirements:
1300 versions.discard('01')
1278 versions.discard('01')
1301 assert versions
1279 assert versions
1302 return min(versions)
1280 return min(versions)
1303
1281
1304 def getbundler(version, repo, bundlecaps=None, filematcher=None,
1282 def getbundler(version, repo, bundlecaps=None, filematcher=None,
1305 ellipses=False, shallow=False, ellipsisroots=None,
1283 ellipses=False, shallow=False, ellipsisroots=None,
1306 fullnodes=None):
1284 fullnodes=None):
1307 assert version in supportedoutgoingversions(repo)
1285 assert version in supportedoutgoingversions(repo)
1308
1286
1309 if filematcher is None:
1287 if filematcher is None:
1310 filematcher = matchmod.alwaysmatcher(repo.root, '')
1288 filematcher = matchmod.alwaysmatcher(repo.root, '')
1311
1289
1312 if version == '01' and not filematcher.always():
1290 if version == '01' and not filematcher.always():
1313 raise error.ProgrammingError('version 01 changegroups do not support '
1291 raise error.ProgrammingError('version 01 changegroups do not support '
1314 'sparse file matchers')
1292 'sparse file matchers')
1315
1293
1316 if ellipses and version in (b'01', b'02'):
1294 if ellipses and version in (b'01', b'02'):
1317 raise error.Abort(
1295 raise error.Abort(
1318 _('ellipsis nodes require at least cg3 on client and server, '
1296 _('ellipsis nodes require at least cg3 on client and server, '
1319 'but negotiated version %s') % version)
1297 'but negotiated version %s') % version)
1320
1298
1321 # Requested files could include files not in the local store. So
1299 # Requested files could include files not in the local store. So
1322 # filter those out.
1300 # filter those out.
1323 filematcher = matchmod.intersectmatchers(repo.narrowmatch(),
1301 filematcher = matchmod.intersectmatchers(repo.narrowmatch(),
1324 filematcher)
1302 filematcher)
1325
1303
1326 fn = _packermap[version][0]
1304 fn = _packermap[version][0]
1327 return fn(repo, filematcher, bundlecaps, ellipses=ellipses,
1305 return fn(repo, filematcher, bundlecaps, ellipses=ellipses,
1328 shallow=shallow, ellipsisroots=ellipsisroots,
1306 shallow=shallow, ellipsisroots=ellipsisroots,
1329 fullnodes=fullnodes)
1307 fullnodes=fullnodes)
1330
1308
1331 def getunbundler(version, fh, alg, extras=None):
1309 def getunbundler(version, fh, alg, extras=None):
1332 return _packermap[version][1](fh, alg, extras=extras)
1310 return _packermap[version][1](fh, alg, extras=extras)
1333
1311
1334 def _changegroupinfo(repo, nodes, source):
1312 def _changegroupinfo(repo, nodes, source):
1335 if repo.ui.verbose or source == 'bundle':
1313 if repo.ui.verbose or source == 'bundle':
1336 repo.ui.status(_("%d changesets found\n") % len(nodes))
1314 repo.ui.status(_("%d changesets found\n") % len(nodes))
1337 if repo.ui.debugflag:
1315 if repo.ui.debugflag:
1338 repo.ui.debug("list of changesets:\n")
1316 repo.ui.debug("list of changesets:\n")
1339 for node in nodes:
1317 for node in nodes:
1340 repo.ui.debug("%s\n" % hex(node))
1318 repo.ui.debug("%s\n" % hex(node))
1341
1319
1342 def makechangegroup(repo, outgoing, version, source, fastpath=False,
1320 def makechangegroup(repo, outgoing, version, source, fastpath=False,
1343 bundlecaps=None):
1321 bundlecaps=None):
1344 cgstream = makestream(repo, outgoing, version, source,
1322 cgstream = makestream(repo, outgoing, version, source,
1345 fastpath=fastpath, bundlecaps=bundlecaps)
1323 fastpath=fastpath, bundlecaps=bundlecaps)
1346 return getunbundler(version, util.chunkbuffer(cgstream), None,
1324 return getunbundler(version, util.chunkbuffer(cgstream), None,
1347 {'clcount': len(outgoing.missing) })
1325 {'clcount': len(outgoing.missing) })
1348
1326
1349 def makestream(repo, outgoing, version, source, fastpath=False,
1327 def makestream(repo, outgoing, version, source, fastpath=False,
1350 bundlecaps=None, filematcher=None):
1328 bundlecaps=None, filematcher=None):
1351 bundler = getbundler(version, repo, bundlecaps=bundlecaps,
1329 bundler = getbundler(version, repo, bundlecaps=bundlecaps,
1352 filematcher=filematcher)
1330 filematcher=filematcher)
1353
1331
1354 repo = repo.unfiltered()
1332 repo = repo.unfiltered()
1355 commonrevs = outgoing.common
1333 commonrevs = outgoing.common
1356 csets = outgoing.missing
1334 csets = outgoing.missing
1357 heads = outgoing.missingheads
1335 heads = outgoing.missingheads
1358 # We go through the fast path if we get told to, or if all (unfiltered
1336 # We go through the fast path if we get told to, or if all (unfiltered
1359 # heads have been requested (since we then know there all linkrevs will
1337 # heads have been requested (since we then know there all linkrevs will
1360 # be pulled by the client).
1338 # be pulled by the client).
1361 heads.sort()
1339 heads.sort()
1362 fastpathlinkrev = fastpath or (
1340 fastpathlinkrev = fastpath or (
1363 repo.filtername is None and heads == sorted(repo.heads()))
1341 repo.filtername is None and heads == sorted(repo.heads()))
1364
1342
1365 repo.hook('preoutgoing', throw=True, source=source)
1343 repo.hook('preoutgoing', throw=True, source=source)
1366 _changegroupinfo(repo, csets, source)
1344 _changegroupinfo(repo, csets, source)
1367 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
1345 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
1368
1346
1369 def _addchangegroupfiles(repo, source, revmap, trp, expectedfiles, needfiles):
1347 def _addchangegroupfiles(repo, source, revmap, trp, expectedfiles, needfiles):
1370 revisions = 0
1348 revisions = 0
1371 files = 0
1349 files = 0
1372 progress = repo.ui.makeprogress(_('files'), unit=_('files'),
1350 progress = repo.ui.makeprogress(_('files'), unit=_('files'),
1373 total=expectedfiles)
1351 total=expectedfiles)
1374 for chunkdata in iter(source.filelogheader, {}):
1352 for chunkdata in iter(source.filelogheader, {}):
1375 files += 1
1353 files += 1
1376 f = chunkdata["filename"]
1354 f = chunkdata["filename"]
1377 repo.ui.debug("adding %s revisions\n" % f)
1355 repo.ui.debug("adding %s revisions\n" % f)
1378 progress.increment()
1356 progress.increment()
1379 fl = repo.file(f)
1357 fl = repo.file(f)
1380 o = len(fl)
1358 o = len(fl)
1381 try:
1359 try:
1382 deltas = source.deltaiter()
1360 deltas = source.deltaiter()
1383 if not fl.addgroup(deltas, revmap, trp):
1361 if not fl.addgroup(deltas, revmap, trp):
1384 raise error.Abort(_("received file revlog group is empty"))
1362 raise error.Abort(_("received file revlog group is empty"))
1385 except error.CensoredBaseError as e:
1363 except error.CensoredBaseError as e:
1386 raise error.Abort(_("received delta base is censored: %s") % e)
1364 raise error.Abort(_("received delta base is censored: %s") % e)
1387 revisions += len(fl) - o
1365 revisions += len(fl) - o
1388 if f in needfiles:
1366 if f in needfiles:
1389 needs = needfiles[f]
1367 needs = needfiles[f]
1390 for new in pycompat.xrange(o, len(fl)):
1368 for new in pycompat.xrange(o, len(fl)):
1391 n = fl.node(new)
1369 n = fl.node(new)
1392 if n in needs:
1370 if n in needs:
1393 needs.remove(n)
1371 needs.remove(n)
1394 else:
1372 else:
1395 raise error.Abort(
1373 raise error.Abort(
1396 _("received spurious file revlog entry"))
1374 _("received spurious file revlog entry"))
1397 if not needs:
1375 if not needs:
1398 del needfiles[f]
1376 del needfiles[f]
1399 progress.complete()
1377 progress.complete()
1400
1378
1401 for f, needs in needfiles.iteritems():
1379 for f, needs in needfiles.iteritems():
1402 fl = repo.file(f)
1380 fl = repo.file(f)
1403 for n in needs:
1381 for n in needs:
1404 try:
1382 try:
1405 fl.rev(n)
1383 fl.rev(n)
1406 except error.LookupError:
1384 except error.LookupError:
1407 raise error.Abort(
1385 raise error.Abort(
1408 _('missing file data for %s:%s - run hg verify') %
1386 _('missing file data for %s:%s - run hg verify') %
1409 (f, hex(n)))
1387 (f, hex(n)))
1410
1388
1411 return revisions, files
1389 return revisions, files
@@ -1,1408 +1,1404 b''
1 # configitems.py - centralized declaration of configuration option
1 # configitems.py - centralized declaration of configuration option
2 #
2 #
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
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 functools
10 import functools
11 import re
11 import re
12
12
13 from . import (
13 from . import (
14 encoding,
14 encoding,
15 error,
15 error,
16 )
16 )
17
17
18 def loadconfigtable(ui, extname, configtable):
18 def loadconfigtable(ui, extname, configtable):
19 """update config item known to the ui with the extension ones"""
19 """update config item known to the ui with the extension ones"""
20 for section, items in sorted(configtable.items()):
20 for section, items in sorted(configtable.items()):
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
22 knownkeys = set(knownitems)
22 knownkeys = set(knownitems)
23 newkeys = set(items)
23 newkeys = set(items)
24 for key in sorted(knownkeys & newkeys):
24 for key in sorted(knownkeys & newkeys):
25 msg = "extension '%s' overwrite config item '%s.%s'"
25 msg = "extension '%s' overwrite config item '%s.%s'"
26 msg %= (extname, section, key)
26 msg %= (extname, section, key)
27 ui.develwarn(msg, config='warn-config')
27 ui.develwarn(msg, config='warn-config')
28
28
29 knownitems.update(items)
29 knownitems.update(items)
30
30
31 class configitem(object):
31 class configitem(object):
32 """represent a known config item
32 """represent a known config item
33
33
34 :section: the official config section where to find this item,
34 :section: the official config section where to find this item,
35 :name: the official name within the section,
35 :name: the official name within the section,
36 :default: default value for this item,
36 :default: default value for this item,
37 :alias: optional list of tuples as alternatives,
37 :alias: optional list of tuples as alternatives,
38 :generic: this is a generic definition, match name using regular expression.
38 :generic: this is a generic definition, match name using regular expression.
39 """
39 """
40
40
41 def __init__(self, section, name, default=None, alias=(),
41 def __init__(self, section, name, default=None, alias=(),
42 generic=False, priority=0):
42 generic=False, priority=0):
43 self.section = section
43 self.section = section
44 self.name = name
44 self.name = name
45 self.default = default
45 self.default = default
46 self.alias = list(alias)
46 self.alias = list(alias)
47 self.generic = generic
47 self.generic = generic
48 self.priority = priority
48 self.priority = priority
49 self._re = None
49 self._re = None
50 if generic:
50 if generic:
51 self._re = re.compile(self.name)
51 self._re = re.compile(self.name)
52
52
53 class itemregister(dict):
53 class itemregister(dict):
54 """A specialized dictionary that can handle wild-card selection"""
54 """A specialized dictionary that can handle wild-card selection"""
55
55
56 def __init__(self):
56 def __init__(self):
57 super(itemregister, self).__init__()
57 super(itemregister, self).__init__()
58 self._generics = set()
58 self._generics = set()
59
59
60 def update(self, other):
60 def update(self, other):
61 super(itemregister, self).update(other)
61 super(itemregister, self).update(other)
62 self._generics.update(other._generics)
62 self._generics.update(other._generics)
63
63
64 def __setitem__(self, key, item):
64 def __setitem__(self, key, item):
65 super(itemregister, self).__setitem__(key, item)
65 super(itemregister, self).__setitem__(key, item)
66 if item.generic:
66 if item.generic:
67 self._generics.add(item)
67 self._generics.add(item)
68
68
69 def get(self, key):
69 def get(self, key):
70 baseitem = super(itemregister, self).get(key)
70 baseitem = super(itemregister, self).get(key)
71 if baseitem is not None and not baseitem.generic:
71 if baseitem is not None and not baseitem.generic:
72 return baseitem
72 return baseitem
73
73
74 # search for a matching generic item
74 # search for a matching generic item
75 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
75 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
76 for item in generics:
76 for item in generics:
77 # we use 'match' instead of 'search' to make the matching simpler
77 # we use 'match' instead of 'search' to make the matching simpler
78 # for people unfamiliar with regular expression. Having the match
78 # for people unfamiliar with regular expression. Having the match
79 # rooted to the start of the string will produce less surprising
79 # rooted to the start of the string will produce less surprising
80 # result for user writing simple regex for sub-attribute.
80 # result for user writing simple regex for sub-attribute.
81 #
81 #
82 # For example using "color\..*" match produces an unsurprising
82 # For example using "color\..*" match produces an unsurprising
83 # result, while using search could suddenly match apparently
83 # result, while using search could suddenly match apparently
84 # unrelated configuration that happens to contains "color."
84 # unrelated configuration that happens to contains "color."
85 # anywhere. This is a tradeoff where we favor requiring ".*" on
85 # anywhere. This is a tradeoff where we favor requiring ".*" on
86 # some match to avoid the need to prefix most pattern with "^".
86 # some match to avoid the need to prefix most pattern with "^".
87 # The "^" seems more error prone.
87 # The "^" seems more error prone.
88 if item._re.match(key):
88 if item._re.match(key):
89 return item
89 return item
90
90
91 return None
91 return None
92
92
93 coreitems = {}
93 coreitems = {}
94
94
95 def _register(configtable, *args, **kwargs):
95 def _register(configtable, *args, **kwargs):
96 item = configitem(*args, **kwargs)
96 item = configitem(*args, **kwargs)
97 section = configtable.setdefault(item.section, itemregister())
97 section = configtable.setdefault(item.section, itemregister())
98 if item.name in section:
98 if item.name in section:
99 msg = "duplicated config item registration for '%s.%s'"
99 msg = "duplicated config item registration for '%s.%s'"
100 raise error.ProgrammingError(msg % (item.section, item.name))
100 raise error.ProgrammingError(msg % (item.section, item.name))
101 section[item.name] = item
101 section[item.name] = item
102
102
103 # special value for case where the default is derived from other values
103 # special value for case where the default is derived from other values
104 dynamicdefault = object()
104 dynamicdefault = object()
105
105
106 # Registering actual config items
106 # Registering actual config items
107
107
108 def getitemregister(configtable):
108 def getitemregister(configtable):
109 f = functools.partial(_register, configtable)
109 f = functools.partial(_register, configtable)
110 # export pseudo enum as configitem.*
110 # export pseudo enum as configitem.*
111 f.dynamicdefault = dynamicdefault
111 f.dynamicdefault = dynamicdefault
112 return f
112 return f
113
113
114 coreconfigitem = getitemregister(coreitems)
114 coreconfigitem = getitemregister(coreitems)
115
115
116 coreconfigitem('alias', '.*',
116 coreconfigitem('alias', '.*',
117 default=dynamicdefault,
117 default=dynamicdefault,
118 generic=True,
118 generic=True,
119 )
119 )
120 coreconfigitem('annotate', 'nodates',
120 coreconfigitem('annotate', 'nodates',
121 default=False,
121 default=False,
122 )
122 )
123 coreconfigitem('annotate', 'showfunc',
123 coreconfigitem('annotate', 'showfunc',
124 default=False,
124 default=False,
125 )
125 )
126 coreconfigitem('annotate', 'unified',
126 coreconfigitem('annotate', 'unified',
127 default=None,
127 default=None,
128 )
128 )
129 coreconfigitem('annotate', 'git',
129 coreconfigitem('annotate', 'git',
130 default=False,
130 default=False,
131 )
131 )
132 coreconfigitem('annotate', 'ignorews',
132 coreconfigitem('annotate', 'ignorews',
133 default=False,
133 default=False,
134 )
134 )
135 coreconfigitem('annotate', 'ignorewsamount',
135 coreconfigitem('annotate', 'ignorewsamount',
136 default=False,
136 default=False,
137 )
137 )
138 coreconfigitem('annotate', 'ignoreblanklines',
138 coreconfigitem('annotate', 'ignoreblanklines',
139 default=False,
139 default=False,
140 )
140 )
141 coreconfigitem('annotate', 'ignorewseol',
141 coreconfigitem('annotate', 'ignorewseol',
142 default=False,
142 default=False,
143 )
143 )
144 coreconfigitem('annotate', 'nobinary',
144 coreconfigitem('annotate', 'nobinary',
145 default=False,
145 default=False,
146 )
146 )
147 coreconfigitem('annotate', 'noprefix',
147 coreconfigitem('annotate', 'noprefix',
148 default=False,
148 default=False,
149 )
149 )
150 coreconfigitem('annotate', 'word-diff',
150 coreconfigitem('annotate', 'word-diff',
151 default=False,
151 default=False,
152 )
152 )
153 coreconfigitem('auth', 'cookiefile',
153 coreconfigitem('auth', 'cookiefile',
154 default=None,
154 default=None,
155 )
155 )
156 # bookmarks.pushing: internal hack for discovery
156 # bookmarks.pushing: internal hack for discovery
157 coreconfigitem('bookmarks', 'pushing',
157 coreconfigitem('bookmarks', 'pushing',
158 default=list,
158 default=list,
159 )
159 )
160 # bundle.mainreporoot: internal hack for bundlerepo
160 # bundle.mainreporoot: internal hack for bundlerepo
161 coreconfigitem('bundle', 'mainreporoot',
161 coreconfigitem('bundle', 'mainreporoot',
162 default='',
162 default='',
163 )
163 )
164 # bundle.reorder: experimental config
165 coreconfigitem('bundle', 'reorder',
166 default='auto',
167 )
168 coreconfigitem('censor', 'policy',
164 coreconfigitem('censor', 'policy',
169 default='abort',
165 default='abort',
170 )
166 )
171 coreconfigitem('chgserver', 'idletimeout',
167 coreconfigitem('chgserver', 'idletimeout',
172 default=3600,
168 default=3600,
173 )
169 )
174 coreconfigitem('chgserver', 'skiphash',
170 coreconfigitem('chgserver', 'skiphash',
175 default=False,
171 default=False,
176 )
172 )
177 coreconfigitem('cmdserver', 'log',
173 coreconfigitem('cmdserver', 'log',
178 default=None,
174 default=None,
179 )
175 )
180 coreconfigitem('color', '.*',
176 coreconfigitem('color', '.*',
181 default=None,
177 default=None,
182 generic=True,
178 generic=True,
183 )
179 )
184 coreconfigitem('color', 'mode',
180 coreconfigitem('color', 'mode',
185 default='auto',
181 default='auto',
186 )
182 )
187 coreconfigitem('color', 'pagermode',
183 coreconfigitem('color', 'pagermode',
188 default=dynamicdefault,
184 default=dynamicdefault,
189 )
185 )
190 coreconfigitem('commands', 'grep.all-files',
186 coreconfigitem('commands', 'grep.all-files',
191 default=False,
187 default=False,
192 )
188 )
193 coreconfigitem('commands', 'resolve.confirm',
189 coreconfigitem('commands', 'resolve.confirm',
194 default=False,
190 default=False,
195 )
191 )
196 coreconfigitem('commands', 'resolve.explicit-re-merge',
192 coreconfigitem('commands', 'resolve.explicit-re-merge',
197 default=False,
193 default=False,
198 )
194 )
199 coreconfigitem('commands', 'resolve.mark-check',
195 coreconfigitem('commands', 'resolve.mark-check',
200 default='none',
196 default='none',
201 )
197 )
202 coreconfigitem('commands', 'show.aliasprefix',
198 coreconfigitem('commands', 'show.aliasprefix',
203 default=list,
199 default=list,
204 )
200 )
205 coreconfigitem('commands', 'status.relative',
201 coreconfigitem('commands', 'status.relative',
206 default=False,
202 default=False,
207 )
203 )
208 coreconfigitem('commands', 'status.skipstates',
204 coreconfigitem('commands', 'status.skipstates',
209 default=[],
205 default=[],
210 )
206 )
211 coreconfigitem('commands', 'status.terse',
207 coreconfigitem('commands', 'status.terse',
212 default='',
208 default='',
213 )
209 )
214 coreconfigitem('commands', 'status.verbose',
210 coreconfigitem('commands', 'status.verbose',
215 default=False,
211 default=False,
216 )
212 )
217 coreconfigitem('commands', 'update.check',
213 coreconfigitem('commands', 'update.check',
218 default=None,
214 default=None,
219 )
215 )
220 coreconfigitem('commands', 'update.requiredest',
216 coreconfigitem('commands', 'update.requiredest',
221 default=False,
217 default=False,
222 )
218 )
223 coreconfigitem('committemplate', '.*',
219 coreconfigitem('committemplate', '.*',
224 default=None,
220 default=None,
225 generic=True,
221 generic=True,
226 )
222 )
227 coreconfigitem('convert', 'bzr.saverev',
223 coreconfigitem('convert', 'bzr.saverev',
228 default=True,
224 default=True,
229 )
225 )
230 coreconfigitem('convert', 'cvsps.cache',
226 coreconfigitem('convert', 'cvsps.cache',
231 default=True,
227 default=True,
232 )
228 )
233 coreconfigitem('convert', 'cvsps.fuzz',
229 coreconfigitem('convert', 'cvsps.fuzz',
234 default=60,
230 default=60,
235 )
231 )
236 coreconfigitem('convert', 'cvsps.logencoding',
232 coreconfigitem('convert', 'cvsps.logencoding',
237 default=None,
233 default=None,
238 )
234 )
239 coreconfigitem('convert', 'cvsps.mergefrom',
235 coreconfigitem('convert', 'cvsps.mergefrom',
240 default=None,
236 default=None,
241 )
237 )
242 coreconfigitem('convert', 'cvsps.mergeto',
238 coreconfigitem('convert', 'cvsps.mergeto',
243 default=None,
239 default=None,
244 )
240 )
245 coreconfigitem('convert', 'git.committeractions',
241 coreconfigitem('convert', 'git.committeractions',
246 default=lambda: ['messagedifferent'],
242 default=lambda: ['messagedifferent'],
247 )
243 )
248 coreconfigitem('convert', 'git.extrakeys',
244 coreconfigitem('convert', 'git.extrakeys',
249 default=list,
245 default=list,
250 )
246 )
251 coreconfigitem('convert', 'git.findcopiesharder',
247 coreconfigitem('convert', 'git.findcopiesharder',
252 default=False,
248 default=False,
253 )
249 )
254 coreconfigitem('convert', 'git.remoteprefix',
250 coreconfigitem('convert', 'git.remoteprefix',
255 default='remote',
251 default='remote',
256 )
252 )
257 coreconfigitem('convert', 'git.renamelimit',
253 coreconfigitem('convert', 'git.renamelimit',
258 default=400,
254 default=400,
259 )
255 )
260 coreconfigitem('convert', 'git.saverev',
256 coreconfigitem('convert', 'git.saverev',
261 default=True,
257 default=True,
262 )
258 )
263 coreconfigitem('convert', 'git.similarity',
259 coreconfigitem('convert', 'git.similarity',
264 default=50,
260 default=50,
265 )
261 )
266 coreconfigitem('convert', 'git.skipsubmodules',
262 coreconfigitem('convert', 'git.skipsubmodules',
267 default=False,
263 default=False,
268 )
264 )
269 coreconfigitem('convert', 'hg.clonebranches',
265 coreconfigitem('convert', 'hg.clonebranches',
270 default=False,
266 default=False,
271 )
267 )
272 coreconfigitem('convert', 'hg.ignoreerrors',
268 coreconfigitem('convert', 'hg.ignoreerrors',
273 default=False,
269 default=False,
274 )
270 )
275 coreconfigitem('convert', 'hg.revs',
271 coreconfigitem('convert', 'hg.revs',
276 default=None,
272 default=None,
277 )
273 )
278 coreconfigitem('convert', 'hg.saverev',
274 coreconfigitem('convert', 'hg.saverev',
279 default=False,
275 default=False,
280 )
276 )
281 coreconfigitem('convert', 'hg.sourcename',
277 coreconfigitem('convert', 'hg.sourcename',
282 default=None,
278 default=None,
283 )
279 )
284 coreconfigitem('convert', 'hg.startrev',
280 coreconfigitem('convert', 'hg.startrev',
285 default=None,
281 default=None,
286 )
282 )
287 coreconfigitem('convert', 'hg.tagsbranch',
283 coreconfigitem('convert', 'hg.tagsbranch',
288 default='default',
284 default='default',
289 )
285 )
290 coreconfigitem('convert', 'hg.usebranchnames',
286 coreconfigitem('convert', 'hg.usebranchnames',
291 default=True,
287 default=True,
292 )
288 )
293 coreconfigitem('convert', 'ignoreancestorcheck',
289 coreconfigitem('convert', 'ignoreancestorcheck',
294 default=False,
290 default=False,
295 )
291 )
296 coreconfigitem('convert', 'localtimezone',
292 coreconfigitem('convert', 'localtimezone',
297 default=False,
293 default=False,
298 )
294 )
299 coreconfigitem('convert', 'p4.encoding',
295 coreconfigitem('convert', 'p4.encoding',
300 default=dynamicdefault,
296 default=dynamicdefault,
301 )
297 )
302 coreconfigitem('convert', 'p4.startrev',
298 coreconfigitem('convert', 'p4.startrev',
303 default=0,
299 default=0,
304 )
300 )
305 coreconfigitem('convert', 'skiptags',
301 coreconfigitem('convert', 'skiptags',
306 default=False,
302 default=False,
307 )
303 )
308 coreconfigitem('convert', 'svn.debugsvnlog',
304 coreconfigitem('convert', 'svn.debugsvnlog',
309 default=True,
305 default=True,
310 )
306 )
311 coreconfigitem('convert', 'svn.trunk',
307 coreconfigitem('convert', 'svn.trunk',
312 default=None,
308 default=None,
313 )
309 )
314 coreconfigitem('convert', 'svn.tags',
310 coreconfigitem('convert', 'svn.tags',
315 default=None,
311 default=None,
316 )
312 )
317 coreconfigitem('convert', 'svn.branches',
313 coreconfigitem('convert', 'svn.branches',
318 default=None,
314 default=None,
319 )
315 )
320 coreconfigitem('convert', 'svn.startrev',
316 coreconfigitem('convert', 'svn.startrev',
321 default=0,
317 default=0,
322 )
318 )
323 coreconfigitem('debug', 'dirstate.delaywrite',
319 coreconfigitem('debug', 'dirstate.delaywrite',
324 default=0,
320 default=0,
325 )
321 )
326 coreconfigitem('defaults', '.*',
322 coreconfigitem('defaults', '.*',
327 default=None,
323 default=None,
328 generic=True,
324 generic=True,
329 )
325 )
330 coreconfigitem('devel', 'all-warnings',
326 coreconfigitem('devel', 'all-warnings',
331 default=False,
327 default=False,
332 )
328 )
333 coreconfigitem('devel', 'bundle2.debug',
329 coreconfigitem('devel', 'bundle2.debug',
334 default=False,
330 default=False,
335 )
331 )
336 coreconfigitem('devel', 'cache-vfs',
332 coreconfigitem('devel', 'cache-vfs',
337 default=None,
333 default=None,
338 )
334 )
339 coreconfigitem('devel', 'check-locks',
335 coreconfigitem('devel', 'check-locks',
340 default=False,
336 default=False,
341 )
337 )
342 coreconfigitem('devel', 'check-relroot',
338 coreconfigitem('devel', 'check-relroot',
343 default=False,
339 default=False,
344 )
340 )
345 coreconfigitem('devel', 'default-date',
341 coreconfigitem('devel', 'default-date',
346 default=None,
342 default=None,
347 )
343 )
348 coreconfigitem('devel', 'deprec-warn',
344 coreconfigitem('devel', 'deprec-warn',
349 default=False,
345 default=False,
350 )
346 )
351 coreconfigitem('devel', 'disableloaddefaultcerts',
347 coreconfigitem('devel', 'disableloaddefaultcerts',
352 default=False,
348 default=False,
353 )
349 )
354 coreconfigitem('devel', 'warn-empty-changegroup',
350 coreconfigitem('devel', 'warn-empty-changegroup',
355 default=False,
351 default=False,
356 )
352 )
357 coreconfigitem('devel', 'legacy.exchange',
353 coreconfigitem('devel', 'legacy.exchange',
358 default=list,
354 default=list,
359 )
355 )
360 coreconfigitem('devel', 'servercafile',
356 coreconfigitem('devel', 'servercafile',
361 default='',
357 default='',
362 )
358 )
363 coreconfigitem('devel', 'serverexactprotocol',
359 coreconfigitem('devel', 'serverexactprotocol',
364 default='',
360 default='',
365 )
361 )
366 coreconfigitem('devel', 'serverrequirecert',
362 coreconfigitem('devel', 'serverrequirecert',
367 default=False,
363 default=False,
368 )
364 )
369 coreconfigitem('devel', 'strip-obsmarkers',
365 coreconfigitem('devel', 'strip-obsmarkers',
370 default=True,
366 default=True,
371 )
367 )
372 coreconfigitem('devel', 'warn-config',
368 coreconfigitem('devel', 'warn-config',
373 default=None,
369 default=None,
374 )
370 )
375 coreconfigitem('devel', 'warn-config-default',
371 coreconfigitem('devel', 'warn-config-default',
376 default=None,
372 default=None,
377 )
373 )
378 coreconfigitem('devel', 'user.obsmarker',
374 coreconfigitem('devel', 'user.obsmarker',
379 default=None,
375 default=None,
380 )
376 )
381 coreconfigitem('devel', 'warn-config-unknown',
377 coreconfigitem('devel', 'warn-config-unknown',
382 default=None,
378 default=None,
383 )
379 )
384 coreconfigitem('devel', 'debug.extensions',
380 coreconfigitem('devel', 'debug.extensions',
385 default=False,
381 default=False,
386 )
382 )
387 coreconfigitem('devel', 'debug.peer-request',
383 coreconfigitem('devel', 'debug.peer-request',
388 default=False,
384 default=False,
389 )
385 )
390 coreconfigitem('diff', 'nodates',
386 coreconfigitem('diff', 'nodates',
391 default=False,
387 default=False,
392 )
388 )
393 coreconfigitem('diff', 'showfunc',
389 coreconfigitem('diff', 'showfunc',
394 default=False,
390 default=False,
395 )
391 )
396 coreconfigitem('diff', 'unified',
392 coreconfigitem('diff', 'unified',
397 default=None,
393 default=None,
398 )
394 )
399 coreconfigitem('diff', 'git',
395 coreconfigitem('diff', 'git',
400 default=False,
396 default=False,
401 )
397 )
402 coreconfigitem('diff', 'ignorews',
398 coreconfigitem('diff', 'ignorews',
403 default=False,
399 default=False,
404 )
400 )
405 coreconfigitem('diff', 'ignorewsamount',
401 coreconfigitem('diff', 'ignorewsamount',
406 default=False,
402 default=False,
407 )
403 )
408 coreconfigitem('diff', 'ignoreblanklines',
404 coreconfigitem('diff', 'ignoreblanklines',
409 default=False,
405 default=False,
410 )
406 )
411 coreconfigitem('diff', 'ignorewseol',
407 coreconfigitem('diff', 'ignorewseol',
412 default=False,
408 default=False,
413 )
409 )
414 coreconfigitem('diff', 'nobinary',
410 coreconfigitem('diff', 'nobinary',
415 default=False,
411 default=False,
416 )
412 )
417 coreconfigitem('diff', 'noprefix',
413 coreconfigitem('diff', 'noprefix',
418 default=False,
414 default=False,
419 )
415 )
420 coreconfigitem('diff', 'word-diff',
416 coreconfigitem('diff', 'word-diff',
421 default=False,
417 default=False,
422 )
418 )
423 coreconfigitem('email', 'bcc',
419 coreconfigitem('email', 'bcc',
424 default=None,
420 default=None,
425 )
421 )
426 coreconfigitem('email', 'cc',
422 coreconfigitem('email', 'cc',
427 default=None,
423 default=None,
428 )
424 )
429 coreconfigitem('email', 'charsets',
425 coreconfigitem('email', 'charsets',
430 default=list,
426 default=list,
431 )
427 )
432 coreconfigitem('email', 'from',
428 coreconfigitem('email', 'from',
433 default=None,
429 default=None,
434 )
430 )
435 coreconfigitem('email', 'method',
431 coreconfigitem('email', 'method',
436 default='smtp',
432 default='smtp',
437 )
433 )
438 coreconfigitem('email', 'reply-to',
434 coreconfigitem('email', 'reply-to',
439 default=None,
435 default=None,
440 )
436 )
441 coreconfigitem('email', 'to',
437 coreconfigitem('email', 'to',
442 default=None,
438 default=None,
443 )
439 )
444 coreconfigitem('experimental', 'archivemetatemplate',
440 coreconfigitem('experimental', 'archivemetatemplate',
445 default=dynamicdefault,
441 default=dynamicdefault,
446 )
442 )
447 coreconfigitem('experimental', 'bundle-phases',
443 coreconfigitem('experimental', 'bundle-phases',
448 default=False,
444 default=False,
449 )
445 )
450 coreconfigitem('experimental', 'bundle2-advertise',
446 coreconfigitem('experimental', 'bundle2-advertise',
451 default=True,
447 default=True,
452 )
448 )
453 coreconfigitem('experimental', 'bundle2-output-capture',
449 coreconfigitem('experimental', 'bundle2-output-capture',
454 default=False,
450 default=False,
455 )
451 )
456 coreconfigitem('experimental', 'bundle2.pushback',
452 coreconfigitem('experimental', 'bundle2.pushback',
457 default=False,
453 default=False,
458 )
454 )
459 coreconfigitem('experimental', 'bundle2lazylocking',
455 coreconfigitem('experimental', 'bundle2lazylocking',
460 default=False,
456 default=False,
461 )
457 )
462 coreconfigitem('experimental', 'bundlecomplevel',
458 coreconfigitem('experimental', 'bundlecomplevel',
463 default=None,
459 default=None,
464 )
460 )
465 coreconfigitem('experimental', 'bundlecomplevel.bzip2',
461 coreconfigitem('experimental', 'bundlecomplevel.bzip2',
466 default=None,
462 default=None,
467 )
463 )
468 coreconfigitem('experimental', 'bundlecomplevel.gzip',
464 coreconfigitem('experimental', 'bundlecomplevel.gzip',
469 default=None,
465 default=None,
470 )
466 )
471 coreconfigitem('experimental', 'bundlecomplevel.none',
467 coreconfigitem('experimental', 'bundlecomplevel.none',
472 default=None,
468 default=None,
473 )
469 )
474 coreconfigitem('experimental', 'bundlecomplevel.zstd',
470 coreconfigitem('experimental', 'bundlecomplevel.zstd',
475 default=None,
471 default=None,
476 )
472 )
477 coreconfigitem('experimental', 'changegroup3',
473 coreconfigitem('experimental', 'changegroup3',
478 default=False,
474 default=False,
479 )
475 )
480 coreconfigitem('experimental', 'clientcompressionengines',
476 coreconfigitem('experimental', 'clientcompressionengines',
481 default=list,
477 default=list,
482 )
478 )
483 coreconfigitem('experimental', 'copytrace',
479 coreconfigitem('experimental', 'copytrace',
484 default='on',
480 default='on',
485 )
481 )
486 coreconfigitem('experimental', 'copytrace.movecandidateslimit',
482 coreconfigitem('experimental', 'copytrace.movecandidateslimit',
487 default=100,
483 default=100,
488 )
484 )
489 coreconfigitem('experimental', 'copytrace.sourcecommitlimit',
485 coreconfigitem('experimental', 'copytrace.sourcecommitlimit',
490 default=100,
486 default=100,
491 )
487 )
492 coreconfigitem('experimental', 'crecordtest',
488 coreconfigitem('experimental', 'crecordtest',
493 default=None,
489 default=None,
494 )
490 )
495 coreconfigitem('experimental', 'directaccess',
491 coreconfigitem('experimental', 'directaccess',
496 default=False,
492 default=False,
497 )
493 )
498 coreconfigitem('experimental', 'directaccess.revnums',
494 coreconfigitem('experimental', 'directaccess.revnums',
499 default=False,
495 default=False,
500 )
496 )
501 coreconfigitem('experimental', 'editortmpinhg',
497 coreconfigitem('experimental', 'editortmpinhg',
502 default=False,
498 default=False,
503 )
499 )
504 coreconfigitem('experimental', 'evolution',
500 coreconfigitem('experimental', 'evolution',
505 default=list,
501 default=list,
506 )
502 )
507 coreconfigitem('experimental', 'evolution.allowdivergence',
503 coreconfigitem('experimental', 'evolution.allowdivergence',
508 default=False,
504 default=False,
509 alias=[('experimental', 'allowdivergence')]
505 alias=[('experimental', 'allowdivergence')]
510 )
506 )
511 coreconfigitem('experimental', 'evolution.allowunstable',
507 coreconfigitem('experimental', 'evolution.allowunstable',
512 default=None,
508 default=None,
513 )
509 )
514 coreconfigitem('experimental', 'evolution.createmarkers',
510 coreconfigitem('experimental', 'evolution.createmarkers',
515 default=None,
511 default=None,
516 )
512 )
517 coreconfigitem('experimental', 'evolution.effect-flags',
513 coreconfigitem('experimental', 'evolution.effect-flags',
518 default=True,
514 default=True,
519 alias=[('experimental', 'effect-flags')]
515 alias=[('experimental', 'effect-flags')]
520 )
516 )
521 coreconfigitem('experimental', 'evolution.exchange',
517 coreconfigitem('experimental', 'evolution.exchange',
522 default=None,
518 default=None,
523 )
519 )
524 coreconfigitem('experimental', 'evolution.bundle-obsmarker',
520 coreconfigitem('experimental', 'evolution.bundle-obsmarker',
525 default=False,
521 default=False,
526 )
522 )
527 coreconfigitem('experimental', 'evolution.report-instabilities',
523 coreconfigitem('experimental', 'evolution.report-instabilities',
528 default=True,
524 default=True,
529 )
525 )
530 coreconfigitem('experimental', 'evolution.track-operation',
526 coreconfigitem('experimental', 'evolution.track-operation',
531 default=True,
527 default=True,
532 )
528 )
533 coreconfigitem('experimental', 'maxdeltachainspan',
529 coreconfigitem('experimental', 'maxdeltachainspan',
534 default=-1,
530 default=-1,
535 )
531 )
536 coreconfigitem('experimental', 'mergetempdirprefix',
532 coreconfigitem('experimental', 'mergetempdirprefix',
537 default=None,
533 default=None,
538 )
534 )
539 coreconfigitem('experimental', 'mmapindexthreshold',
535 coreconfigitem('experimental', 'mmapindexthreshold',
540 default=None,
536 default=None,
541 )
537 )
542 coreconfigitem('experimental', 'nonnormalparanoidcheck',
538 coreconfigitem('experimental', 'nonnormalparanoidcheck',
543 default=False,
539 default=False,
544 )
540 )
545 coreconfigitem('experimental', 'exportableenviron',
541 coreconfigitem('experimental', 'exportableenviron',
546 default=list,
542 default=list,
547 )
543 )
548 coreconfigitem('experimental', 'extendedheader.index',
544 coreconfigitem('experimental', 'extendedheader.index',
549 default=None,
545 default=None,
550 )
546 )
551 coreconfigitem('experimental', 'extendedheader.similarity',
547 coreconfigitem('experimental', 'extendedheader.similarity',
552 default=False,
548 default=False,
553 )
549 )
554 coreconfigitem('experimental', 'format.compression',
550 coreconfigitem('experimental', 'format.compression',
555 default='zlib',
551 default='zlib',
556 )
552 )
557 coreconfigitem('experimental', 'graphshorten',
553 coreconfigitem('experimental', 'graphshorten',
558 default=False,
554 default=False,
559 )
555 )
560 coreconfigitem('experimental', 'graphstyle.parent',
556 coreconfigitem('experimental', 'graphstyle.parent',
561 default=dynamicdefault,
557 default=dynamicdefault,
562 )
558 )
563 coreconfigitem('experimental', 'graphstyle.missing',
559 coreconfigitem('experimental', 'graphstyle.missing',
564 default=dynamicdefault,
560 default=dynamicdefault,
565 )
561 )
566 coreconfigitem('experimental', 'graphstyle.grandparent',
562 coreconfigitem('experimental', 'graphstyle.grandparent',
567 default=dynamicdefault,
563 default=dynamicdefault,
568 )
564 )
569 coreconfigitem('experimental', 'hook-track-tags',
565 coreconfigitem('experimental', 'hook-track-tags',
570 default=False,
566 default=False,
571 )
567 )
572 coreconfigitem('experimental', 'httppeer.advertise-v2',
568 coreconfigitem('experimental', 'httppeer.advertise-v2',
573 default=False,
569 default=False,
574 )
570 )
575 coreconfigitem('experimental', 'httppostargs',
571 coreconfigitem('experimental', 'httppostargs',
576 default=False,
572 default=False,
577 )
573 )
578 coreconfigitem('experimental', 'mergedriver',
574 coreconfigitem('experimental', 'mergedriver',
579 default=None,
575 default=None,
580 )
576 )
581 coreconfigitem('experimental', 'nointerrupt', default=False)
577 coreconfigitem('experimental', 'nointerrupt', default=False)
582 coreconfigitem('experimental', 'nointerrupt-interactiveonly', default=True)
578 coreconfigitem('experimental', 'nointerrupt-interactiveonly', default=True)
583
579
584 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
580 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
585 default=False,
581 default=False,
586 )
582 )
587 coreconfigitem('experimental', 'remotenames',
583 coreconfigitem('experimental', 'remotenames',
588 default=False,
584 default=False,
589 )
585 )
590 coreconfigitem('experimental', 'removeemptydirs',
586 coreconfigitem('experimental', 'removeemptydirs',
591 default=True,
587 default=True,
592 )
588 )
593 coreconfigitem('experimental', 'revisions.prefixhexnode',
589 coreconfigitem('experimental', 'revisions.prefixhexnode',
594 default=False,
590 default=False,
595 )
591 )
596 coreconfigitem('experimental', 'revlogv2',
592 coreconfigitem('experimental', 'revlogv2',
597 default=None,
593 default=None,
598 )
594 )
599 coreconfigitem('experimental', 'revisions.disambiguatewithin',
595 coreconfigitem('experimental', 'revisions.disambiguatewithin',
600 default=None,
596 default=None,
601 )
597 )
602 coreconfigitem('experimental', 'single-head-per-branch',
598 coreconfigitem('experimental', 'single-head-per-branch',
603 default=False,
599 default=False,
604 )
600 )
605 coreconfigitem('experimental', 'sshserver.support-v2',
601 coreconfigitem('experimental', 'sshserver.support-v2',
606 default=False,
602 default=False,
607 )
603 )
608 coreconfigitem('experimental', 'spacemovesdown',
604 coreconfigitem('experimental', 'spacemovesdown',
609 default=False,
605 default=False,
610 )
606 )
611 coreconfigitem('experimental', 'sparse-read',
607 coreconfigitem('experimental', 'sparse-read',
612 default=False,
608 default=False,
613 )
609 )
614 coreconfigitem('experimental', 'sparse-read.density-threshold',
610 coreconfigitem('experimental', 'sparse-read.density-threshold',
615 default=0.50,
611 default=0.50,
616 )
612 )
617 coreconfigitem('experimental', 'sparse-read.min-gap-size',
613 coreconfigitem('experimental', 'sparse-read.min-gap-size',
618 default='65K',
614 default='65K',
619 )
615 )
620 coreconfigitem('experimental', 'treemanifest',
616 coreconfigitem('experimental', 'treemanifest',
621 default=False,
617 default=False,
622 )
618 )
623 coreconfigitem('experimental', 'update.atomic-file',
619 coreconfigitem('experimental', 'update.atomic-file',
624 default=False,
620 default=False,
625 )
621 )
626 coreconfigitem('experimental', 'sshpeer.advertise-v2',
622 coreconfigitem('experimental', 'sshpeer.advertise-v2',
627 default=False,
623 default=False,
628 )
624 )
629 coreconfigitem('experimental', 'web.apiserver',
625 coreconfigitem('experimental', 'web.apiserver',
630 default=False,
626 default=False,
631 )
627 )
632 coreconfigitem('experimental', 'web.api.http-v2',
628 coreconfigitem('experimental', 'web.api.http-v2',
633 default=False,
629 default=False,
634 )
630 )
635 coreconfigitem('experimental', 'web.api.debugreflect',
631 coreconfigitem('experimental', 'web.api.debugreflect',
636 default=False,
632 default=False,
637 )
633 )
638 coreconfigitem('experimental', 'worker.wdir-get-thread-safe',
634 coreconfigitem('experimental', 'worker.wdir-get-thread-safe',
639 default=False,
635 default=False,
640 )
636 )
641 coreconfigitem('experimental', 'xdiff',
637 coreconfigitem('experimental', 'xdiff',
642 default=False,
638 default=False,
643 )
639 )
644 coreconfigitem('extensions', '.*',
640 coreconfigitem('extensions', '.*',
645 default=None,
641 default=None,
646 generic=True,
642 generic=True,
647 )
643 )
648 coreconfigitem('extdata', '.*',
644 coreconfigitem('extdata', '.*',
649 default=None,
645 default=None,
650 generic=True,
646 generic=True,
651 )
647 )
652 coreconfigitem('format', 'chunkcachesize',
648 coreconfigitem('format', 'chunkcachesize',
653 default=None,
649 default=None,
654 )
650 )
655 coreconfigitem('format', 'dotencode',
651 coreconfigitem('format', 'dotencode',
656 default=True,
652 default=True,
657 )
653 )
658 coreconfigitem('format', 'generaldelta',
654 coreconfigitem('format', 'generaldelta',
659 default=False,
655 default=False,
660 )
656 )
661 coreconfigitem('format', 'manifestcachesize',
657 coreconfigitem('format', 'manifestcachesize',
662 default=None,
658 default=None,
663 )
659 )
664 coreconfigitem('format', 'maxchainlen',
660 coreconfigitem('format', 'maxchainlen',
665 default=dynamicdefault,
661 default=dynamicdefault,
666 )
662 )
667 coreconfigitem('format', 'obsstore-version',
663 coreconfigitem('format', 'obsstore-version',
668 default=None,
664 default=None,
669 )
665 )
670 coreconfigitem('format', 'sparse-revlog',
666 coreconfigitem('format', 'sparse-revlog',
671 default=False,
667 default=False,
672 )
668 )
673 coreconfigitem('format', 'usefncache',
669 coreconfigitem('format', 'usefncache',
674 default=True,
670 default=True,
675 )
671 )
676 coreconfigitem('format', 'usegeneraldelta',
672 coreconfigitem('format', 'usegeneraldelta',
677 default=True,
673 default=True,
678 )
674 )
679 coreconfigitem('format', 'usestore',
675 coreconfigitem('format', 'usestore',
680 default=True,
676 default=True,
681 )
677 )
682 coreconfigitem('format', 'internal-phase',
678 coreconfigitem('format', 'internal-phase',
683 default=False,
679 default=False,
684 )
680 )
685 coreconfigitem('fsmonitor', 'warn_when_unused',
681 coreconfigitem('fsmonitor', 'warn_when_unused',
686 default=True,
682 default=True,
687 )
683 )
688 coreconfigitem('fsmonitor', 'warn_update_file_count',
684 coreconfigitem('fsmonitor', 'warn_update_file_count',
689 default=50000,
685 default=50000,
690 )
686 )
691 coreconfigitem('hooks', '.*',
687 coreconfigitem('hooks', '.*',
692 default=dynamicdefault,
688 default=dynamicdefault,
693 generic=True,
689 generic=True,
694 )
690 )
695 coreconfigitem('hgweb-paths', '.*',
691 coreconfigitem('hgweb-paths', '.*',
696 default=list,
692 default=list,
697 generic=True,
693 generic=True,
698 )
694 )
699 coreconfigitem('hostfingerprints', '.*',
695 coreconfigitem('hostfingerprints', '.*',
700 default=list,
696 default=list,
701 generic=True,
697 generic=True,
702 )
698 )
703 coreconfigitem('hostsecurity', 'ciphers',
699 coreconfigitem('hostsecurity', 'ciphers',
704 default=None,
700 default=None,
705 )
701 )
706 coreconfigitem('hostsecurity', 'disabletls10warning',
702 coreconfigitem('hostsecurity', 'disabletls10warning',
707 default=False,
703 default=False,
708 )
704 )
709 coreconfigitem('hostsecurity', 'minimumprotocol',
705 coreconfigitem('hostsecurity', 'minimumprotocol',
710 default=dynamicdefault,
706 default=dynamicdefault,
711 )
707 )
712 coreconfigitem('hostsecurity', '.*:minimumprotocol$',
708 coreconfigitem('hostsecurity', '.*:minimumprotocol$',
713 default=dynamicdefault,
709 default=dynamicdefault,
714 generic=True,
710 generic=True,
715 )
711 )
716 coreconfigitem('hostsecurity', '.*:ciphers$',
712 coreconfigitem('hostsecurity', '.*:ciphers$',
717 default=dynamicdefault,
713 default=dynamicdefault,
718 generic=True,
714 generic=True,
719 )
715 )
720 coreconfigitem('hostsecurity', '.*:fingerprints$',
716 coreconfigitem('hostsecurity', '.*:fingerprints$',
721 default=list,
717 default=list,
722 generic=True,
718 generic=True,
723 )
719 )
724 coreconfigitem('hostsecurity', '.*:verifycertsfile$',
720 coreconfigitem('hostsecurity', '.*:verifycertsfile$',
725 default=None,
721 default=None,
726 generic=True,
722 generic=True,
727 )
723 )
728
724
729 coreconfigitem('http_proxy', 'always',
725 coreconfigitem('http_proxy', 'always',
730 default=False,
726 default=False,
731 )
727 )
732 coreconfigitem('http_proxy', 'host',
728 coreconfigitem('http_proxy', 'host',
733 default=None,
729 default=None,
734 )
730 )
735 coreconfigitem('http_proxy', 'no',
731 coreconfigitem('http_proxy', 'no',
736 default=list,
732 default=list,
737 )
733 )
738 coreconfigitem('http_proxy', 'passwd',
734 coreconfigitem('http_proxy', 'passwd',
739 default=None,
735 default=None,
740 )
736 )
741 coreconfigitem('http_proxy', 'user',
737 coreconfigitem('http_proxy', 'user',
742 default=None,
738 default=None,
743 )
739 )
744 coreconfigitem('logtoprocess', 'commandexception',
740 coreconfigitem('logtoprocess', 'commandexception',
745 default=None,
741 default=None,
746 )
742 )
747 coreconfigitem('logtoprocess', 'commandfinish',
743 coreconfigitem('logtoprocess', 'commandfinish',
748 default=None,
744 default=None,
749 )
745 )
750 coreconfigitem('logtoprocess', 'command',
746 coreconfigitem('logtoprocess', 'command',
751 default=None,
747 default=None,
752 )
748 )
753 coreconfigitem('logtoprocess', 'develwarn',
749 coreconfigitem('logtoprocess', 'develwarn',
754 default=None,
750 default=None,
755 )
751 )
756 coreconfigitem('logtoprocess', 'uiblocked',
752 coreconfigitem('logtoprocess', 'uiblocked',
757 default=None,
753 default=None,
758 )
754 )
759 coreconfigitem('merge', 'checkunknown',
755 coreconfigitem('merge', 'checkunknown',
760 default='abort',
756 default='abort',
761 )
757 )
762 coreconfigitem('merge', 'checkignored',
758 coreconfigitem('merge', 'checkignored',
763 default='abort',
759 default='abort',
764 )
760 )
765 coreconfigitem('experimental', 'merge.checkpathconflicts',
761 coreconfigitem('experimental', 'merge.checkpathconflicts',
766 default=False,
762 default=False,
767 )
763 )
768 coreconfigitem('merge', 'followcopies',
764 coreconfigitem('merge', 'followcopies',
769 default=True,
765 default=True,
770 )
766 )
771 coreconfigitem('merge', 'on-failure',
767 coreconfigitem('merge', 'on-failure',
772 default='continue',
768 default='continue',
773 )
769 )
774 coreconfigitem('merge', 'preferancestor',
770 coreconfigitem('merge', 'preferancestor',
775 default=lambda: ['*'],
771 default=lambda: ['*'],
776 )
772 )
777 coreconfigitem('merge', 'strict-capability-check',
773 coreconfigitem('merge', 'strict-capability-check',
778 default=False,
774 default=False,
779 )
775 )
780 coreconfigitem('merge-tools', '.*',
776 coreconfigitem('merge-tools', '.*',
781 default=None,
777 default=None,
782 generic=True,
778 generic=True,
783 )
779 )
784 coreconfigitem('merge-tools', br'.*\.args$',
780 coreconfigitem('merge-tools', br'.*\.args$',
785 default="$local $base $other",
781 default="$local $base $other",
786 generic=True,
782 generic=True,
787 priority=-1,
783 priority=-1,
788 )
784 )
789 coreconfigitem('merge-tools', br'.*\.binary$',
785 coreconfigitem('merge-tools', br'.*\.binary$',
790 default=False,
786 default=False,
791 generic=True,
787 generic=True,
792 priority=-1,
788 priority=-1,
793 )
789 )
794 coreconfigitem('merge-tools', br'.*\.check$',
790 coreconfigitem('merge-tools', br'.*\.check$',
795 default=list,
791 default=list,
796 generic=True,
792 generic=True,
797 priority=-1,
793 priority=-1,
798 )
794 )
799 coreconfigitem('merge-tools', br'.*\.checkchanged$',
795 coreconfigitem('merge-tools', br'.*\.checkchanged$',
800 default=False,
796 default=False,
801 generic=True,
797 generic=True,
802 priority=-1,
798 priority=-1,
803 )
799 )
804 coreconfigitem('merge-tools', br'.*\.executable$',
800 coreconfigitem('merge-tools', br'.*\.executable$',
805 default=dynamicdefault,
801 default=dynamicdefault,
806 generic=True,
802 generic=True,
807 priority=-1,
803 priority=-1,
808 )
804 )
809 coreconfigitem('merge-tools', br'.*\.fixeol$',
805 coreconfigitem('merge-tools', br'.*\.fixeol$',
810 default=False,
806 default=False,
811 generic=True,
807 generic=True,
812 priority=-1,
808 priority=-1,
813 )
809 )
814 coreconfigitem('merge-tools', br'.*\.gui$',
810 coreconfigitem('merge-tools', br'.*\.gui$',
815 default=False,
811 default=False,
816 generic=True,
812 generic=True,
817 priority=-1,
813 priority=-1,
818 )
814 )
819 coreconfigitem('merge-tools', br'.*\.mergemarkers$',
815 coreconfigitem('merge-tools', br'.*\.mergemarkers$',
820 default='basic',
816 default='basic',
821 generic=True,
817 generic=True,
822 priority=-1,
818 priority=-1,
823 )
819 )
824 coreconfigitem('merge-tools', br'.*\.mergemarkertemplate$',
820 coreconfigitem('merge-tools', br'.*\.mergemarkertemplate$',
825 default=dynamicdefault, # take from ui.mergemarkertemplate
821 default=dynamicdefault, # take from ui.mergemarkertemplate
826 generic=True,
822 generic=True,
827 priority=-1,
823 priority=-1,
828 )
824 )
829 coreconfigitem('merge-tools', br'.*\.priority$',
825 coreconfigitem('merge-tools', br'.*\.priority$',
830 default=0,
826 default=0,
831 generic=True,
827 generic=True,
832 priority=-1,
828 priority=-1,
833 )
829 )
834 coreconfigitem('merge-tools', br'.*\.premerge$',
830 coreconfigitem('merge-tools', br'.*\.premerge$',
835 default=dynamicdefault,
831 default=dynamicdefault,
836 generic=True,
832 generic=True,
837 priority=-1,
833 priority=-1,
838 )
834 )
839 coreconfigitem('merge-tools', br'.*\.symlink$',
835 coreconfigitem('merge-tools', br'.*\.symlink$',
840 default=False,
836 default=False,
841 generic=True,
837 generic=True,
842 priority=-1,
838 priority=-1,
843 )
839 )
844 coreconfigitem('pager', 'attend-.*',
840 coreconfigitem('pager', 'attend-.*',
845 default=dynamicdefault,
841 default=dynamicdefault,
846 generic=True,
842 generic=True,
847 )
843 )
848 coreconfigitem('pager', 'ignore',
844 coreconfigitem('pager', 'ignore',
849 default=list,
845 default=list,
850 )
846 )
851 coreconfigitem('pager', 'pager',
847 coreconfigitem('pager', 'pager',
852 default=dynamicdefault,
848 default=dynamicdefault,
853 )
849 )
854 coreconfigitem('patch', 'eol',
850 coreconfigitem('patch', 'eol',
855 default='strict',
851 default='strict',
856 )
852 )
857 coreconfigitem('patch', 'fuzz',
853 coreconfigitem('patch', 'fuzz',
858 default=2,
854 default=2,
859 )
855 )
860 coreconfigitem('paths', 'default',
856 coreconfigitem('paths', 'default',
861 default=None,
857 default=None,
862 )
858 )
863 coreconfigitem('paths', 'default-push',
859 coreconfigitem('paths', 'default-push',
864 default=None,
860 default=None,
865 )
861 )
866 coreconfigitem('paths', '.*',
862 coreconfigitem('paths', '.*',
867 default=None,
863 default=None,
868 generic=True,
864 generic=True,
869 )
865 )
870 coreconfigitem('phases', 'checksubrepos',
866 coreconfigitem('phases', 'checksubrepos',
871 default='follow',
867 default='follow',
872 )
868 )
873 coreconfigitem('phases', 'new-commit',
869 coreconfigitem('phases', 'new-commit',
874 default='draft',
870 default='draft',
875 )
871 )
876 coreconfigitem('phases', 'publish',
872 coreconfigitem('phases', 'publish',
877 default=True,
873 default=True,
878 )
874 )
879 coreconfigitem('profiling', 'enabled',
875 coreconfigitem('profiling', 'enabled',
880 default=False,
876 default=False,
881 )
877 )
882 coreconfigitem('profiling', 'format',
878 coreconfigitem('profiling', 'format',
883 default='text',
879 default='text',
884 )
880 )
885 coreconfigitem('profiling', 'freq',
881 coreconfigitem('profiling', 'freq',
886 default=1000,
882 default=1000,
887 )
883 )
888 coreconfigitem('profiling', 'limit',
884 coreconfigitem('profiling', 'limit',
889 default=30,
885 default=30,
890 )
886 )
891 coreconfigitem('profiling', 'nested',
887 coreconfigitem('profiling', 'nested',
892 default=0,
888 default=0,
893 )
889 )
894 coreconfigitem('profiling', 'output',
890 coreconfigitem('profiling', 'output',
895 default=None,
891 default=None,
896 )
892 )
897 coreconfigitem('profiling', 'showmax',
893 coreconfigitem('profiling', 'showmax',
898 default=0.999,
894 default=0.999,
899 )
895 )
900 coreconfigitem('profiling', 'showmin',
896 coreconfigitem('profiling', 'showmin',
901 default=dynamicdefault,
897 default=dynamicdefault,
902 )
898 )
903 coreconfigitem('profiling', 'sort',
899 coreconfigitem('profiling', 'sort',
904 default='inlinetime',
900 default='inlinetime',
905 )
901 )
906 coreconfigitem('profiling', 'statformat',
902 coreconfigitem('profiling', 'statformat',
907 default='hotpath',
903 default='hotpath',
908 )
904 )
909 coreconfigitem('profiling', 'time-track',
905 coreconfigitem('profiling', 'time-track',
910 default='cpu',
906 default='cpu',
911 )
907 )
912 coreconfigitem('profiling', 'type',
908 coreconfigitem('profiling', 'type',
913 default='stat',
909 default='stat',
914 )
910 )
915 coreconfigitem('progress', 'assume-tty',
911 coreconfigitem('progress', 'assume-tty',
916 default=False,
912 default=False,
917 )
913 )
918 coreconfigitem('progress', 'changedelay',
914 coreconfigitem('progress', 'changedelay',
919 default=1,
915 default=1,
920 )
916 )
921 coreconfigitem('progress', 'clear-complete',
917 coreconfigitem('progress', 'clear-complete',
922 default=True,
918 default=True,
923 )
919 )
924 coreconfigitem('progress', 'debug',
920 coreconfigitem('progress', 'debug',
925 default=False,
921 default=False,
926 )
922 )
927 coreconfigitem('progress', 'delay',
923 coreconfigitem('progress', 'delay',
928 default=3,
924 default=3,
929 )
925 )
930 coreconfigitem('progress', 'disable',
926 coreconfigitem('progress', 'disable',
931 default=False,
927 default=False,
932 )
928 )
933 coreconfigitem('progress', 'estimateinterval',
929 coreconfigitem('progress', 'estimateinterval',
934 default=60.0,
930 default=60.0,
935 )
931 )
936 coreconfigitem('progress', 'format',
932 coreconfigitem('progress', 'format',
937 default=lambda: ['topic', 'bar', 'number', 'estimate'],
933 default=lambda: ['topic', 'bar', 'number', 'estimate'],
938 )
934 )
939 coreconfigitem('progress', 'refresh',
935 coreconfigitem('progress', 'refresh',
940 default=0.1,
936 default=0.1,
941 )
937 )
942 coreconfigitem('progress', 'width',
938 coreconfigitem('progress', 'width',
943 default=dynamicdefault,
939 default=dynamicdefault,
944 )
940 )
945 coreconfigitem('push', 'pushvars.server',
941 coreconfigitem('push', 'pushvars.server',
946 default=False,
942 default=False,
947 )
943 )
948 coreconfigitem('storage', 'revlog.optimize-delta-parent-choice',
944 coreconfigitem('storage', 'revlog.optimize-delta-parent-choice',
949 default=True,
945 default=True,
950 alias=[('format', 'aggressivemergedeltas')],
946 alias=[('format', 'aggressivemergedeltas')],
951 )
947 )
952 coreconfigitem('server', 'bookmarks-pushkey-compat',
948 coreconfigitem('server', 'bookmarks-pushkey-compat',
953 default=True,
949 default=True,
954 )
950 )
955 coreconfigitem('server', 'bundle1',
951 coreconfigitem('server', 'bundle1',
956 default=True,
952 default=True,
957 )
953 )
958 coreconfigitem('server', 'bundle1gd',
954 coreconfigitem('server', 'bundle1gd',
959 default=None,
955 default=None,
960 )
956 )
961 coreconfigitem('server', 'bundle1.pull',
957 coreconfigitem('server', 'bundle1.pull',
962 default=None,
958 default=None,
963 )
959 )
964 coreconfigitem('server', 'bundle1gd.pull',
960 coreconfigitem('server', 'bundle1gd.pull',
965 default=None,
961 default=None,
966 )
962 )
967 coreconfigitem('server', 'bundle1.push',
963 coreconfigitem('server', 'bundle1.push',
968 default=None,
964 default=None,
969 )
965 )
970 coreconfigitem('server', 'bundle1gd.push',
966 coreconfigitem('server', 'bundle1gd.push',
971 default=None,
967 default=None,
972 )
968 )
973 coreconfigitem('server', 'bundle2.stream',
969 coreconfigitem('server', 'bundle2.stream',
974 default=True,
970 default=True,
975 alias=[('experimental', 'bundle2.stream')]
971 alias=[('experimental', 'bundle2.stream')]
976 )
972 )
977 coreconfigitem('server', 'compressionengines',
973 coreconfigitem('server', 'compressionengines',
978 default=list,
974 default=list,
979 )
975 )
980 coreconfigitem('server', 'concurrent-push-mode',
976 coreconfigitem('server', 'concurrent-push-mode',
981 default='strict',
977 default='strict',
982 )
978 )
983 coreconfigitem('server', 'disablefullbundle',
979 coreconfigitem('server', 'disablefullbundle',
984 default=False,
980 default=False,
985 )
981 )
986 coreconfigitem('server', 'maxhttpheaderlen',
982 coreconfigitem('server', 'maxhttpheaderlen',
987 default=1024,
983 default=1024,
988 )
984 )
989 coreconfigitem('server', 'pullbundle',
985 coreconfigitem('server', 'pullbundle',
990 default=False,
986 default=False,
991 )
987 )
992 coreconfigitem('server', 'preferuncompressed',
988 coreconfigitem('server', 'preferuncompressed',
993 default=False,
989 default=False,
994 )
990 )
995 coreconfigitem('server', 'streamunbundle',
991 coreconfigitem('server', 'streamunbundle',
996 default=False,
992 default=False,
997 )
993 )
998 coreconfigitem('server', 'uncompressed',
994 coreconfigitem('server', 'uncompressed',
999 default=True,
995 default=True,
1000 )
996 )
1001 coreconfigitem('server', 'uncompressedallowsecret',
997 coreconfigitem('server', 'uncompressedallowsecret',
1002 default=False,
998 default=False,
1003 )
999 )
1004 coreconfigitem('server', 'validate',
1000 coreconfigitem('server', 'validate',
1005 default=False,
1001 default=False,
1006 )
1002 )
1007 coreconfigitem('server', 'zliblevel',
1003 coreconfigitem('server', 'zliblevel',
1008 default=-1,
1004 default=-1,
1009 )
1005 )
1010 coreconfigitem('server', 'zstdlevel',
1006 coreconfigitem('server', 'zstdlevel',
1011 default=3,
1007 default=3,
1012 )
1008 )
1013 coreconfigitem('share', 'pool',
1009 coreconfigitem('share', 'pool',
1014 default=None,
1010 default=None,
1015 )
1011 )
1016 coreconfigitem('share', 'poolnaming',
1012 coreconfigitem('share', 'poolnaming',
1017 default='identity',
1013 default='identity',
1018 )
1014 )
1019 coreconfigitem('smtp', 'host',
1015 coreconfigitem('smtp', 'host',
1020 default=None,
1016 default=None,
1021 )
1017 )
1022 coreconfigitem('smtp', 'local_hostname',
1018 coreconfigitem('smtp', 'local_hostname',
1023 default=None,
1019 default=None,
1024 )
1020 )
1025 coreconfigitem('smtp', 'password',
1021 coreconfigitem('smtp', 'password',
1026 default=None,
1022 default=None,
1027 )
1023 )
1028 coreconfigitem('smtp', 'port',
1024 coreconfigitem('smtp', 'port',
1029 default=dynamicdefault,
1025 default=dynamicdefault,
1030 )
1026 )
1031 coreconfigitem('smtp', 'tls',
1027 coreconfigitem('smtp', 'tls',
1032 default='none',
1028 default='none',
1033 )
1029 )
1034 coreconfigitem('smtp', 'username',
1030 coreconfigitem('smtp', 'username',
1035 default=None,
1031 default=None,
1036 )
1032 )
1037 coreconfigitem('sparse', 'missingwarning',
1033 coreconfigitem('sparse', 'missingwarning',
1038 default=True,
1034 default=True,
1039 )
1035 )
1040 coreconfigitem('subrepos', 'allowed',
1036 coreconfigitem('subrepos', 'allowed',
1041 default=dynamicdefault, # to make backporting simpler
1037 default=dynamicdefault, # to make backporting simpler
1042 )
1038 )
1043 coreconfigitem('subrepos', 'hg:allowed',
1039 coreconfigitem('subrepos', 'hg:allowed',
1044 default=dynamicdefault,
1040 default=dynamicdefault,
1045 )
1041 )
1046 coreconfigitem('subrepos', 'git:allowed',
1042 coreconfigitem('subrepos', 'git:allowed',
1047 default=dynamicdefault,
1043 default=dynamicdefault,
1048 )
1044 )
1049 coreconfigitem('subrepos', 'svn:allowed',
1045 coreconfigitem('subrepos', 'svn:allowed',
1050 default=dynamicdefault,
1046 default=dynamicdefault,
1051 )
1047 )
1052 coreconfigitem('templates', '.*',
1048 coreconfigitem('templates', '.*',
1053 default=None,
1049 default=None,
1054 generic=True,
1050 generic=True,
1055 )
1051 )
1056 coreconfigitem('trusted', 'groups',
1052 coreconfigitem('trusted', 'groups',
1057 default=list,
1053 default=list,
1058 )
1054 )
1059 coreconfigitem('trusted', 'users',
1055 coreconfigitem('trusted', 'users',
1060 default=list,
1056 default=list,
1061 )
1057 )
1062 coreconfigitem('ui', '_usedassubrepo',
1058 coreconfigitem('ui', '_usedassubrepo',
1063 default=False,
1059 default=False,
1064 )
1060 )
1065 coreconfigitem('ui', 'allowemptycommit',
1061 coreconfigitem('ui', 'allowemptycommit',
1066 default=False,
1062 default=False,
1067 )
1063 )
1068 coreconfigitem('ui', 'archivemeta',
1064 coreconfigitem('ui', 'archivemeta',
1069 default=True,
1065 default=True,
1070 )
1066 )
1071 coreconfigitem('ui', 'askusername',
1067 coreconfigitem('ui', 'askusername',
1072 default=False,
1068 default=False,
1073 )
1069 )
1074 coreconfigitem('ui', 'clonebundlefallback',
1070 coreconfigitem('ui', 'clonebundlefallback',
1075 default=False,
1071 default=False,
1076 )
1072 )
1077 coreconfigitem('ui', 'clonebundleprefers',
1073 coreconfigitem('ui', 'clonebundleprefers',
1078 default=list,
1074 default=list,
1079 )
1075 )
1080 coreconfigitem('ui', 'clonebundles',
1076 coreconfigitem('ui', 'clonebundles',
1081 default=True,
1077 default=True,
1082 )
1078 )
1083 coreconfigitem('ui', 'color',
1079 coreconfigitem('ui', 'color',
1084 default='auto',
1080 default='auto',
1085 )
1081 )
1086 coreconfigitem('ui', 'commitsubrepos',
1082 coreconfigitem('ui', 'commitsubrepos',
1087 default=False,
1083 default=False,
1088 )
1084 )
1089 coreconfigitem('ui', 'debug',
1085 coreconfigitem('ui', 'debug',
1090 default=False,
1086 default=False,
1091 )
1087 )
1092 coreconfigitem('ui', 'debugger',
1088 coreconfigitem('ui', 'debugger',
1093 default=None,
1089 default=None,
1094 )
1090 )
1095 coreconfigitem('ui', 'editor',
1091 coreconfigitem('ui', 'editor',
1096 default=dynamicdefault,
1092 default=dynamicdefault,
1097 )
1093 )
1098 coreconfigitem('ui', 'fallbackencoding',
1094 coreconfigitem('ui', 'fallbackencoding',
1099 default=None,
1095 default=None,
1100 )
1096 )
1101 coreconfigitem('ui', 'forcecwd',
1097 coreconfigitem('ui', 'forcecwd',
1102 default=None,
1098 default=None,
1103 )
1099 )
1104 coreconfigitem('ui', 'forcemerge',
1100 coreconfigitem('ui', 'forcemerge',
1105 default=None,
1101 default=None,
1106 )
1102 )
1107 coreconfigitem('ui', 'formatdebug',
1103 coreconfigitem('ui', 'formatdebug',
1108 default=False,
1104 default=False,
1109 )
1105 )
1110 coreconfigitem('ui', 'formatjson',
1106 coreconfigitem('ui', 'formatjson',
1111 default=False,
1107 default=False,
1112 )
1108 )
1113 coreconfigitem('ui', 'formatted',
1109 coreconfigitem('ui', 'formatted',
1114 default=None,
1110 default=None,
1115 )
1111 )
1116 coreconfigitem('ui', 'graphnodetemplate',
1112 coreconfigitem('ui', 'graphnodetemplate',
1117 default=None,
1113 default=None,
1118 )
1114 )
1119 coreconfigitem('ui', 'history-editing-backup',
1115 coreconfigitem('ui', 'history-editing-backup',
1120 default=True,
1116 default=True,
1121 )
1117 )
1122 coreconfigitem('ui', 'interactive',
1118 coreconfigitem('ui', 'interactive',
1123 default=None,
1119 default=None,
1124 )
1120 )
1125 coreconfigitem('ui', 'interface',
1121 coreconfigitem('ui', 'interface',
1126 default=None,
1122 default=None,
1127 )
1123 )
1128 coreconfigitem('ui', 'interface.chunkselector',
1124 coreconfigitem('ui', 'interface.chunkselector',
1129 default=None,
1125 default=None,
1130 )
1126 )
1131 coreconfigitem('ui', 'large-file-limit',
1127 coreconfigitem('ui', 'large-file-limit',
1132 default=10000000,
1128 default=10000000,
1133 )
1129 )
1134 coreconfigitem('ui', 'logblockedtimes',
1130 coreconfigitem('ui', 'logblockedtimes',
1135 default=False,
1131 default=False,
1136 )
1132 )
1137 coreconfigitem('ui', 'logtemplate',
1133 coreconfigitem('ui', 'logtemplate',
1138 default=None,
1134 default=None,
1139 )
1135 )
1140 coreconfigitem('ui', 'merge',
1136 coreconfigitem('ui', 'merge',
1141 default=None,
1137 default=None,
1142 )
1138 )
1143 coreconfigitem('ui', 'mergemarkers',
1139 coreconfigitem('ui', 'mergemarkers',
1144 default='basic',
1140 default='basic',
1145 )
1141 )
1146 coreconfigitem('ui', 'mergemarkertemplate',
1142 coreconfigitem('ui', 'mergemarkertemplate',
1147 default=('{node|short} '
1143 default=('{node|short} '
1148 '{ifeq(tags, "tip", "", '
1144 '{ifeq(tags, "tip", "", '
1149 'ifeq(tags, "", "", "{tags} "))}'
1145 'ifeq(tags, "", "", "{tags} "))}'
1150 '{if(bookmarks, "{bookmarks} ")}'
1146 '{if(bookmarks, "{bookmarks} ")}'
1151 '{ifeq(branch, "default", "", "{branch} ")}'
1147 '{ifeq(branch, "default", "", "{branch} ")}'
1152 '- {author|user}: {desc|firstline}')
1148 '- {author|user}: {desc|firstline}')
1153 )
1149 )
1154 coreconfigitem('ui', 'nontty',
1150 coreconfigitem('ui', 'nontty',
1155 default=False,
1151 default=False,
1156 )
1152 )
1157 coreconfigitem('ui', 'origbackuppath',
1153 coreconfigitem('ui', 'origbackuppath',
1158 default=None,
1154 default=None,
1159 )
1155 )
1160 coreconfigitem('ui', 'paginate',
1156 coreconfigitem('ui', 'paginate',
1161 default=True,
1157 default=True,
1162 )
1158 )
1163 coreconfigitem('ui', 'patch',
1159 coreconfigitem('ui', 'patch',
1164 default=None,
1160 default=None,
1165 )
1161 )
1166 coreconfigitem('ui', 'portablefilenames',
1162 coreconfigitem('ui', 'portablefilenames',
1167 default='warn',
1163 default='warn',
1168 )
1164 )
1169 coreconfigitem('ui', 'promptecho',
1165 coreconfigitem('ui', 'promptecho',
1170 default=False,
1166 default=False,
1171 )
1167 )
1172 coreconfigitem('ui', 'quiet',
1168 coreconfigitem('ui', 'quiet',
1173 default=False,
1169 default=False,
1174 )
1170 )
1175 coreconfigitem('ui', 'quietbookmarkmove',
1171 coreconfigitem('ui', 'quietbookmarkmove',
1176 default=False,
1172 default=False,
1177 )
1173 )
1178 coreconfigitem('ui', 'remotecmd',
1174 coreconfigitem('ui', 'remotecmd',
1179 default='hg',
1175 default='hg',
1180 )
1176 )
1181 coreconfigitem('ui', 'report_untrusted',
1177 coreconfigitem('ui', 'report_untrusted',
1182 default=True,
1178 default=True,
1183 )
1179 )
1184 coreconfigitem('ui', 'rollback',
1180 coreconfigitem('ui', 'rollback',
1185 default=True,
1181 default=True,
1186 )
1182 )
1187 coreconfigitem('ui', 'signal-safe-lock',
1183 coreconfigitem('ui', 'signal-safe-lock',
1188 default=True,
1184 default=True,
1189 )
1185 )
1190 coreconfigitem('ui', 'slash',
1186 coreconfigitem('ui', 'slash',
1191 default=False,
1187 default=False,
1192 )
1188 )
1193 coreconfigitem('ui', 'ssh',
1189 coreconfigitem('ui', 'ssh',
1194 default='ssh',
1190 default='ssh',
1195 )
1191 )
1196 coreconfigitem('ui', 'ssherrorhint',
1192 coreconfigitem('ui', 'ssherrorhint',
1197 default=None,
1193 default=None,
1198 )
1194 )
1199 coreconfigitem('ui', 'statuscopies',
1195 coreconfigitem('ui', 'statuscopies',
1200 default=False,
1196 default=False,
1201 )
1197 )
1202 coreconfigitem('ui', 'strict',
1198 coreconfigitem('ui', 'strict',
1203 default=False,
1199 default=False,
1204 )
1200 )
1205 coreconfigitem('ui', 'style',
1201 coreconfigitem('ui', 'style',
1206 default='',
1202 default='',
1207 )
1203 )
1208 coreconfigitem('ui', 'supportcontact',
1204 coreconfigitem('ui', 'supportcontact',
1209 default=None,
1205 default=None,
1210 )
1206 )
1211 coreconfigitem('ui', 'textwidth',
1207 coreconfigitem('ui', 'textwidth',
1212 default=78,
1208 default=78,
1213 )
1209 )
1214 coreconfigitem('ui', 'timeout',
1210 coreconfigitem('ui', 'timeout',
1215 default='600',
1211 default='600',
1216 )
1212 )
1217 coreconfigitem('ui', 'timeout.warn',
1213 coreconfigitem('ui', 'timeout.warn',
1218 default=0,
1214 default=0,
1219 )
1215 )
1220 coreconfigitem('ui', 'traceback',
1216 coreconfigitem('ui', 'traceback',
1221 default=False,
1217 default=False,
1222 )
1218 )
1223 coreconfigitem('ui', 'tweakdefaults',
1219 coreconfigitem('ui', 'tweakdefaults',
1224 default=False,
1220 default=False,
1225 )
1221 )
1226 coreconfigitem('ui', 'username',
1222 coreconfigitem('ui', 'username',
1227 alias=[('ui', 'user')]
1223 alias=[('ui', 'user')]
1228 )
1224 )
1229 coreconfigitem('ui', 'verbose',
1225 coreconfigitem('ui', 'verbose',
1230 default=False,
1226 default=False,
1231 )
1227 )
1232 coreconfigitem('verify', 'skipflags',
1228 coreconfigitem('verify', 'skipflags',
1233 default=None,
1229 default=None,
1234 )
1230 )
1235 coreconfigitem('web', 'allowbz2',
1231 coreconfigitem('web', 'allowbz2',
1236 default=False,
1232 default=False,
1237 )
1233 )
1238 coreconfigitem('web', 'allowgz',
1234 coreconfigitem('web', 'allowgz',
1239 default=False,
1235 default=False,
1240 )
1236 )
1241 coreconfigitem('web', 'allow-pull',
1237 coreconfigitem('web', 'allow-pull',
1242 alias=[('web', 'allowpull')],
1238 alias=[('web', 'allowpull')],
1243 default=True,
1239 default=True,
1244 )
1240 )
1245 coreconfigitem('web', 'allow-push',
1241 coreconfigitem('web', 'allow-push',
1246 alias=[('web', 'allow_push')],
1242 alias=[('web', 'allow_push')],
1247 default=list,
1243 default=list,
1248 )
1244 )
1249 coreconfigitem('web', 'allowzip',
1245 coreconfigitem('web', 'allowzip',
1250 default=False,
1246 default=False,
1251 )
1247 )
1252 coreconfigitem('web', 'archivesubrepos',
1248 coreconfigitem('web', 'archivesubrepos',
1253 default=False,
1249 default=False,
1254 )
1250 )
1255 coreconfigitem('web', 'cache',
1251 coreconfigitem('web', 'cache',
1256 default=True,
1252 default=True,
1257 )
1253 )
1258 coreconfigitem('web', 'contact',
1254 coreconfigitem('web', 'contact',
1259 default=None,
1255 default=None,
1260 )
1256 )
1261 coreconfigitem('web', 'deny_push',
1257 coreconfigitem('web', 'deny_push',
1262 default=list,
1258 default=list,
1263 )
1259 )
1264 coreconfigitem('web', 'guessmime',
1260 coreconfigitem('web', 'guessmime',
1265 default=False,
1261 default=False,
1266 )
1262 )
1267 coreconfigitem('web', 'hidden',
1263 coreconfigitem('web', 'hidden',
1268 default=False,
1264 default=False,
1269 )
1265 )
1270 coreconfigitem('web', 'labels',
1266 coreconfigitem('web', 'labels',
1271 default=list,
1267 default=list,
1272 )
1268 )
1273 coreconfigitem('web', 'logoimg',
1269 coreconfigitem('web', 'logoimg',
1274 default='hglogo.png',
1270 default='hglogo.png',
1275 )
1271 )
1276 coreconfigitem('web', 'logourl',
1272 coreconfigitem('web', 'logourl',
1277 default='https://mercurial-scm.org/',
1273 default='https://mercurial-scm.org/',
1278 )
1274 )
1279 coreconfigitem('web', 'accesslog',
1275 coreconfigitem('web', 'accesslog',
1280 default='-',
1276 default='-',
1281 )
1277 )
1282 coreconfigitem('web', 'address',
1278 coreconfigitem('web', 'address',
1283 default='',
1279 default='',
1284 )
1280 )
1285 coreconfigitem('web', 'allow-archive',
1281 coreconfigitem('web', 'allow-archive',
1286 alias=[('web', 'allow_archive')],
1282 alias=[('web', 'allow_archive')],
1287 default=list,
1283 default=list,
1288 )
1284 )
1289 coreconfigitem('web', 'allow_read',
1285 coreconfigitem('web', 'allow_read',
1290 default=list,
1286 default=list,
1291 )
1287 )
1292 coreconfigitem('web', 'baseurl',
1288 coreconfigitem('web', 'baseurl',
1293 default=None,
1289 default=None,
1294 )
1290 )
1295 coreconfigitem('web', 'cacerts',
1291 coreconfigitem('web', 'cacerts',
1296 default=None,
1292 default=None,
1297 )
1293 )
1298 coreconfigitem('web', 'certificate',
1294 coreconfigitem('web', 'certificate',
1299 default=None,
1295 default=None,
1300 )
1296 )
1301 coreconfigitem('web', 'collapse',
1297 coreconfigitem('web', 'collapse',
1302 default=False,
1298 default=False,
1303 )
1299 )
1304 coreconfigitem('web', 'csp',
1300 coreconfigitem('web', 'csp',
1305 default=None,
1301 default=None,
1306 )
1302 )
1307 coreconfigitem('web', 'deny_read',
1303 coreconfigitem('web', 'deny_read',
1308 default=list,
1304 default=list,
1309 )
1305 )
1310 coreconfigitem('web', 'descend',
1306 coreconfigitem('web', 'descend',
1311 default=True,
1307 default=True,
1312 )
1308 )
1313 coreconfigitem('web', 'description',
1309 coreconfigitem('web', 'description',
1314 default="",
1310 default="",
1315 )
1311 )
1316 coreconfigitem('web', 'encoding',
1312 coreconfigitem('web', 'encoding',
1317 default=lambda: encoding.encoding,
1313 default=lambda: encoding.encoding,
1318 )
1314 )
1319 coreconfigitem('web', 'errorlog',
1315 coreconfigitem('web', 'errorlog',
1320 default='-',
1316 default='-',
1321 )
1317 )
1322 coreconfigitem('web', 'ipv6',
1318 coreconfigitem('web', 'ipv6',
1323 default=False,
1319 default=False,
1324 )
1320 )
1325 coreconfigitem('web', 'maxchanges',
1321 coreconfigitem('web', 'maxchanges',
1326 default=10,
1322 default=10,
1327 )
1323 )
1328 coreconfigitem('web', 'maxfiles',
1324 coreconfigitem('web', 'maxfiles',
1329 default=10,
1325 default=10,
1330 )
1326 )
1331 coreconfigitem('web', 'maxshortchanges',
1327 coreconfigitem('web', 'maxshortchanges',
1332 default=60,
1328 default=60,
1333 )
1329 )
1334 coreconfigitem('web', 'motd',
1330 coreconfigitem('web', 'motd',
1335 default='',
1331 default='',
1336 )
1332 )
1337 coreconfigitem('web', 'name',
1333 coreconfigitem('web', 'name',
1338 default=dynamicdefault,
1334 default=dynamicdefault,
1339 )
1335 )
1340 coreconfigitem('web', 'port',
1336 coreconfigitem('web', 'port',
1341 default=8000,
1337 default=8000,
1342 )
1338 )
1343 coreconfigitem('web', 'prefix',
1339 coreconfigitem('web', 'prefix',
1344 default='',
1340 default='',
1345 )
1341 )
1346 coreconfigitem('web', 'push_ssl',
1342 coreconfigitem('web', 'push_ssl',
1347 default=True,
1343 default=True,
1348 )
1344 )
1349 coreconfigitem('web', 'refreshinterval',
1345 coreconfigitem('web', 'refreshinterval',
1350 default=20,
1346 default=20,
1351 )
1347 )
1352 coreconfigitem('web', 'server-header',
1348 coreconfigitem('web', 'server-header',
1353 default=None,
1349 default=None,
1354 )
1350 )
1355 coreconfigitem('web', 'static',
1351 coreconfigitem('web', 'static',
1356 default=None,
1352 default=None,
1357 )
1353 )
1358 coreconfigitem('web', 'staticurl',
1354 coreconfigitem('web', 'staticurl',
1359 default=None,
1355 default=None,
1360 )
1356 )
1361 coreconfigitem('web', 'stripes',
1357 coreconfigitem('web', 'stripes',
1362 default=1,
1358 default=1,
1363 )
1359 )
1364 coreconfigitem('web', 'style',
1360 coreconfigitem('web', 'style',
1365 default='paper',
1361 default='paper',
1366 )
1362 )
1367 coreconfigitem('web', 'templates',
1363 coreconfigitem('web', 'templates',
1368 default=None,
1364 default=None,
1369 )
1365 )
1370 coreconfigitem('web', 'view',
1366 coreconfigitem('web', 'view',
1371 default='served',
1367 default='served',
1372 )
1368 )
1373 coreconfigitem('worker', 'backgroundclose',
1369 coreconfigitem('worker', 'backgroundclose',
1374 default=dynamicdefault,
1370 default=dynamicdefault,
1375 )
1371 )
1376 # Windows defaults to a limit of 512 open files. A buffer of 128
1372 # Windows defaults to a limit of 512 open files. A buffer of 128
1377 # should give us enough headway.
1373 # should give us enough headway.
1378 coreconfigitem('worker', 'backgroundclosemaxqueue',
1374 coreconfigitem('worker', 'backgroundclosemaxqueue',
1379 default=384,
1375 default=384,
1380 )
1376 )
1381 coreconfigitem('worker', 'backgroundcloseminfilecount',
1377 coreconfigitem('worker', 'backgroundcloseminfilecount',
1382 default=2048,
1378 default=2048,
1383 )
1379 )
1384 coreconfigitem('worker', 'backgroundclosethreadcount',
1380 coreconfigitem('worker', 'backgroundclosethreadcount',
1385 default=4,
1381 default=4,
1386 )
1382 )
1387 coreconfigitem('worker', 'enabled',
1383 coreconfigitem('worker', 'enabled',
1388 default=True,
1384 default=True,
1389 )
1385 )
1390 coreconfigitem('worker', 'numcpus',
1386 coreconfigitem('worker', 'numcpus',
1391 default=None,
1387 default=None,
1392 )
1388 )
1393
1389
1394 # Rebase related configuration moved to core because other extension are doing
1390 # Rebase related configuration moved to core because other extension are doing
1395 # strange things. For example, shelve import the extensions to reuse some bit
1391 # strange things. For example, shelve import the extensions to reuse some bit
1396 # without formally loading it.
1392 # without formally loading it.
1397 coreconfigitem('commands', 'rebase.requiredest',
1393 coreconfigitem('commands', 'rebase.requiredest',
1398 default=False,
1394 default=False,
1399 )
1395 )
1400 coreconfigitem('experimental', 'rebaseskipobsolete',
1396 coreconfigitem('experimental', 'rebaseskipobsolete',
1401 default=True,
1397 default=True,
1402 )
1398 )
1403 coreconfigitem('rebase', 'singletransaction',
1399 coreconfigitem('rebase', 'singletransaction',
1404 default=False,
1400 default=False,
1405 )
1401 )
1406 coreconfigitem('rebase', 'experimental.inmemory',
1402 coreconfigitem('rebase', 'experimental.inmemory',
1407 default=False,
1403 default=False,
1408 )
1404 )
@@ -1,402 +1,402 b''
1 #require no-reposimplestore
1 #require no-reposimplestore
2
2
3 Check whether size of generaldelta revlog is not bigger than its
3 Check whether size of generaldelta revlog is not bigger than its
4 regular equivalent. Test would fail if generaldelta was naive
4 regular equivalent. Test would fail if generaldelta was naive
5 implementation of parentdelta: third manifest revision would be fully
5 implementation of parentdelta: third manifest revision would be fully
6 inserted due to big distance from its paren revision (zero).
6 inserted due to big distance from its paren revision (zero).
7
7
8 $ hg init repo --config format.generaldelta=no --config format.usegeneraldelta=no
8 $ hg init repo --config format.generaldelta=no --config format.usegeneraldelta=no
9 $ cd repo
9 $ cd repo
10 $ echo foo > foo
10 $ echo foo > foo
11 $ echo bar > bar
11 $ echo bar > bar
12 $ echo baz > baz
12 $ echo baz > baz
13 $ hg commit -q -Am boo
13 $ hg commit -q -Am boo
14 $ hg clone --pull . ../gdrepo -q --config format.generaldelta=yes
14 $ hg clone --pull . ../gdrepo -q --config format.generaldelta=yes
15 $ for r in 1 2 3; do
15 $ for r in 1 2 3; do
16 > echo $r > foo
16 > echo $r > foo
17 > hg commit -q -m $r
17 > hg commit -q -m $r
18 > hg up -q -r 0
18 > hg up -q -r 0
19 > hg pull . -q -r $r -R ../gdrepo
19 > hg pull . -q -r $r -R ../gdrepo
20 > done
20 > done
21
21
22 $ cd ..
22 $ cd ..
23 >>> from __future__ import print_function
23 >>> from __future__ import print_function
24 >>> import os
24 >>> import os
25 >>> regsize = os.stat("repo/.hg/store/00manifest.i").st_size
25 >>> regsize = os.stat("repo/.hg/store/00manifest.i").st_size
26 >>> gdsize = os.stat("gdrepo/.hg/store/00manifest.i").st_size
26 >>> gdsize = os.stat("gdrepo/.hg/store/00manifest.i").st_size
27 >>> if regsize < gdsize:
27 >>> if regsize < gdsize:
28 ... print('generaldata increased size of manifest')
28 ... print('generaldata increased size of manifest')
29
29
30 Verify rev reordering doesnt create invalid bundles (issue4462)
30 Verify rev reordering doesnt create invalid bundles (issue4462)
31 This requires a commit tree that when pulled will reorder manifest revs such
31 This requires a commit tree that when pulled will reorder manifest revs such
32 that the second manifest to create a file rev will be ordered before the first
32 that the second manifest to create a file rev will be ordered before the first
33 manifest to create that file rev. We also need to do a partial pull to ensure
33 manifest to create that file rev. We also need to do a partial pull to ensure
34 reordering happens. At the end we verify the linkrev points at the earliest
34 reordering happens. At the end we verify the linkrev points at the earliest
35 commit.
35 commit.
36
36
37 $ hg init server --config format.generaldelta=True
37 $ hg init server --config format.generaldelta=True
38 $ cd server
38 $ cd server
39 $ touch a
39 $ touch a
40 $ hg commit -Aqm a
40 $ hg commit -Aqm a
41 $ echo x > x
41 $ echo x > x
42 $ echo y > y
42 $ echo y > y
43 $ hg commit -Aqm xy
43 $ hg commit -Aqm xy
44 $ hg up -q '.^'
44 $ hg up -q '.^'
45 $ echo x > x
45 $ echo x > x
46 $ echo z > z
46 $ echo z > z
47 $ hg commit -Aqm xz
47 $ hg commit -Aqm xz
48 $ hg up -q 1
48 $ hg up -q 1
49 $ echo b > b
49 $ echo b > b
50 $ hg commit -Aqm b
50 $ hg commit -Aqm b
51 $ hg merge -q 2
51 $ hg merge -q 2
52 $ hg commit -Aqm merge
52 $ hg commit -Aqm merge
53 $ echo c > c
53 $ echo c > c
54 $ hg commit -Aqm c
54 $ hg commit -Aqm c
55 $ hg log -G -T '{rev} {shortest(node)} {desc}'
55 $ hg log -G -T '{rev} {shortest(node)} {desc}'
56 @ 5 ebb8 c
56 @ 5 ebb8 c
57 |
57 |
58 o 4 baf7 merge
58 o 4 baf7 merge
59 |\
59 |\
60 | o 3 a129 b
60 | o 3 a129 b
61 | |
61 | |
62 o | 2 958c xz
62 o | 2 958c xz
63 | |
63 | |
64 | o 1 f00c xy
64 | o 1 f00c xy
65 |/
65 |/
66 o 0 3903 a
66 o 0 3903 a
67
67
68 $ cd ..
68 $ cd ..
69 $ hg init client --config format.generaldelta=false --config format.usegeneraldelta=false
69 $ hg init client --config format.generaldelta=false --config format.usegeneraldelta=false
70 $ cd client
70 $ cd client
71 $ hg pull -q ../server -r 4
71 $ hg pull -q ../server -r 4
72 $ hg debugdeltachain x
72 $ hg debugdeltachain x
73 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
73 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
74 0 1 1 -1 base 3 2 3 1.50000 3 0 0.00000
74 0 1 1 -1 base 3 2 3 1.50000 3 0 0.00000
75
75
76 $ cd ..
76 $ cd ..
77
77
78 Test "usegeneraldelta" config
78 Test "usegeneraldelta" config
79 (repo are general delta, but incoming bundle are not re-deltafied)
79 (repo are general delta, but incoming bundle are not re-deltafied)
80
80
81 delta coming from the server base delta server are not recompressed.
81 delta coming from the server base delta server are not recompressed.
82 (also include the aggressive version for comparison)
82 (also include the aggressive version for comparison)
83
83
84 $ hg clone repo --pull --config format.usegeneraldelta=1 usegd
84 $ hg clone repo --pull --config format.usegeneraldelta=1 usegd
85 requesting all changes
85 requesting all changes
86 adding changesets
86 adding changesets
87 adding manifests
87 adding manifests
88 adding file changes
88 adding file changes
89 added 4 changesets with 6 changes to 3 files (+2 heads)
89 added 4 changesets with 6 changes to 3 files (+2 heads)
90 new changesets 0ea3fcf9d01d:bba78d330d9c
90 new changesets 0ea3fcf9d01d:bba78d330d9c
91 updating to branch default
91 updating to branch default
92 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
93 $ hg clone repo --pull --config format.generaldelta=1 full
93 $ hg clone repo --pull --config format.generaldelta=1 full
94 requesting all changes
94 requesting all changes
95 adding changesets
95 adding changesets
96 adding manifests
96 adding manifests
97 adding file changes
97 adding file changes
98 added 4 changesets with 6 changes to 3 files (+2 heads)
98 added 4 changesets with 6 changes to 3 files (+2 heads)
99 new changesets 0ea3fcf9d01d:bba78d330d9c
99 new changesets 0ea3fcf9d01d:bba78d330d9c
100 updating to branch default
100 updating to branch default
101 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
101 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
102 $ hg -R repo debugdeltachain -m
102 $ hg -R repo debugdeltachain -m
103 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
103 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
104 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
104 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
105 1 1 2 0 prev 57 135 161 1.19259 161 0 0.00000
105 1 1 2 0 prev 57 135 161 1.19259 161 0 0.00000
106 2 1 3 1 prev 57 135 218 1.61481 218 0 0.00000
106 2 1 3 1 prev 57 135 218 1.61481 218 0 0.00000
107 3 2 1 -1 base 104 135 104 0.77037 104 0 0.00000
107 3 2 1 -1 base 104 135 104 0.77037 104 0 0.00000
108 $ hg -R usegd debugdeltachain -m
108 $ hg -R usegd debugdeltachain -m
109 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
109 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
110 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
110 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
111 1 1 2 0 p1 57 135 161 1.19259 161 0 0.00000
111 1 1 2 0 p1 57 135 161 1.19259 161 0 0.00000
112 2 1 3 1 prev 57 135 218 1.61481 218 0 0.00000
112 2 1 3 1 prev 57 135 218 1.61481 218 0 0.00000
113 3 1 2 0 p1 57 135 161 1.19259 275 114 0.70807
113 3 1 2 0 p1 57 135 161 1.19259 275 114 0.70807
114 $ hg -R full debugdeltachain -m
114 $ hg -R full debugdeltachain -m
115 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
115 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
116 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
116 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
117 1 1 2 0 p1 57 135 161 1.19259 161 0 0.00000
117 1 1 2 0 p1 57 135 161 1.19259 161 0 0.00000
118 2 1 2 0 p1 57 135 161 1.19259 218 57 0.35404
118 2 1 2 0 p1 57 135 161 1.19259 218 57 0.35404
119 3 1 2 0 p1 57 135 161 1.19259 275 114 0.70807
119 3 1 2 0 p1 57 135 161 1.19259 275 114 0.70807
120
120
121 Test revlog.optimize-delta-parent-choice
121 Test revlog.optimize-delta-parent-choice
122
122
123 $ hg init --config format.generaldelta=1 aggressive
123 $ hg init --config format.generaldelta=1 aggressive
124 $ cd aggressive
124 $ cd aggressive
125 $ cat << EOF >> .hg/hgrc
125 $ cat << EOF >> .hg/hgrc
126 > [format]
126 > [format]
127 > generaldelta = 1
127 > generaldelta = 1
128 > EOF
128 > EOF
129 $ touch a b c d e
129 $ touch a b c d e
130 $ hg commit -Aqm side1
130 $ hg commit -Aqm side1
131 $ hg up -q null
131 $ hg up -q null
132 $ touch x y
132 $ touch x y
133 $ hg commit -Aqm side2
133 $ hg commit -Aqm side2
134
134
135 - Verify non-aggressive merge uses p1 (commit 1) as delta parent
135 - Verify non-aggressive merge uses p1 (commit 1) as delta parent
136 $ hg merge -q 0
136 $ hg merge -q 0
137 $ hg commit -q -m merge
137 $ hg commit -q -m merge
138 $ hg debugdeltachain -m
138 $ hg debugdeltachain -m
139 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
139 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
140 0 1 1 -1 base 59 215 59 0.27442 59 0 0.00000
140 0 1 1 -1 base 59 215 59 0.27442 59 0 0.00000
141 1 1 2 0 prev 61 86 120 1.39535 120 0 0.00000
141 1 1 2 0 prev 61 86 120 1.39535 120 0 0.00000
142 2 1 2 0 p2 62 301 121 0.40199 182 61 0.50413
142 2 1 2 0 p2 62 301 121 0.40199 182 61 0.50413
143
143
144 $ hg strip -q -r . --config extensions.strip=
144 $ hg strip -q -r . --config extensions.strip=
145
145
146 - Verify aggressive merge uses p2 (commit 0) as delta parent
146 - Verify aggressive merge uses p2 (commit 0) as delta parent
147 $ hg up -q -C 1
147 $ hg up -q -C 1
148 $ hg merge -q 0
148 $ hg merge -q 0
149 $ hg commit -q -m merge --config storage.revlog.optimize-delta-parent-choice=yes
149 $ hg commit -q -m merge --config storage.revlog.optimize-delta-parent-choice=yes
150 $ hg debugdeltachain -m
150 $ hg debugdeltachain -m
151 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
151 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
152 0 1 1 -1 base 59 215 59 0.27442 59 0 0.00000
152 0 1 1 -1 base 59 215 59 0.27442 59 0 0.00000
153 1 1 2 0 prev 61 86 120 1.39535 120 0 0.00000
153 1 1 2 0 prev 61 86 120 1.39535 120 0 0.00000
154 2 1 2 0 p2 62 301 121 0.40199 182 61 0.50413
154 2 1 2 0 p2 62 301 121 0.40199 182 61 0.50413
155
155
156 Test that strip bundle use bundle2
156 Test that strip bundle use bundle2
157 $ hg --config extensions.strip= strip .
157 $ hg --config extensions.strip= strip .
158 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
158 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
159 saved backup bundle to $TESTTMP/aggressive/.hg/strip-backup/1c5d4dc9a8b8-6c68e60c-backup.hg
159 saved backup bundle to $TESTTMP/aggressive/.hg/strip-backup/1c5d4dc9a8b8-6c68e60c-backup.hg
160 $ hg debugbundle .hg/strip-backup/*
160 $ hg debugbundle .hg/strip-backup/*
161 Stream params: {Compression: BZ}
161 Stream params: {Compression: BZ}
162 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
162 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
163 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9
163 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9
164 cache:rev-branch-cache -- {} (mandatory: False)
164 cache:rev-branch-cache -- {} (mandatory: False)
165 phase-heads -- {} (mandatory: True)
165 phase-heads -- {} (mandatory: True)
166 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9 draft
166 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9 draft
167
167
168 $ cd ..
168 $ cd ..
169
169
170 test maxdeltachainspan
170 test maxdeltachainspan
171
171
172 $ hg init source-repo
172 $ hg init source-repo
173 $ cd source-repo
173 $ cd source-repo
174 $ hg debugbuilddag --new-file '.+5:brancha$.+11:branchb$.+30:branchc<brancha+2<branchb+2'
174 $ hg debugbuilddag --new-file '.+5:brancha$.+11:branchb$.+30:branchc<brancha+2<branchb+2'
175 # add an empty revision somewhere
175 # add an empty revision somewhere
176 $ hg up tip
176 $ hg up tip
177 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
177 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
178 $ hg rm .
178 $ hg rm .
179 removing nf10
179 removing nf10
180 removing nf11
180 removing nf11
181 removing nf12
181 removing nf12
182 removing nf13
182 removing nf13
183 removing nf14
183 removing nf14
184 removing nf15
184 removing nf15
185 removing nf16
185 removing nf16
186 removing nf17
186 removing nf17
187 removing nf51
187 removing nf51
188 removing nf52
188 removing nf52
189 removing nf6
189 removing nf6
190 removing nf7
190 removing nf7
191 removing nf8
191 removing nf8
192 removing nf9
192 removing nf9
193 $ hg commit -m 'empty all'
193 $ hg commit -m 'empty all'
194 $ hg revert --all --rev 'p1(.)'
194 $ hg revert --all --rev 'p1(.)'
195 adding nf10
195 adding nf10
196 adding nf11
196 adding nf11
197 adding nf12
197 adding nf12
198 adding nf13
198 adding nf13
199 adding nf14
199 adding nf14
200 adding nf15
200 adding nf15
201 adding nf16
201 adding nf16
202 adding nf17
202 adding nf17
203 adding nf51
203 adding nf51
204 adding nf52
204 adding nf52
205 adding nf6
205 adding nf6
206 adding nf7
206 adding nf7
207 adding nf8
207 adding nf8
208 adding nf9
208 adding nf9
209 $ hg commit -m 'restore all'
209 $ hg commit -m 'restore all'
210 $ hg up null
210 $ hg up null
211 0 files updated, 0 files merged, 14 files removed, 0 files unresolved
211 0 files updated, 0 files merged, 14 files removed, 0 files unresolved
212 $
212 $
213 $ cd ..
213 $ cd ..
214 $ hg -R source-repo debugdeltachain -m
214 $ hg -R source-repo debugdeltachain -m
215 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
215 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
216 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
216 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
217 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
217 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
218 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
218 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
219 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
219 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
220 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
220 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
221 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
221 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
222 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
222 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
223 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
223 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
224 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
224 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
225 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
225 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
226 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
226 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
227 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
227 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
228 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
228 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
229 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
229 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
230 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
230 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
231 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
231 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
232 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
232 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
233 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
233 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
234 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
234 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
235 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
235 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
236 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
236 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
237 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
237 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
238 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
238 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
239 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
239 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
240 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
240 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
241 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
241 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
242 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
242 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
243 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
243 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
244 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
244 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
245 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
245 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
246 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
246 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
247 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
247 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
248 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
248 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
249 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
249 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
250 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
250 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
251 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
251 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
252 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
252 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
253 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
253 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
254 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
254 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
255 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
255 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
256 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
256 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
257 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
257 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
258 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
258 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
259 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
259 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
260 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
260 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
261 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
261 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
262 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
262 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
263 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
263 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
264 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
264 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
265 49 4 1 -1 base 197 316 197 0.62342 197 0 0.00000
265 49 4 1 -1 base 197 316 197 0.62342 197 0 0.00000
266 50 4 2 49 p1 58 362 255 0.70442 255 0 0.00000
266 50 4 2 49 p1 58 362 255 0.70442 255 0 0.00000
267 51 4 3 50 prev 356 594 611 1.02862 611 0 0.00000
267 51 4 3 50 prev 356 594 611 1.02862 611 0 0.00000
268 52 4 4 51 p1 58 640 669 1.04531 669 0 0.00000
268 52 4 4 51 p1 58 640 669 1.04531 669 0 0.00000
269 53 5 1 -1 base 0 0 0 0.00000 0 0 0.00000
269 53 5 1 -1 base 0 0 0 0.00000 0 0 0.00000
270 54 6 1 -1 base 369 640 369 0.57656 369 0 0.00000
270 54 6 1 -1 base 369 640 369 0.57656 369 0 0.00000
271 $ hg clone --pull source-repo --config experimental.maxdeltachainspan=2800 relax-chain --config format.generaldelta=yes
271 $ hg clone --pull source-repo --config experimental.maxdeltachainspan=2800 relax-chain --config format.generaldelta=yes
272 requesting all changes
272 requesting all changes
273 adding changesets
273 adding changesets
274 adding manifests
274 adding manifests
275 adding file changes
275 adding file changes
276 added 55 changesets with 53 changes to 53 files (+2 heads)
276 added 55 changesets with 53 changes to 53 files (+2 heads)
277 new changesets 61246295ee1e:c930ac4a5b32
277 new changesets 61246295ee1e:c930ac4a5b32
278 updating to branch default
278 updating to branch default
279 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
279 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 $ hg -R relax-chain debugdeltachain -m
280 $ hg -R relax-chain debugdeltachain -m
281 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
281 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
282 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
282 0 1 1 -1 base 47 46 47 1.02174 47 0 0.00000
283 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
283 1 1 2 0 p1 58 92 105 1.14130 105 0 0.00000
284 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
284 2 1 3 1 p1 58 138 163 1.18116 163 0 0.00000
285 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
285 3 1 4 2 p1 58 184 221 1.20109 221 0 0.00000
286 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
286 4 1 5 3 p1 58 230 279 1.21304 279 0 0.00000
287 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
287 5 1 6 4 p1 58 276 337 1.22101 337 0 0.00000
288 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
288 6 1 7 5 p1 58 322 395 1.22671 395 0 0.00000
289 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
289 7 1 8 6 p1 58 368 453 1.23098 453 0 0.00000
290 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
290 8 1 9 7 p1 58 414 511 1.23430 511 0 0.00000
291 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
291 9 1 10 8 p1 58 460 569 1.23696 569 0 0.00000
292 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
292 10 1 11 9 p1 58 506 627 1.23913 627 0 0.00000
293 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
293 11 1 12 10 p1 58 552 685 1.24094 685 0 0.00000
294 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
294 12 1 13 11 p1 58 598 743 1.24247 743 0 0.00000
295 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
295 13 1 14 12 p1 58 644 801 1.24379 801 0 0.00000
296 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
296 14 1 15 13 p1 58 690 859 1.24493 859 0 0.00000
297 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
297 15 1 16 14 p1 58 736 917 1.24592 917 0 0.00000
298 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
298 16 1 17 15 p1 58 782 975 1.24680 975 0 0.00000
299 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
299 17 1 18 16 p1 58 828 1033 1.24758 1033 0 0.00000
300 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
300 18 1 19 17 p1 58 874 1091 1.24828 1091 0 0.00000
301 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
301 19 1 20 18 p1 58 920 1149 1.24891 1149 0 0.00000
302 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
302 20 1 21 19 p1 58 966 1207 1.24948 1207 0 0.00000
303 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
303 21 1 22 20 p1 58 1012 1265 1.25000 1265 0 0.00000
304 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
304 22 1 23 21 p1 58 1058 1323 1.25047 1323 0 0.00000
305 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
305 23 1 24 22 p1 58 1104 1381 1.25091 1381 0 0.00000
306 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
306 24 1 25 23 p1 58 1150 1439 1.25130 1439 0 0.00000
307 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
307 25 1 26 24 p1 58 1196 1497 1.25167 1497 0 0.00000
308 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
308 26 1 27 25 p1 58 1242 1555 1.25201 1555 0 0.00000
309 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
309 27 1 28 26 p1 58 1288 1613 1.25233 1613 0 0.00000
310 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
310 28 1 29 27 p1 58 1334 1671 1.25262 1671 0 0.00000
311 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
311 29 1 30 28 p1 58 1380 1729 1.25290 1729 0 0.00000
312 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
312 30 1 31 29 p1 58 1426 1787 1.25316 1787 0 0.00000
313 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
313 31 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
314 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
314 32 2 2 31 p1 57 90 103 1.14444 103 0 0.00000
315 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
315 33 2 3 32 p1 57 135 160 1.18519 160 0 0.00000
316 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
316 34 2 4 33 p1 57 180 217 1.20556 217 0 0.00000
317 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
317 35 2 5 34 p1 57 225 274 1.21778 274 0 0.00000
318 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
318 36 2 6 35 p1 57 270 331 1.22593 331 0 0.00000
319 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
319 37 2 7 36 p1 58 316 389 1.23101 389 0 0.00000
320 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
320 38 2 8 37 p1 58 362 447 1.23481 447 0 0.00000
321 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
321 39 3 1 -1 base 46 45 46 1.02222 46 0 0.00000
322 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
322 40 3 2 39 p1 57 90 103 1.14444 103 0 0.00000
323 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
323 41 3 3 40 p1 57 135 160 1.18519 160 0 0.00000
324 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
324 42 3 4 41 p1 57 180 217 1.20556 217 0 0.00000
325 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
325 43 3 5 42 p1 58 226 275 1.21681 275 0 0.00000
326 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
326 44 3 6 43 p1 58 272 333 1.22426 333 0 0.00000
327 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
327 45 3 7 44 p1 58 318 391 1.22956 391 0 0.00000
328 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
328 46 3 8 45 p1 58 364 449 1.23352 449 0 0.00000
329 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
329 47 3 9 46 p1 58 410 507 1.23659 507 0 0.00000
330 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
330 48 3 10 47 p1 58 456 565 1.23904 565 0 0.00000
331 49 4 1 -1 base 197 316 197 0.62342 197 0 0.00000
331 49 3 11 48 p1 58 502 623 1.24104 623 0 0.00000
332 50 4 2 49 p1 58 362 255 0.70442 255 0 0.00000
332 50 3 12 49 p1 58 548 681 1.24270 681 0 0.00000
333 51 2 13 17 p1 58 594 739 1.24411 2781 2042 2.76319
333 51 3 13 50 p1 58 594 739 1.24411 739 0 0.00000
334 52 5 1 -1 base 369 640 369 0.57656 369 0 0.00000
334 52 3 14 51 p1 58 640 797 1.24531 797 0 0.00000
335 53 6 1 -1 base 0 0 0 0.00000 0 0 0.00000
335 53 4 1 -1 base 0 0 0 0.00000 0 0 0.00000
336 54 7 1 -1 base 369 640 369 0.57656 369 0 0.00000
336 54 5 1 -1 base 369 640 369 0.57656 369 0 0.00000
337 $ hg clone --pull source-repo --config experimental.maxdeltachainspan=0 noconst-chain --config format.generaldelta=yes
337 $ hg clone --pull source-repo --config experimental.maxdeltachainspan=0 noconst-chain --config format.generaldelta=yes
338 requesting all changes
338 requesting all changes
339 adding changesets
339 adding changesets
340 adding manifests
340 adding manifests
341 adding file changes
341 adding file changes
342 added 55 changesets with 53 changes to 53 files (+2 heads)
342 added 55 changesets with 53 changes to 53 files (+2 heads)
343 new changesets 61246295ee1e:c930ac4a5b32
343 new changesets 61246295ee1e:c930ac4a5b32
344 updating to branch default
344 updating to branch default
345 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
345 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
346 $ hg -R noconst-chain debugdeltachain -m
346 $ hg -R noconst-chain debugdeltachain -m
347 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
347 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
348 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
348 0 1 1 -1 base 47 46 47 1.02174 47 0 0.00000
349 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
349 1 1 2 0 p1 58 92 105 1.14130 105 0 0.00000
350 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
350 2 1 3 1 p1 58 138 163 1.18116 163 0 0.00000
351 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
351 3 1 4 2 p1 58 184 221 1.20109 221 0 0.00000
352 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
352 4 1 5 3 p1 58 230 279 1.21304 279 0 0.00000
353 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
353 5 1 6 4 p1 58 276 337 1.22101 337 0 0.00000
354 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
354 6 1 7 5 p1 58 322 395 1.22671 395 0 0.00000
355 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
355 7 1 8 6 p1 58 368 453 1.23098 453 0 0.00000
356 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
356 8 1 9 7 p1 58 414 511 1.23430 511 0 0.00000
357 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
357 9 1 10 8 p1 58 460 569 1.23696 569 0 0.00000
358 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
358 10 1 11 9 p1 58 506 627 1.23913 627 0 0.00000
359 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
359 11 1 12 10 p1 58 552 685 1.24094 685 0 0.00000
360 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
360 12 1 13 11 p1 58 598 743 1.24247 743 0 0.00000
361 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
361 13 1 14 12 p1 58 644 801 1.24379 801 0 0.00000
362 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
362 14 1 15 13 p1 58 690 859 1.24493 859 0 0.00000
363 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
363 15 1 16 14 p1 58 736 917 1.24592 917 0 0.00000
364 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
364 16 1 17 15 p1 58 782 975 1.24680 975 0 0.00000
365 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
365 17 1 18 16 p1 58 828 1033 1.24758 1033 0 0.00000
366 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
366 18 1 19 17 p1 58 874 1091 1.24828 1091 0 0.00000
367 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
367 19 1 20 18 p1 58 920 1149 1.24891 1149 0 0.00000
368 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
368 20 1 21 19 p1 58 966 1207 1.24948 1207 0 0.00000
369 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
369 21 1 22 20 p1 58 1012 1265 1.25000 1265 0 0.00000
370 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
370 22 1 23 21 p1 58 1058 1323 1.25047 1323 0 0.00000
371 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
371 23 1 24 22 p1 58 1104 1381 1.25091 1381 0 0.00000
372 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
372 24 1 25 23 p1 58 1150 1439 1.25130 1439 0 0.00000
373 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
373 25 1 26 24 p1 58 1196 1497 1.25167 1497 0 0.00000
374 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
374 26 1 27 25 p1 58 1242 1555 1.25201 1555 0 0.00000
375 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
375 27 1 28 26 p1 58 1288 1613 1.25233 1613 0 0.00000
376 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
376 28 1 29 27 p1 58 1334 1671 1.25262 1671 0 0.00000
377 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
377 29 1 30 28 p1 58 1380 1729 1.25290 1729 0 0.00000
378 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
378 30 1 31 29 p1 58 1426 1787 1.25316 1787 0 0.00000
379 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
379 31 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
380 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
380 32 2 2 31 p1 57 90 103 1.14444 103 0 0.00000
381 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
381 33 2 3 32 p1 57 135 160 1.18519 160 0 0.00000
382 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
382 34 2 4 33 p1 57 180 217 1.20556 217 0 0.00000
383 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
383 35 2 5 34 p1 57 225 274 1.21778 274 0 0.00000
384 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
384 36 2 6 35 p1 57 270 331 1.22593 331 0 0.00000
385 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
385 37 2 7 36 p1 58 316 389 1.23101 389 0 0.00000
386 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
386 38 2 8 37 p1 58 362 447 1.23481 447 0 0.00000
387 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
387 39 3 1 -1 base 46 45 46 1.02222 46 0 0.00000
388 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
388 40 3 2 39 p1 57 90 103 1.14444 103 0 0.00000
389 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
389 41 3 3 40 p1 57 135 160 1.18519 160 0 0.00000
390 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
390 42 3 4 41 p1 57 180 217 1.20556 217 0 0.00000
391 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
391 43 3 5 42 p1 58 226 275 1.21681 275 0 0.00000
392 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
392 44 3 6 43 p1 58 272 333 1.22426 333 0 0.00000
393 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
393 45 3 7 44 p1 58 318 391 1.22956 391 0 0.00000
394 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
394 46 3 8 45 p1 58 364 449 1.23352 449 0 0.00000
395 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
395 47 3 9 46 p1 58 410 507 1.23659 507 0 0.00000
396 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
396 48 3 10 47 p1 58 456 565 1.23904 565 0 0.00000
397 49 1 7 5 p1 58 316 389 1.23101 2857 2468 6.34447
397 49 3 11 48 p1 58 502 623 1.24104 623 0 0.00000
398 50 1 8 49 p1 58 362 447 1.23481 2915 2468 5.52125
398 50 3 12 49 p1 58 548 681 1.24270 681 0 0.00000
399 51 2 13 17 p1 58 594 739 1.24411 2642 1903 2.57510
399 51 3 13 50 p1 58 594 739 1.24411 739 0 0.00000
400 52 2 14 51 p1 58 640 797 1.24531 2700 1903 2.38770
400 52 3 14 51 p1 58 640 797 1.24531 797 0 0.00000
401 53 4 1 -1 base 0 0 0 0.00000 0 0 0.00000
401 53 4 1 -1 base 0 0 0 0.00000 0 0 0.00000
402 54 5 1 -1 base 369 640 369 0.57656 369 0 0.00000
402 54 5 1 -1 base 369 640 369 0.57656 369 0 0.00000
General Comments 0
You need to be logged in to leave comments. Login now