##// END OF EJS Templates
changegroup: don't limit cgv4 to revlogv2 repos...
Raphaël Gomès -
r47842:08e26ef4 default
parent child Browse files
Show More
@@ -1,1944 +1,1947 b''
1 1 # changegroup.py - Mercurial changegroup manipulation functions
2 2 #
3 3 # Copyright 2006 Olivia Mackall <olivia@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import collections
11 11 import os
12 12 import struct
13 13 import weakref
14 14
15 15 from .i18n import _
16 16 from .node import (
17 17 hex,
18 18 nullrev,
19 19 short,
20 20 )
21 21 from .pycompat import open
22 22
23 23 from . import (
24 24 error,
25 25 match as matchmod,
26 26 mdiff,
27 27 phases,
28 28 pycompat,
29 29 requirements,
30 30 scmutil,
31 31 util,
32 32 )
33 33
34 34 from .interfaces import repository
35 35 from .revlogutils import sidedata as sidedatamod
36 36 from .revlogutils import constants as revlog_constants
37 37
38 38 _CHANGEGROUPV1_DELTA_HEADER = struct.Struct(b"20s20s20s20s")
39 39 _CHANGEGROUPV2_DELTA_HEADER = struct.Struct(b"20s20s20s20s20s")
40 40 _CHANGEGROUPV3_DELTA_HEADER = struct.Struct(b">20s20s20s20s20sH")
41 41
42 42 LFS_REQUIREMENT = b'lfs'
43 43
44 44 readexactly = util.readexactly
45 45
46 46
47 47 def getchunk(stream):
48 48 """return the next chunk from stream as a string"""
49 49 d = readexactly(stream, 4)
50 50 l = struct.unpack(b">l", d)[0]
51 51 if l <= 4:
52 52 if l:
53 53 raise error.Abort(_(b"invalid chunk length %d") % l)
54 54 return b""
55 55 return readexactly(stream, l - 4)
56 56
57 57
58 58 def chunkheader(length):
59 59 """return a changegroup chunk header (string)"""
60 60 return struct.pack(b">l", length + 4)
61 61
62 62
63 63 def closechunk():
64 64 """return a changegroup chunk header (string) for a zero-length chunk"""
65 65 return struct.pack(b">l", 0)
66 66
67 67
68 68 def _fileheader(path):
69 69 """Obtain a changegroup chunk header for a named path."""
70 70 return chunkheader(len(path)) + path
71 71
72 72
73 73 def writechunks(ui, chunks, filename, vfs=None):
74 74 """Write chunks to a file and return its filename.
75 75
76 76 The stream is assumed to be a bundle file.
77 77 Existing files will not be overwritten.
78 78 If no filename is specified, a temporary file is created.
79 79 """
80 80 fh = None
81 81 cleanup = None
82 82 try:
83 83 if filename:
84 84 if vfs:
85 85 fh = vfs.open(filename, b"wb")
86 86 else:
87 87 # Increase default buffer size because default is usually
88 88 # small (4k is common on Linux).
89 89 fh = open(filename, b"wb", 131072)
90 90 else:
91 91 fd, filename = pycompat.mkstemp(prefix=b"hg-bundle-", suffix=b".hg")
92 92 fh = os.fdopen(fd, "wb")
93 93 cleanup = filename
94 94 for c in chunks:
95 95 fh.write(c)
96 96 cleanup = None
97 97 return filename
98 98 finally:
99 99 if fh is not None:
100 100 fh.close()
101 101 if cleanup is not None:
102 102 if filename and vfs:
103 103 vfs.unlink(cleanup)
104 104 else:
105 105 os.unlink(cleanup)
106 106
107 107
108 108 class cg1unpacker(object):
109 109 """Unpacker for cg1 changegroup streams.
110 110
111 111 A changegroup unpacker handles the framing of the revision data in
112 112 the wire format. Most consumers will want to use the apply()
113 113 method to add the changes from the changegroup to a repository.
114 114
115 115 If you're forwarding a changegroup unmodified to another consumer,
116 116 use getchunks(), which returns an iterator of changegroup
117 117 chunks. This is mostly useful for cases where you need to know the
118 118 data stream has ended by observing the end of the changegroup.
119 119
120 120 deltachunk() is useful only if you're applying delta data. Most
121 121 consumers should prefer apply() instead.
122 122
123 123 A few other public methods exist. Those are used only for
124 124 bundlerepo and some debug commands - their use is discouraged.
125 125 """
126 126
127 127 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
128 128 deltaheadersize = deltaheader.size
129 129 version = b'01'
130 130 _grouplistcount = 1 # One list of files after the manifests
131 131
132 132 def __init__(self, fh, alg, extras=None):
133 133 if alg is None:
134 134 alg = b'UN'
135 135 if alg not in util.compengines.supportedbundletypes:
136 136 raise error.Abort(_(b'unknown stream compression type: %s') % alg)
137 137 if alg == b'BZ':
138 138 alg = b'_truncatedBZ'
139 139
140 140 compengine = util.compengines.forbundletype(alg)
141 141 self._stream = compengine.decompressorreader(fh)
142 142 self._type = alg
143 143 self.extras = extras or {}
144 144 self.callback = None
145 145
146 146 # These methods (compressed, read, seek, tell) all appear to only
147 147 # be used by bundlerepo, but it's a little hard to tell.
148 148 def compressed(self):
149 149 return self._type is not None and self._type != b'UN'
150 150
151 151 def read(self, l):
152 152 return self._stream.read(l)
153 153
154 154 def seek(self, pos):
155 155 return self._stream.seek(pos)
156 156
157 157 def tell(self):
158 158 return self._stream.tell()
159 159
160 160 def close(self):
161 161 return self._stream.close()
162 162
163 163 def _chunklength(self):
164 164 d = readexactly(self._stream, 4)
165 165 l = struct.unpack(b">l", d)[0]
166 166 if l <= 4:
167 167 if l:
168 168 raise error.Abort(_(b"invalid chunk length %d") % l)
169 169 return 0
170 170 if self.callback:
171 171 self.callback()
172 172 return l - 4
173 173
174 174 def changelogheader(self):
175 175 """v10 does not have a changelog header chunk"""
176 176 return {}
177 177
178 178 def manifestheader(self):
179 179 """v10 does not have a manifest header chunk"""
180 180 return {}
181 181
182 182 def filelogheader(self):
183 183 """return the header of the filelogs chunk, v10 only has the filename"""
184 184 l = self._chunklength()
185 185 if not l:
186 186 return {}
187 187 fname = readexactly(self._stream, l)
188 188 return {b'filename': fname}
189 189
190 190 def _deltaheader(self, headertuple, prevnode):
191 191 node, p1, p2, cs = headertuple
192 192 if prevnode is None:
193 193 deltabase = p1
194 194 else:
195 195 deltabase = prevnode
196 196 flags = 0
197 197 return node, p1, p2, deltabase, cs, flags
198 198
199 199 def deltachunk(self, prevnode):
200 200 l = self._chunklength()
201 201 if not l:
202 202 return {}
203 203 headerdata = readexactly(self._stream, self.deltaheadersize)
204 204 header = self.deltaheader.unpack(headerdata)
205 205 delta = readexactly(self._stream, l - self.deltaheadersize)
206 206 node, p1, p2, deltabase, cs, flags = self._deltaheader(header, prevnode)
207 207 # cg4 forward-compat
208 208 sidedata = {}
209 209 return (node, p1, p2, cs, deltabase, delta, flags, sidedata)
210 210
211 211 def getchunks(self):
212 212 """returns all the chunks contains in the bundle
213 213
214 214 Used when you need to forward the binary stream to a file or another
215 215 network API. To do so, it parse the changegroup data, otherwise it will
216 216 block in case of sshrepo because it don't know the end of the stream.
217 217 """
218 218 # For changegroup 1 and 2, we expect 3 parts: changelog, manifestlog,
219 219 # and a list of filelogs. For changegroup 3, we expect 4 parts:
220 220 # changelog, manifestlog, a list of tree manifestlogs, and a list of
221 221 # filelogs.
222 222 #
223 223 # Changelog and manifestlog parts are terminated with empty chunks. The
224 224 # tree and file parts are a list of entry sections. Each entry section
225 225 # is a series of chunks terminating in an empty chunk. The list of these
226 226 # entry sections is terminated in yet another empty chunk, so we know
227 227 # we've reached the end of the tree/file list when we reach an empty
228 228 # chunk that was proceeded by no non-empty chunks.
229 229
230 230 parts = 0
231 231 while parts < 2 + self._grouplistcount:
232 232 noentries = True
233 233 while True:
234 234 chunk = getchunk(self)
235 235 if not chunk:
236 236 # The first two empty chunks represent the end of the
237 237 # changelog and the manifestlog portions. The remaining
238 238 # empty chunks represent either A) the end of individual
239 239 # tree or file entries in the file list, or B) the end of
240 240 # the entire list. It's the end of the entire list if there
241 241 # were no entries (i.e. noentries is True).
242 242 if parts < 2:
243 243 parts += 1
244 244 elif noentries:
245 245 parts += 1
246 246 break
247 247 noentries = False
248 248 yield chunkheader(len(chunk))
249 249 pos = 0
250 250 while pos < len(chunk):
251 251 next = pos + 2 ** 20
252 252 yield chunk[pos:next]
253 253 pos = next
254 254 yield closechunk()
255 255
256 256 def _unpackmanifests(self, repo, revmap, trp, prog, addrevisioncb=None):
257 257 self.callback = prog.increment
258 258 # no need to check for empty manifest group here:
259 259 # if the result of the merge of 1 and 2 is the same in 3 and 4,
260 260 # no new manifest will be created and the manifest group will
261 261 # be empty during the pull
262 262 self.manifestheader()
263 263 deltas = self.deltaiter()
264 264 storage = repo.manifestlog.getstorage(b'')
265 265 storage.addgroup(deltas, revmap, trp, addrevisioncb=addrevisioncb)
266 266 prog.complete()
267 267 self.callback = None
268 268
269 269 def apply(
270 270 self,
271 271 repo,
272 272 tr,
273 273 srctype,
274 274 url,
275 275 targetphase=phases.draft,
276 276 expectedtotal=None,
277 277 sidedata_categories=None,
278 278 ):
279 279 """Add the changegroup returned by source.read() to this repo.
280 280 srctype is a string like 'push', 'pull', or 'unbundle'. url is
281 281 the URL of the repo where this changegroup is coming from.
282 282
283 283 Return an integer summarizing the change to this repo:
284 284 - nothing changed or no source: 0
285 285 - more heads than before: 1+added heads (2..n)
286 286 - fewer heads than before: -1-removed heads (-2..-n)
287 287 - number of heads stays the same: 1
288 288
289 289 `sidedata_categories` is an optional set of the remote's sidedata wanted
290 290 categories.
291 291 """
292 292 repo = repo.unfiltered()
293 293
294 294 # Only useful if we're adding sidedata categories. If both peers have
295 295 # the same categories, then we simply don't do anything.
296 296 adding_sidedata = (
297 297 requirements.REVLOGV2_REQUIREMENT in repo.requirements
298 298 and self.version == b'04'
299 299 and srctype == b'pull'
300 300 )
301 301 if adding_sidedata:
302 302 sidedata_helpers = get_sidedata_helpers(
303 303 repo,
304 304 sidedata_categories or set(),
305 305 pull=True,
306 306 )
307 307 else:
308 308 sidedata_helpers = None
309 309
310 310 def csmap(x):
311 311 repo.ui.debug(b"add changeset %s\n" % short(x))
312 312 return len(cl)
313 313
314 314 def revmap(x):
315 315 return cl.rev(x)
316 316
317 317 try:
318 318 # The transaction may already carry source information. In this
319 319 # case we use the top level data. We overwrite the argument
320 320 # because we need to use the top level value (if they exist)
321 321 # in this function.
322 322 srctype = tr.hookargs.setdefault(b'source', srctype)
323 323 tr.hookargs.setdefault(b'url', url)
324 324 repo.hook(
325 325 b'prechangegroup', throw=True, **pycompat.strkwargs(tr.hookargs)
326 326 )
327 327
328 328 # write changelog data to temp files so concurrent readers
329 329 # will not see an inconsistent view
330 330 cl = repo.changelog
331 331 cl.delayupdate(tr)
332 332 oldheads = set(cl.heads())
333 333
334 334 trp = weakref.proxy(tr)
335 335 # pull off the changeset group
336 336 repo.ui.status(_(b"adding changesets\n"))
337 337 clstart = len(cl)
338 338 progress = repo.ui.makeprogress(
339 339 _(b'changesets'), unit=_(b'chunks'), total=expectedtotal
340 340 )
341 341 self.callback = progress.increment
342 342
343 343 efilesset = set()
344 344 duprevs = []
345 345
346 346 def ondupchangelog(cl, rev):
347 347 if rev < clstart:
348 348 duprevs.append(rev)
349 349
350 350 def onchangelog(cl, rev):
351 351 ctx = cl.changelogrevision(rev)
352 352 efilesset.update(ctx.files)
353 353 repo.register_changeset(rev, ctx)
354 354
355 355 self.changelogheader()
356 356 deltas = self.deltaiter()
357 357 if not cl.addgroup(
358 358 deltas,
359 359 csmap,
360 360 trp,
361 361 alwayscache=True,
362 362 addrevisioncb=onchangelog,
363 363 duplicaterevisioncb=ondupchangelog,
364 364 ):
365 365 repo.ui.develwarn(
366 366 b'applied empty changelog from changegroup',
367 367 config=b'warn-empty-changegroup',
368 368 )
369 369 efiles = len(efilesset)
370 370 clend = len(cl)
371 371 changesets = clend - clstart
372 372 progress.complete()
373 373 del deltas
374 374 # TODO Python 2.7 removal
375 375 # del efilesset
376 376 efilesset = None
377 377 self.callback = None
378 378
379 379 # Keep track of the (non-changelog) revlogs we've updated and their
380 380 # range of new revisions for sidedata rewrite.
381 381 # TODO do something more efficient than keeping the reference to
382 382 # the revlogs, especially memory-wise.
383 383 touched_manifests = {}
384 384 touched_filelogs = {}
385 385
386 386 # pull off the manifest group
387 387 repo.ui.status(_(b"adding manifests\n"))
388 388 # We know that we'll never have more manifests than we had
389 389 # changesets.
390 390 progress = repo.ui.makeprogress(
391 391 _(b'manifests'), unit=_(b'chunks'), total=changesets
392 392 )
393 393 on_manifest_rev = None
394 394 if sidedata_helpers:
395 395 if revlog_constants.KIND_MANIFESTLOG in sidedata_helpers[1]:
396 396
397 397 def on_manifest_rev(manifest, rev):
398 398 range = touched_manifests.get(manifest)
399 399 if not range:
400 400 touched_manifests[manifest] = (rev, rev)
401 401 else:
402 402 assert rev == range[1] + 1
403 403 touched_manifests[manifest] = (range[0], rev)
404 404
405 405 self._unpackmanifests(
406 406 repo,
407 407 revmap,
408 408 trp,
409 409 progress,
410 410 addrevisioncb=on_manifest_rev,
411 411 )
412 412
413 413 needfiles = {}
414 414 if repo.ui.configbool(b'server', b'validate'):
415 415 cl = repo.changelog
416 416 ml = repo.manifestlog
417 417 # validate incoming csets have their manifests
418 418 for cset in pycompat.xrange(clstart, clend):
419 419 mfnode = cl.changelogrevision(cset).manifest
420 420 mfest = ml[mfnode].readdelta()
421 421 # store file nodes we must see
422 422 for f, n in pycompat.iteritems(mfest):
423 423 needfiles.setdefault(f, set()).add(n)
424 424
425 425 on_filelog_rev = None
426 426 if sidedata_helpers:
427 427 if revlog_constants.KIND_FILELOG in sidedata_helpers[1]:
428 428
429 429 def on_filelog_rev(filelog, rev):
430 430 range = touched_filelogs.get(filelog)
431 431 if not range:
432 432 touched_filelogs[filelog] = (rev, rev)
433 433 else:
434 434 assert rev == range[1] + 1
435 435 touched_filelogs[filelog] = (range[0], rev)
436 436
437 437 # process the files
438 438 repo.ui.status(_(b"adding file changes\n"))
439 439 newrevs, newfiles = _addchangegroupfiles(
440 440 repo,
441 441 self,
442 442 revmap,
443 443 trp,
444 444 efiles,
445 445 needfiles,
446 446 addrevisioncb=on_filelog_rev,
447 447 )
448 448
449 449 if sidedata_helpers:
450 450 if revlog_constants.KIND_CHANGELOG in sidedata_helpers[1]:
451 451 cl.rewrite_sidedata(sidedata_helpers, clstart, clend - 1)
452 452 for mf, (startrev, endrev) in touched_manifests.items():
453 453 mf.rewrite_sidedata(sidedata_helpers, startrev, endrev)
454 454 for fl, (startrev, endrev) in touched_filelogs.items():
455 455 fl.rewrite_sidedata(sidedata_helpers, startrev, endrev)
456 456
457 457 # making sure the value exists
458 458 tr.changes.setdefault(b'changegroup-count-changesets', 0)
459 459 tr.changes.setdefault(b'changegroup-count-revisions', 0)
460 460 tr.changes.setdefault(b'changegroup-count-files', 0)
461 461 tr.changes.setdefault(b'changegroup-count-heads', 0)
462 462
463 463 # some code use bundle operation for internal purpose. They usually
464 464 # set `ui.quiet` to do this outside of user sight. Size the report
465 465 # of such operation now happens at the end of the transaction, that
466 466 # ui.quiet has not direct effect on the output.
467 467 #
468 468 # To preserve this intend use an inelegant hack, we fail to report
469 469 # the change if `quiet` is set. We should probably move to
470 470 # something better, but this is a good first step to allow the "end
471 471 # of transaction report" to pass tests.
472 472 if not repo.ui.quiet:
473 473 tr.changes[b'changegroup-count-changesets'] += changesets
474 474 tr.changes[b'changegroup-count-revisions'] += newrevs
475 475 tr.changes[b'changegroup-count-files'] += newfiles
476 476
477 477 deltaheads = 0
478 478 if oldheads:
479 479 heads = cl.heads()
480 480 deltaheads += len(heads) - len(oldheads)
481 481 for h in heads:
482 482 if h not in oldheads and repo[h].closesbranch():
483 483 deltaheads -= 1
484 484
485 485 # see previous comment about checking ui.quiet
486 486 if not repo.ui.quiet:
487 487 tr.changes[b'changegroup-count-heads'] += deltaheads
488 488 repo.invalidatevolatilesets()
489 489
490 490 if changesets > 0:
491 491 if b'node' not in tr.hookargs:
492 492 tr.hookargs[b'node'] = hex(cl.node(clstart))
493 493 tr.hookargs[b'node_last'] = hex(cl.node(clend - 1))
494 494 hookargs = dict(tr.hookargs)
495 495 else:
496 496 hookargs = dict(tr.hookargs)
497 497 hookargs[b'node'] = hex(cl.node(clstart))
498 498 hookargs[b'node_last'] = hex(cl.node(clend - 1))
499 499 repo.hook(
500 500 b'pretxnchangegroup',
501 501 throw=True,
502 502 **pycompat.strkwargs(hookargs)
503 503 )
504 504
505 505 added = pycompat.xrange(clstart, clend)
506 506 phaseall = None
507 507 if srctype in (b'push', b'serve'):
508 508 # Old servers can not push the boundary themselves.
509 509 # New servers won't push the boundary if changeset already
510 510 # exists locally as secret
511 511 #
512 512 # We should not use added here but the list of all change in
513 513 # the bundle
514 514 if repo.publishing():
515 515 targetphase = phaseall = phases.public
516 516 else:
517 517 # closer target phase computation
518 518
519 519 # Those changesets have been pushed from the
520 520 # outside, their phases are going to be pushed
521 521 # alongside. Therefor `targetphase` is
522 522 # ignored.
523 523 targetphase = phaseall = phases.draft
524 524 if added:
525 525 phases.registernew(repo, tr, targetphase, added)
526 526 if phaseall is not None:
527 527 if duprevs:
528 528 duprevs.extend(added)
529 529 else:
530 530 duprevs = added
531 531 phases.advanceboundary(repo, tr, phaseall, [], revs=duprevs)
532 532 duprevs = []
533 533
534 534 if changesets > 0:
535 535
536 536 def runhooks(unused_success):
537 537 # These hooks run when the lock releases, not when the
538 538 # transaction closes. So it's possible for the changelog
539 539 # to have changed since we last saw it.
540 540 if clstart >= len(repo):
541 541 return
542 542
543 543 repo.hook(b"changegroup", **pycompat.strkwargs(hookargs))
544 544
545 545 for rev in added:
546 546 args = hookargs.copy()
547 547 args[b'node'] = hex(cl.node(rev))
548 548 del args[b'node_last']
549 549 repo.hook(b"incoming", **pycompat.strkwargs(args))
550 550
551 551 newheads = [h for h in repo.heads() if h not in oldheads]
552 552 repo.ui.log(
553 553 b"incoming",
554 554 b"%d incoming changes - new heads: %s\n",
555 555 len(added),
556 556 b', '.join([hex(c[:6]) for c in newheads]),
557 557 )
558 558
559 559 tr.addpostclose(
560 560 b'changegroup-runhooks-%020i' % clstart,
561 561 lambda tr: repo._afterlock(runhooks),
562 562 )
563 563 finally:
564 564 repo.ui.flush()
565 565 # never return 0 here:
566 566 if deltaheads < 0:
567 567 ret = deltaheads - 1
568 568 else:
569 569 ret = deltaheads + 1
570 570 return ret
571 571
572 572 def deltaiter(self):
573 573 """
574 574 returns an iterator of the deltas in this changegroup
575 575
576 576 Useful for passing to the underlying storage system to be stored.
577 577 """
578 578 chain = None
579 579 for chunkdata in iter(lambda: self.deltachunk(chain), {}):
580 580 # Chunkdata: (node, p1, p2, cs, deltabase, delta, flags, sidedata)
581 581 yield chunkdata
582 582 chain = chunkdata[0]
583 583
584 584
585 585 class cg2unpacker(cg1unpacker):
586 586 """Unpacker for cg2 streams.
587 587
588 588 cg2 streams add support for generaldelta, so the delta header
589 589 format is slightly different. All other features about the data
590 590 remain the same.
591 591 """
592 592
593 593 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
594 594 deltaheadersize = deltaheader.size
595 595 version = b'02'
596 596
597 597 def _deltaheader(self, headertuple, prevnode):
598 598 node, p1, p2, deltabase, cs = headertuple
599 599 flags = 0
600 600 return node, p1, p2, deltabase, cs, flags
601 601
602 602
603 603 class cg3unpacker(cg2unpacker):
604 604 """Unpacker for cg3 streams.
605 605
606 606 cg3 streams add support for exchanging treemanifests and revlog
607 607 flags. It adds the revlog flags to the delta header and an empty chunk
608 608 separating manifests and files.
609 609 """
610 610
611 611 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
612 612 deltaheadersize = deltaheader.size
613 613 version = b'03'
614 614 _grouplistcount = 2 # One list of manifests and one list of files
615 615
616 616 def _deltaheader(self, headertuple, prevnode):
617 617 node, p1, p2, deltabase, cs, flags = headertuple
618 618 return node, p1, p2, deltabase, cs, flags
619 619
620 620 def _unpackmanifests(self, repo, revmap, trp, prog, addrevisioncb=None):
621 621 super(cg3unpacker, self)._unpackmanifests(
622 622 repo, revmap, trp, prog, addrevisioncb=addrevisioncb
623 623 )
624 624 for chunkdata in iter(self.filelogheader, {}):
625 625 # If we get here, there are directory manifests in the changegroup
626 626 d = chunkdata[b"filename"]
627 627 repo.ui.debug(b"adding %s revisions\n" % d)
628 628 deltas = self.deltaiter()
629 629 if not repo.manifestlog.getstorage(d).addgroup(
630 630 deltas, revmap, trp, addrevisioncb=addrevisioncb
631 631 ):
632 632 raise error.Abort(_(b"received dir revlog group is empty"))
633 633
634 634
635 635 class cg4unpacker(cg3unpacker):
636 636 """Unpacker for cg4 streams.
637 637
638 638 cg4 streams add support for exchanging sidedata.
639 639 """
640 640
641 641 version = b'04'
642 642
643 643 def deltachunk(self, prevnode):
644 644 res = super(cg4unpacker, self).deltachunk(prevnode)
645 645 if not res:
646 646 return res
647 647
648 648 (node, p1, p2, cs, deltabase, delta, flags, _sidedata) = res
649 649
650 650 sidedata_raw = getchunk(self._stream)
651 651 sidedata = {}
652 652 if len(sidedata_raw) > 0:
653 653 sidedata = sidedatamod.deserialize_sidedata(sidedata_raw)
654 654
655 655 return node, p1, p2, cs, deltabase, delta, flags, sidedata
656 656
657 657
658 658 class headerlessfixup(object):
659 659 def __init__(self, fh, h):
660 660 self._h = h
661 661 self._fh = fh
662 662
663 663 def read(self, n):
664 664 if self._h:
665 665 d, self._h = self._h[:n], self._h[n:]
666 666 if len(d) < n:
667 667 d += readexactly(self._fh, n - len(d))
668 668 return d
669 669 return readexactly(self._fh, n)
670 670
671 671
672 672 def _revisiondeltatochunks(repo, delta, headerfn):
673 673 """Serialize a revisiondelta to changegroup chunks."""
674 674
675 675 # The captured revision delta may be encoded as a delta against
676 676 # a base revision or as a full revision. The changegroup format
677 677 # requires that everything on the wire be deltas. So for full
678 678 # revisions, we need to invent a header that says to rewrite
679 679 # data.
680 680
681 681 if delta.delta is not None:
682 682 prefix, data = b'', delta.delta
683 683 elif delta.basenode == repo.nullid:
684 684 data = delta.revision
685 685 prefix = mdiff.trivialdiffheader(len(data))
686 686 else:
687 687 data = delta.revision
688 688 prefix = mdiff.replacediffheader(delta.baserevisionsize, len(data))
689 689
690 690 meta = headerfn(delta)
691 691
692 692 yield chunkheader(len(meta) + len(prefix) + len(data))
693 693 yield meta
694 694 if prefix:
695 695 yield prefix
696 696 yield data
697 697
698 698 sidedata = delta.sidedata
699 699 if sidedata is not None:
700 700 # Need a separate chunk for sidedata to be able to differentiate
701 701 # "raw delta" length and sidedata length
702 702 yield chunkheader(len(sidedata))
703 703 yield sidedata
704 704
705 705
706 706 def _sortnodesellipsis(store, nodes, cl, lookup):
707 707 """Sort nodes for changegroup generation."""
708 708 # Ellipses serving mode.
709 709 #
710 710 # In a perfect world, we'd generate better ellipsis-ified graphs
711 711 # for non-changelog revlogs. In practice, we haven't started doing
712 712 # that yet, so the resulting DAGs for the manifestlog and filelogs
713 713 # are actually full of bogus parentage on all the ellipsis
714 714 # nodes. This has the side effect that, while the contents are
715 715 # correct, the individual DAGs might be completely out of whack in
716 716 # a case like 882681bc3166 and its ancestors (back about 10
717 717 # revisions or so) in the main hg repo.
718 718 #
719 719 # The one invariant we *know* holds is that the new (potentially
720 720 # bogus) DAG shape will be valid if we order the nodes in the
721 721 # order that they're introduced in dramatis personae by the
722 722 # changelog, so what we do is we sort the non-changelog histories
723 723 # by the order in which they are used by the changelog.
724 724 key = lambda n: cl.rev(lookup(n))
725 725 return sorted(nodes, key=key)
726 726
727 727
728 728 def _resolvenarrowrevisioninfo(
729 729 cl,
730 730 store,
731 731 ischangelog,
732 732 rev,
733 733 linkrev,
734 734 linknode,
735 735 clrevtolocalrev,
736 736 fullclnodes,
737 737 precomputedellipsis,
738 738 ):
739 739 linkparents = precomputedellipsis[linkrev]
740 740
741 741 def local(clrev):
742 742 """Turn a changelog revnum into a local revnum.
743 743
744 744 The ellipsis dag is stored as revnums on the changelog,
745 745 but when we're producing ellipsis entries for
746 746 non-changelog revlogs, we need to turn those numbers into
747 747 something local. This does that for us, and during the
748 748 changelog sending phase will also expand the stored
749 749 mappings as needed.
750 750 """
751 751 if clrev == nullrev:
752 752 return nullrev
753 753
754 754 if ischangelog:
755 755 return clrev
756 756
757 757 # Walk the ellipsis-ized changelog breadth-first looking for a
758 758 # change that has been linked from the current revlog.
759 759 #
760 760 # For a flat manifest revlog only a single step should be necessary
761 761 # as all relevant changelog entries are relevant to the flat
762 762 # manifest.
763 763 #
764 764 # For a filelog or tree manifest dirlog however not every changelog
765 765 # entry will have been relevant, so we need to skip some changelog
766 766 # nodes even after ellipsis-izing.
767 767 walk = [clrev]
768 768 while walk:
769 769 p = walk[0]
770 770 walk = walk[1:]
771 771 if p in clrevtolocalrev:
772 772 return clrevtolocalrev[p]
773 773 elif p in fullclnodes:
774 774 walk.extend([pp for pp in cl.parentrevs(p) if pp != nullrev])
775 775 elif p in precomputedellipsis:
776 776 walk.extend(
777 777 [pp for pp in precomputedellipsis[p] if pp != nullrev]
778 778 )
779 779 else:
780 780 # In this case, we've got an ellipsis with parents
781 781 # outside the current bundle (likely an
782 782 # incremental pull). We "know" that we can use the
783 783 # value of this same revlog at whatever revision
784 784 # is pointed to by linknode. "Know" is in scare
785 785 # quotes because I haven't done enough examination
786 786 # of edge cases to convince myself this is really
787 787 # a fact - it works for all the (admittedly
788 788 # thorough) cases in our testsuite, but I would be
789 789 # somewhat unsurprised to find a case in the wild
790 790 # where this breaks down a bit. That said, I don't
791 791 # know if it would hurt anything.
792 792 for i in pycompat.xrange(rev, 0, -1):
793 793 if store.linkrev(i) == clrev:
794 794 return i
795 795 # We failed to resolve a parent for this node, so
796 796 # we crash the changegroup construction.
797 797 raise error.Abort(
798 798 b"unable to resolve parent while packing '%s' %r"
799 799 b' for changeset %r' % (store.indexfile, rev, clrev)
800 800 )
801 801
802 802 return nullrev
803 803
804 804 if not linkparents or (store.parentrevs(rev) == (nullrev, nullrev)):
805 805 p1, p2 = nullrev, nullrev
806 806 elif len(linkparents) == 1:
807 807 (p1,) = sorted(local(p) for p in linkparents)
808 808 p2 = nullrev
809 809 else:
810 810 p1, p2 = sorted(local(p) for p in linkparents)
811 811
812 812 p1node, p2node = store.node(p1), store.node(p2)
813 813
814 814 return p1node, p2node, linknode
815 815
816 816
817 817 def deltagroup(
818 818 repo,
819 819 store,
820 820 nodes,
821 821 ischangelog,
822 822 lookup,
823 823 forcedeltaparentprev,
824 824 topic=None,
825 825 ellipses=False,
826 826 clrevtolocalrev=None,
827 827 fullclnodes=None,
828 828 precomputedellipsis=None,
829 829 sidedata_helpers=None,
830 830 ):
831 831 """Calculate deltas for a set of revisions.
832 832
833 833 Is a generator of ``revisiondelta`` instances.
834 834
835 835 If topic is not None, progress detail will be generated using this
836 836 topic name (e.g. changesets, manifests, etc).
837 837
838 838 See `storageutil.emitrevisions` for the doc on `sidedata_helpers`.
839 839 """
840 840 if not nodes:
841 841 return
842 842
843 843 cl = repo.changelog
844 844
845 845 if ischangelog:
846 846 # `hg log` shows changesets in storage order. To preserve order
847 847 # across clones, send out changesets in storage order.
848 848 nodesorder = b'storage'
849 849 elif ellipses:
850 850 nodes = _sortnodesellipsis(store, nodes, cl, lookup)
851 851 nodesorder = b'nodes'
852 852 else:
853 853 nodesorder = None
854 854
855 855 # Perform ellipses filtering and revision massaging. We do this before
856 856 # emitrevisions() because a) filtering out revisions creates less work
857 857 # for emitrevisions() b) dropping revisions would break emitrevisions()'s
858 858 # assumptions about delta choices and we would possibly send a delta
859 859 # referencing a missing base revision.
860 860 #
861 861 # Also, calling lookup() has side-effects with regards to populating
862 862 # data structures. If we don't call lookup() for each node or if we call
863 863 # lookup() after the first pass through each node, things can break -
864 864 # possibly intermittently depending on the python hash seed! For that
865 865 # reason, we store a mapping of all linknodes during the initial node
866 866 # pass rather than use lookup() on the output side.
867 867 if ellipses:
868 868 filtered = []
869 869 adjustedparents = {}
870 870 linknodes = {}
871 871
872 872 for node in nodes:
873 873 rev = store.rev(node)
874 874 linknode = lookup(node)
875 875 linkrev = cl.rev(linknode)
876 876 clrevtolocalrev[linkrev] = rev
877 877
878 878 # If linknode is in fullclnodes, it means the corresponding
879 879 # changeset was a full changeset and is being sent unaltered.
880 880 if linknode in fullclnodes:
881 881 linknodes[node] = linknode
882 882
883 883 # If the corresponding changeset wasn't in the set computed
884 884 # as relevant to us, it should be dropped outright.
885 885 elif linkrev not in precomputedellipsis:
886 886 continue
887 887
888 888 else:
889 889 # We could probably do this later and avoid the dict
890 890 # holding state. But it likely doesn't matter.
891 891 p1node, p2node, linknode = _resolvenarrowrevisioninfo(
892 892 cl,
893 893 store,
894 894 ischangelog,
895 895 rev,
896 896 linkrev,
897 897 linknode,
898 898 clrevtolocalrev,
899 899 fullclnodes,
900 900 precomputedellipsis,
901 901 )
902 902
903 903 adjustedparents[node] = (p1node, p2node)
904 904 linknodes[node] = linknode
905 905
906 906 filtered.append(node)
907 907
908 908 nodes = filtered
909 909
910 910 # We expect the first pass to be fast, so we only engage the progress
911 911 # meter for constructing the revision deltas.
912 912 progress = None
913 913 if topic is not None:
914 914 progress = repo.ui.makeprogress(
915 915 topic, unit=_(b'chunks'), total=len(nodes)
916 916 )
917 917
918 918 configtarget = repo.ui.config(b'devel', b'bundle.delta')
919 919 if configtarget not in (b'', b'p1', b'full'):
920 920 msg = _(b"""config "devel.bundle.delta" as unknown value: %s""")
921 921 repo.ui.warn(msg % configtarget)
922 922
923 923 deltamode = repository.CG_DELTAMODE_STD
924 924 if forcedeltaparentprev:
925 925 deltamode = repository.CG_DELTAMODE_PREV
926 926 elif configtarget == b'p1':
927 927 deltamode = repository.CG_DELTAMODE_P1
928 928 elif configtarget == b'full':
929 929 deltamode = repository.CG_DELTAMODE_FULL
930 930
931 931 revisions = store.emitrevisions(
932 932 nodes,
933 933 nodesorder=nodesorder,
934 934 revisiondata=True,
935 935 assumehaveparentrevisions=not ellipses,
936 936 deltamode=deltamode,
937 937 sidedata_helpers=sidedata_helpers,
938 938 )
939 939
940 940 for i, revision in enumerate(revisions):
941 941 if progress:
942 942 progress.update(i + 1)
943 943
944 944 if ellipses:
945 945 linknode = linknodes[revision.node]
946 946
947 947 if revision.node in adjustedparents:
948 948 p1node, p2node = adjustedparents[revision.node]
949 949 revision.p1node = p1node
950 950 revision.p2node = p2node
951 951 revision.flags |= repository.REVISION_FLAG_ELLIPSIS
952 952
953 953 else:
954 954 linknode = lookup(revision.node)
955 955
956 956 revision.linknode = linknode
957 957 yield revision
958 958
959 959 if progress:
960 960 progress.complete()
961 961
962 962
963 963 class cgpacker(object):
964 964 def __init__(
965 965 self,
966 966 repo,
967 967 oldmatcher,
968 968 matcher,
969 969 version,
970 970 builddeltaheader,
971 971 manifestsend,
972 972 forcedeltaparentprev=False,
973 973 bundlecaps=None,
974 974 ellipses=False,
975 975 shallow=False,
976 976 ellipsisroots=None,
977 977 fullnodes=None,
978 978 remote_sidedata=None,
979 979 ):
980 980 """Given a source repo, construct a bundler.
981 981
982 982 oldmatcher is a matcher that matches on files the client already has.
983 983 These will not be included in the changegroup.
984 984
985 985 matcher is a matcher that matches on files to include in the
986 986 changegroup. Used to facilitate sparse changegroups.
987 987
988 988 forcedeltaparentprev indicates whether delta parents must be against
989 989 the previous revision in a delta group. This should only be used for
990 990 compatibility with changegroup version 1.
991 991
992 992 builddeltaheader is a callable that constructs the header for a group
993 993 delta.
994 994
995 995 manifestsend is a chunk to send after manifests have been fully emitted.
996 996
997 997 ellipses indicates whether ellipsis serving mode is enabled.
998 998
999 999 bundlecaps is optional and can be used to specify the set of
1000 1000 capabilities which can be used to build the bundle. While bundlecaps is
1001 1001 unused in core Mercurial, extensions rely on this feature to communicate
1002 1002 capabilities to customize the changegroup packer.
1003 1003
1004 1004 shallow indicates whether shallow data might be sent. The packer may
1005 1005 need to pack file contents not introduced by the changes being packed.
1006 1006
1007 1007 fullnodes is the set of changelog nodes which should not be ellipsis
1008 1008 nodes. We store this rather than the set of nodes that should be
1009 1009 ellipsis because for very large histories we expect this to be
1010 1010 significantly smaller.
1011 1011
1012 1012 remote_sidedata is the set of sidedata categories wanted by the remote.
1013 1013 """
1014 1014 assert oldmatcher
1015 1015 assert matcher
1016 1016 self._oldmatcher = oldmatcher
1017 1017 self._matcher = matcher
1018 1018
1019 1019 self.version = version
1020 1020 self._forcedeltaparentprev = forcedeltaparentprev
1021 1021 self._builddeltaheader = builddeltaheader
1022 1022 self._manifestsend = manifestsend
1023 1023 self._ellipses = ellipses
1024 1024
1025 1025 # Set of capabilities we can use to build the bundle.
1026 1026 if bundlecaps is None:
1027 1027 bundlecaps = set()
1028 1028 self._bundlecaps = bundlecaps
1029 1029 if remote_sidedata is None:
1030 1030 remote_sidedata = set()
1031 1031 self._remote_sidedata = remote_sidedata
1032 1032 self._isshallow = shallow
1033 1033 self._fullclnodes = fullnodes
1034 1034
1035 1035 # Maps ellipsis revs to their roots at the changelog level.
1036 1036 self._precomputedellipsis = ellipsisroots
1037 1037
1038 1038 self._repo = repo
1039 1039
1040 1040 if self._repo.ui.verbose and not self._repo.ui.debugflag:
1041 1041 self._verbosenote = self._repo.ui.note
1042 1042 else:
1043 1043 self._verbosenote = lambda s: None
1044 1044
1045 1045 def generate(
1046 1046 self, commonrevs, clnodes, fastpathlinkrev, source, changelog=True
1047 1047 ):
1048 1048 """Yield a sequence of changegroup byte chunks.
1049 1049 If changelog is False, changelog data won't be added to changegroup
1050 1050 """
1051 1051
1052 1052 repo = self._repo
1053 1053 cl = repo.changelog
1054 1054
1055 1055 self._verbosenote(_(b'uncompressed size of bundle content:\n'))
1056 1056 size = 0
1057 1057
1058 1058 sidedata_helpers = None
1059 1059 if self.version == b'04':
1060 1060 remote_sidedata = self._remote_sidedata
1061 1061 if source == b'strip':
1062 1062 # We're our own remote when stripping, get the no-op helpers
1063 1063 # TODO a better approach would be for the strip bundle to
1064 1064 # correctly advertise its sidedata categories directly.
1065 1065 remote_sidedata = repo._wanted_sidedata
1066 1066 sidedata_helpers = get_sidedata_helpers(repo, remote_sidedata)
1067 1067
1068 1068 clstate, deltas = self._generatechangelog(
1069 1069 cl,
1070 1070 clnodes,
1071 1071 generate=changelog,
1072 1072 sidedata_helpers=sidedata_helpers,
1073 1073 )
1074 1074 for delta in deltas:
1075 1075 for chunk in _revisiondeltatochunks(
1076 1076 self._repo, delta, self._builddeltaheader
1077 1077 ):
1078 1078 size += len(chunk)
1079 1079 yield chunk
1080 1080
1081 1081 close = closechunk()
1082 1082 size += len(close)
1083 1083 yield closechunk()
1084 1084
1085 1085 self._verbosenote(_(b'%8.i (changelog)\n') % size)
1086 1086
1087 1087 clrevorder = clstate[b'clrevorder']
1088 1088 manifests = clstate[b'manifests']
1089 1089 changedfiles = clstate[b'changedfiles']
1090 1090
1091 1091 # We need to make sure that the linkrev in the changegroup refers to
1092 1092 # the first changeset that introduced the manifest or file revision.
1093 1093 # The fastpath is usually safer than the slowpath, because the filelogs
1094 1094 # are walked in revlog order.
1095 1095 #
1096 1096 # When taking the slowpath when the manifest revlog uses generaldelta,
1097 1097 # the manifest may be walked in the "wrong" order. Without 'clrevorder',
1098 1098 # we would get an incorrect linkrev (see fix in cc0ff93d0c0c).
1099 1099 #
1100 1100 # When taking the fastpath, we are only vulnerable to reordering
1101 1101 # of the changelog itself. The changelog never uses generaldelta and is
1102 1102 # never reordered. To handle this case, we simply take the slowpath,
1103 1103 # which already has the 'clrevorder' logic. This was also fixed in
1104 1104 # cc0ff93d0c0c.
1105 1105
1106 1106 # Treemanifests don't work correctly with fastpathlinkrev
1107 1107 # either, because we don't discover which directory nodes to
1108 1108 # send along with files. This could probably be fixed.
1109 1109 fastpathlinkrev = fastpathlinkrev and not scmutil.istreemanifest(repo)
1110 1110
1111 1111 fnodes = {} # needed file nodes
1112 1112
1113 1113 size = 0
1114 1114 it = self.generatemanifests(
1115 1115 commonrevs,
1116 1116 clrevorder,
1117 1117 fastpathlinkrev,
1118 1118 manifests,
1119 1119 fnodes,
1120 1120 source,
1121 1121 clstate[b'clrevtomanifestrev'],
1122 1122 sidedata_helpers=sidedata_helpers,
1123 1123 )
1124 1124
1125 1125 for tree, deltas in it:
1126 1126 if tree:
1127 1127 assert self.version in (b'03', b'04')
1128 1128 chunk = _fileheader(tree)
1129 1129 size += len(chunk)
1130 1130 yield chunk
1131 1131
1132 1132 for delta in deltas:
1133 1133 chunks = _revisiondeltatochunks(
1134 1134 self._repo, delta, self._builddeltaheader
1135 1135 )
1136 1136 for chunk in chunks:
1137 1137 size += len(chunk)
1138 1138 yield chunk
1139 1139
1140 1140 close = closechunk()
1141 1141 size += len(close)
1142 1142 yield close
1143 1143
1144 1144 self._verbosenote(_(b'%8.i (manifests)\n') % size)
1145 1145 yield self._manifestsend
1146 1146
1147 1147 mfdicts = None
1148 1148 if self._ellipses and self._isshallow:
1149 1149 mfdicts = [
1150 1150 (repo.manifestlog[n].read(), lr)
1151 1151 for (n, lr) in pycompat.iteritems(manifests)
1152 1152 ]
1153 1153
1154 1154 manifests.clear()
1155 1155 clrevs = {cl.rev(x) for x in clnodes}
1156 1156
1157 1157 it = self.generatefiles(
1158 1158 changedfiles,
1159 1159 commonrevs,
1160 1160 source,
1161 1161 mfdicts,
1162 1162 fastpathlinkrev,
1163 1163 fnodes,
1164 1164 clrevs,
1165 1165 sidedata_helpers=sidedata_helpers,
1166 1166 )
1167 1167
1168 1168 for path, deltas in it:
1169 1169 h = _fileheader(path)
1170 1170 size = len(h)
1171 1171 yield h
1172 1172
1173 1173 for delta in deltas:
1174 1174 chunks = _revisiondeltatochunks(
1175 1175 self._repo, delta, self._builddeltaheader
1176 1176 )
1177 1177 for chunk in chunks:
1178 1178 size += len(chunk)
1179 1179 yield chunk
1180 1180
1181 1181 close = closechunk()
1182 1182 size += len(close)
1183 1183 yield close
1184 1184
1185 1185 self._verbosenote(_(b'%8.i %s\n') % (size, path))
1186 1186
1187 1187 yield closechunk()
1188 1188
1189 1189 if clnodes:
1190 1190 repo.hook(b'outgoing', node=hex(clnodes[0]), source=source)
1191 1191
1192 1192 def _generatechangelog(
1193 1193 self, cl, nodes, generate=True, sidedata_helpers=None
1194 1194 ):
1195 1195 """Generate data for changelog chunks.
1196 1196
1197 1197 Returns a 2-tuple of a dict containing state and an iterable of
1198 1198 byte chunks. The state will not be fully populated until the
1199 1199 chunk stream has been fully consumed.
1200 1200
1201 1201 if generate is False, the state will be fully populated and no chunk
1202 1202 stream will be yielded
1203 1203
1204 1204 See `storageutil.emitrevisions` for the doc on `sidedata_helpers`.
1205 1205 """
1206 1206 clrevorder = {}
1207 1207 manifests = {}
1208 1208 mfl = self._repo.manifestlog
1209 1209 changedfiles = set()
1210 1210 clrevtomanifestrev = {}
1211 1211
1212 1212 state = {
1213 1213 b'clrevorder': clrevorder,
1214 1214 b'manifests': manifests,
1215 1215 b'changedfiles': changedfiles,
1216 1216 b'clrevtomanifestrev': clrevtomanifestrev,
1217 1217 }
1218 1218
1219 1219 if not (generate or self._ellipses):
1220 1220 # sort the nodes in storage order
1221 1221 nodes = sorted(nodes, key=cl.rev)
1222 1222 for node in nodes:
1223 1223 c = cl.changelogrevision(node)
1224 1224 clrevorder[node] = len(clrevorder)
1225 1225 # record the first changeset introducing this manifest version
1226 1226 manifests.setdefault(c.manifest, node)
1227 1227 # Record a complete list of potentially-changed files in
1228 1228 # this manifest.
1229 1229 changedfiles.update(c.files)
1230 1230
1231 1231 return state, ()
1232 1232
1233 1233 # Callback for the changelog, used to collect changed files and
1234 1234 # manifest nodes.
1235 1235 # Returns the linkrev node (identity in the changelog case).
1236 1236 def lookupcl(x):
1237 1237 c = cl.changelogrevision(x)
1238 1238 clrevorder[x] = len(clrevorder)
1239 1239
1240 1240 if self._ellipses:
1241 1241 # Only update manifests if x is going to be sent. Otherwise we
1242 1242 # end up with bogus linkrevs specified for manifests and
1243 1243 # we skip some manifest nodes that we should otherwise
1244 1244 # have sent.
1245 1245 if (
1246 1246 x in self._fullclnodes
1247 1247 or cl.rev(x) in self._precomputedellipsis
1248 1248 ):
1249 1249
1250 1250 manifestnode = c.manifest
1251 1251 # Record the first changeset introducing this manifest
1252 1252 # version.
1253 1253 manifests.setdefault(manifestnode, x)
1254 1254 # Set this narrow-specific dict so we have the lowest
1255 1255 # manifest revnum to look up for this cl revnum. (Part of
1256 1256 # mapping changelog ellipsis parents to manifest ellipsis
1257 1257 # parents)
1258 1258 clrevtomanifestrev.setdefault(
1259 1259 cl.rev(x), mfl.rev(manifestnode)
1260 1260 )
1261 1261 # We can't trust the changed files list in the changeset if the
1262 1262 # client requested a shallow clone.
1263 1263 if self._isshallow:
1264 1264 changedfiles.update(mfl[c.manifest].read().keys())
1265 1265 else:
1266 1266 changedfiles.update(c.files)
1267 1267 else:
1268 1268 # record the first changeset introducing this manifest version
1269 1269 manifests.setdefault(c.manifest, x)
1270 1270 # Record a complete list of potentially-changed files in
1271 1271 # this manifest.
1272 1272 changedfiles.update(c.files)
1273 1273
1274 1274 return x
1275 1275
1276 1276 gen = deltagroup(
1277 1277 self._repo,
1278 1278 cl,
1279 1279 nodes,
1280 1280 True,
1281 1281 lookupcl,
1282 1282 self._forcedeltaparentprev,
1283 1283 ellipses=self._ellipses,
1284 1284 topic=_(b'changesets'),
1285 1285 clrevtolocalrev={},
1286 1286 fullclnodes=self._fullclnodes,
1287 1287 precomputedellipsis=self._precomputedellipsis,
1288 1288 sidedata_helpers=sidedata_helpers,
1289 1289 )
1290 1290
1291 1291 return state, gen
1292 1292
1293 1293 def generatemanifests(
1294 1294 self,
1295 1295 commonrevs,
1296 1296 clrevorder,
1297 1297 fastpathlinkrev,
1298 1298 manifests,
1299 1299 fnodes,
1300 1300 source,
1301 1301 clrevtolocalrev,
1302 1302 sidedata_helpers=None,
1303 1303 ):
1304 1304 """Returns an iterator of changegroup chunks containing manifests.
1305 1305
1306 1306 `source` is unused here, but is used by extensions like remotefilelog to
1307 1307 change what is sent based in pulls vs pushes, etc.
1308 1308
1309 1309 See `storageutil.emitrevisions` for the doc on `sidedata_helpers`.
1310 1310 """
1311 1311 repo = self._repo
1312 1312 mfl = repo.manifestlog
1313 1313 tmfnodes = {b'': manifests}
1314 1314
1315 1315 # Callback for the manifest, used to collect linkrevs for filelog
1316 1316 # revisions.
1317 1317 # Returns the linkrev node (collected in lookupcl).
1318 1318 def makelookupmflinknode(tree, nodes):
1319 1319 if fastpathlinkrev:
1320 1320 assert not tree
1321 1321
1322 1322 # pytype: disable=unsupported-operands
1323 1323 return manifests.__getitem__
1324 1324 # pytype: enable=unsupported-operands
1325 1325
1326 1326 def lookupmflinknode(x):
1327 1327 """Callback for looking up the linknode for manifests.
1328 1328
1329 1329 Returns the linkrev node for the specified manifest.
1330 1330
1331 1331 SIDE EFFECT:
1332 1332
1333 1333 1) fclnodes gets populated with the list of relevant
1334 1334 file nodes if we're not using fastpathlinkrev
1335 1335 2) When treemanifests are in use, collects treemanifest nodes
1336 1336 to send
1337 1337
1338 1338 Note that this means manifests must be completely sent to
1339 1339 the client before you can trust the list of files and
1340 1340 treemanifests to send.
1341 1341 """
1342 1342 clnode = nodes[x]
1343 1343 mdata = mfl.get(tree, x).readfast(shallow=True)
1344 1344 for p, n, fl in mdata.iterentries():
1345 1345 if fl == b't': # subdirectory manifest
1346 1346 subtree = tree + p + b'/'
1347 1347 tmfclnodes = tmfnodes.setdefault(subtree, {})
1348 1348 tmfclnode = tmfclnodes.setdefault(n, clnode)
1349 1349 if clrevorder[clnode] < clrevorder[tmfclnode]:
1350 1350 tmfclnodes[n] = clnode
1351 1351 else:
1352 1352 f = tree + p
1353 1353 fclnodes = fnodes.setdefault(f, {})
1354 1354 fclnode = fclnodes.setdefault(n, clnode)
1355 1355 if clrevorder[clnode] < clrevorder[fclnode]:
1356 1356 fclnodes[n] = clnode
1357 1357 return clnode
1358 1358
1359 1359 return lookupmflinknode
1360 1360
1361 1361 while tmfnodes:
1362 1362 tree, nodes = tmfnodes.popitem()
1363 1363
1364 1364 should_visit = self._matcher.visitdir(tree[:-1])
1365 1365 if tree and not should_visit:
1366 1366 continue
1367 1367
1368 1368 store = mfl.getstorage(tree)
1369 1369
1370 1370 if not should_visit:
1371 1371 # No nodes to send because this directory is out of
1372 1372 # the client's view of the repository (probably
1373 1373 # because of narrow clones). Do this even for the root
1374 1374 # directory (tree=='')
1375 1375 prunednodes = []
1376 1376 else:
1377 1377 # Avoid sending any manifest nodes we can prove the
1378 1378 # client already has by checking linkrevs. See the
1379 1379 # related comment in generatefiles().
1380 1380 prunednodes = self._prunemanifests(store, nodes, commonrevs)
1381 1381
1382 1382 if tree and not prunednodes:
1383 1383 continue
1384 1384
1385 1385 lookupfn = makelookupmflinknode(tree, nodes)
1386 1386
1387 1387 deltas = deltagroup(
1388 1388 self._repo,
1389 1389 store,
1390 1390 prunednodes,
1391 1391 False,
1392 1392 lookupfn,
1393 1393 self._forcedeltaparentprev,
1394 1394 ellipses=self._ellipses,
1395 1395 topic=_(b'manifests'),
1396 1396 clrevtolocalrev=clrevtolocalrev,
1397 1397 fullclnodes=self._fullclnodes,
1398 1398 precomputedellipsis=self._precomputedellipsis,
1399 1399 sidedata_helpers=sidedata_helpers,
1400 1400 )
1401 1401
1402 1402 if not self._oldmatcher.visitdir(store.tree[:-1]):
1403 1403 yield tree, deltas
1404 1404 else:
1405 1405 # 'deltas' is a generator and we need to consume it even if
1406 1406 # we are not going to send it because a side-effect is that
1407 1407 # it updates tmdnodes (via lookupfn)
1408 1408 for d in deltas:
1409 1409 pass
1410 1410 if not tree:
1411 1411 yield tree, []
1412 1412
1413 1413 def _prunemanifests(self, store, nodes, commonrevs):
1414 1414 if not self._ellipses:
1415 1415 # In non-ellipses case and large repositories, it is better to
1416 1416 # prevent calling of store.rev and store.linkrev on a lot of
1417 1417 # nodes as compared to sending some extra data
1418 1418 return nodes.copy()
1419 1419 # This is split out as a separate method to allow filtering
1420 1420 # commonrevs in extension code.
1421 1421 #
1422 1422 # TODO(augie): this shouldn't be required, instead we should
1423 1423 # make filtering of revisions to send delegated to the store
1424 1424 # layer.
1425 1425 frev, flr = store.rev, store.linkrev
1426 1426 return [n for n in nodes if flr(frev(n)) not in commonrevs]
1427 1427
1428 1428 # The 'source' parameter is useful for extensions
1429 1429 def generatefiles(
1430 1430 self,
1431 1431 changedfiles,
1432 1432 commonrevs,
1433 1433 source,
1434 1434 mfdicts,
1435 1435 fastpathlinkrev,
1436 1436 fnodes,
1437 1437 clrevs,
1438 1438 sidedata_helpers=None,
1439 1439 ):
1440 1440 changedfiles = [
1441 1441 f
1442 1442 for f in changedfiles
1443 1443 if self._matcher(f) and not self._oldmatcher(f)
1444 1444 ]
1445 1445
1446 1446 if not fastpathlinkrev:
1447 1447
1448 1448 def normallinknodes(unused, fname):
1449 1449 return fnodes.get(fname, {})
1450 1450
1451 1451 else:
1452 1452 cln = self._repo.changelog.node
1453 1453
1454 1454 def normallinknodes(store, fname):
1455 1455 flinkrev = store.linkrev
1456 1456 fnode = store.node
1457 1457 revs = ((r, flinkrev(r)) for r in store)
1458 1458 return {fnode(r): cln(lr) for r, lr in revs if lr in clrevs}
1459 1459
1460 1460 clrevtolocalrev = {}
1461 1461
1462 1462 if self._isshallow:
1463 1463 # In a shallow clone, the linknodes callback needs to also include
1464 1464 # those file nodes that are in the manifests we sent but weren't
1465 1465 # introduced by those manifests.
1466 1466 commonctxs = [self._repo[c] for c in commonrevs]
1467 1467 clrev = self._repo.changelog.rev
1468 1468
1469 1469 def linknodes(flog, fname):
1470 1470 for c in commonctxs:
1471 1471 try:
1472 1472 fnode = c.filenode(fname)
1473 1473 clrevtolocalrev[c.rev()] = flog.rev(fnode)
1474 1474 except error.ManifestLookupError:
1475 1475 pass
1476 1476 links = normallinknodes(flog, fname)
1477 1477 if len(links) != len(mfdicts):
1478 1478 for mf, lr in mfdicts:
1479 1479 fnode = mf.get(fname, None)
1480 1480 if fnode in links:
1481 1481 links[fnode] = min(links[fnode], lr, key=clrev)
1482 1482 elif fnode:
1483 1483 links[fnode] = lr
1484 1484 return links
1485 1485
1486 1486 else:
1487 1487 linknodes = normallinknodes
1488 1488
1489 1489 repo = self._repo
1490 1490 progress = repo.ui.makeprogress(
1491 1491 _(b'files'), unit=_(b'files'), total=len(changedfiles)
1492 1492 )
1493 1493 for i, fname in enumerate(sorted(changedfiles)):
1494 1494 filerevlog = repo.file(fname)
1495 1495 if not filerevlog:
1496 1496 raise error.Abort(
1497 1497 _(b"empty or missing file data for %s") % fname
1498 1498 )
1499 1499
1500 1500 clrevtolocalrev.clear()
1501 1501
1502 1502 linkrevnodes = linknodes(filerevlog, fname)
1503 1503 # Lookup for filenodes, we collected the linkrev nodes above in the
1504 1504 # fastpath case and with lookupmf in the slowpath case.
1505 1505 def lookupfilelog(x):
1506 1506 return linkrevnodes[x]
1507 1507
1508 1508 frev, flr = filerevlog.rev, filerevlog.linkrev
1509 1509 # Skip sending any filenode we know the client already
1510 1510 # has. This avoids over-sending files relatively
1511 1511 # inexpensively, so it's not a problem if we under-filter
1512 1512 # here.
1513 1513 filenodes = [
1514 1514 n for n in linkrevnodes if flr(frev(n)) not in commonrevs
1515 1515 ]
1516 1516
1517 1517 if not filenodes:
1518 1518 continue
1519 1519
1520 1520 progress.update(i + 1, item=fname)
1521 1521
1522 1522 deltas = deltagroup(
1523 1523 self._repo,
1524 1524 filerevlog,
1525 1525 filenodes,
1526 1526 False,
1527 1527 lookupfilelog,
1528 1528 self._forcedeltaparentprev,
1529 1529 ellipses=self._ellipses,
1530 1530 clrevtolocalrev=clrevtolocalrev,
1531 1531 fullclnodes=self._fullclnodes,
1532 1532 precomputedellipsis=self._precomputedellipsis,
1533 1533 sidedata_helpers=sidedata_helpers,
1534 1534 )
1535 1535
1536 1536 yield fname, deltas
1537 1537
1538 1538 progress.complete()
1539 1539
1540 1540
1541 1541 def _makecg1packer(
1542 1542 repo,
1543 1543 oldmatcher,
1544 1544 matcher,
1545 1545 bundlecaps,
1546 1546 ellipses=False,
1547 1547 shallow=False,
1548 1548 ellipsisroots=None,
1549 1549 fullnodes=None,
1550 1550 remote_sidedata=None,
1551 1551 ):
1552 1552 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
1553 1553 d.node, d.p1node, d.p2node, d.linknode
1554 1554 )
1555 1555
1556 1556 return cgpacker(
1557 1557 repo,
1558 1558 oldmatcher,
1559 1559 matcher,
1560 1560 b'01',
1561 1561 builddeltaheader=builddeltaheader,
1562 1562 manifestsend=b'',
1563 1563 forcedeltaparentprev=True,
1564 1564 bundlecaps=bundlecaps,
1565 1565 ellipses=ellipses,
1566 1566 shallow=shallow,
1567 1567 ellipsisroots=ellipsisroots,
1568 1568 fullnodes=fullnodes,
1569 1569 )
1570 1570
1571 1571
1572 1572 def _makecg2packer(
1573 1573 repo,
1574 1574 oldmatcher,
1575 1575 matcher,
1576 1576 bundlecaps,
1577 1577 ellipses=False,
1578 1578 shallow=False,
1579 1579 ellipsisroots=None,
1580 1580 fullnodes=None,
1581 1581 remote_sidedata=None,
1582 1582 ):
1583 1583 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack(
1584 1584 d.node, d.p1node, d.p2node, d.basenode, d.linknode
1585 1585 )
1586 1586
1587 1587 return cgpacker(
1588 1588 repo,
1589 1589 oldmatcher,
1590 1590 matcher,
1591 1591 b'02',
1592 1592 builddeltaheader=builddeltaheader,
1593 1593 manifestsend=b'',
1594 1594 bundlecaps=bundlecaps,
1595 1595 ellipses=ellipses,
1596 1596 shallow=shallow,
1597 1597 ellipsisroots=ellipsisroots,
1598 1598 fullnodes=fullnodes,
1599 1599 )
1600 1600
1601 1601
1602 1602 def _makecg3packer(
1603 1603 repo,
1604 1604 oldmatcher,
1605 1605 matcher,
1606 1606 bundlecaps,
1607 1607 ellipses=False,
1608 1608 shallow=False,
1609 1609 ellipsisroots=None,
1610 1610 fullnodes=None,
1611 1611 remote_sidedata=None,
1612 1612 ):
1613 1613 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1614 1614 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags
1615 1615 )
1616 1616
1617 1617 return cgpacker(
1618 1618 repo,
1619 1619 oldmatcher,
1620 1620 matcher,
1621 1621 b'03',
1622 1622 builddeltaheader=builddeltaheader,
1623 1623 manifestsend=closechunk(),
1624 1624 bundlecaps=bundlecaps,
1625 1625 ellipses=ellipses,
1626 1626 shallow=shallow,
1627 1627 ellipsisroots=ellipsisroots,
1628 1628 fullnodes=fullnodes,
1629 1629 )
1630 1630
1631 1631
1632 1632 def _makecg4packer(
1633 1633 repo,
1634 1634 oldmatcher,
1635 1635 matcher,
1636 1636 bundlecaps,
1637 1637 ellipses=False,
1638 1638 shallow=False,
1639 1639 ellipsisroots=None,
1640 1640 fullnodes=None,
1641 1641 remote_sidedata=None,
1642 1642 ):
1643 1643 # Same header func as cg3. Sidedata is in a separate chunk from the delta to
1644 1644 # differenciate "raw delta" and sidedata.
1645 1645 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1646 1646 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags
1647 1647 )
1648 1648
1649 1649 return cgpacker(
1650 1650 repo,
1651 1651 oldmatcher,
1652 1652 matcher,
1653 1653 b'04',
1654 1654 builddeltaheader=builddeltaheader,
1655 1655 manifestsend=closechunk(),
1656 1656 bundlecaps=bundlecaps,
1657 1657 ellipses=ellipses,
1658 1658 shallow=shallow,
1659 1659 ellipsisroots=ellipsisroots,
1660 1660 fullnodes=fullnodes,
1661 1661 remote_sidedata=remote_sidedata,
1662 1662 )
1663 1663
1664 1664
1665 1665 _packermap = {
1666 1666 b'01': (_makecg1packer, cg1unpacker),
1667 1667 # cg2 adds support for exchanging generaldelta
1668 1668 b'02': (_makecg2packer, cg2unpacker),
1669 1669 # cg3 adds support for exchanging revlog flags and treemanifests
1670 1670 b'03': (_makecg3packer, cg3unpacker),
1671 1671 # ch4 adds support for exchanging sidedata
1672 1672 b'04': (_makecg4packer, cg4unpacker),
1673 1673 }
1674 1674
1675 1675
1676 1676 def allsupportedversions(repo):
1677 1677 versions = set(_packermap.keys())
1678 1678 needv03 = False
1679 1679 if (
1680 1680 repo.ui.configbool(b'experimental', b'changegroup3')
1681 1681 or repo.ui.configbool(b'experimental', b'treemanifest')
1682 1682 or scmutil.istreemanifest(repo)
1683 1683 ):
1684 1684 # we keep version 03 because we need to to exchange treemanifest data
1685 1685 #
1686 1686 # we also keep vresion 01 and 02, because it is possible for repo to
1687 1687 # contains both normal and tree manifest at the same time. so using
1688 1688 # older version to pull data is viable
1689 1689 #
1690 1690 # (or even to push subset of history)
1691 1691 needv03 = True
1692 has_revlogv2 = requirements.REVLOGV2_REQUIREMENT in repo.requirements
1693 if not has_revlogv2:
1694 versions.discard(b'04')
1695 1692 if not needv03:
1696 1693 versions.discard(b'03')
1694 want_v4 = (
1695 repo.ui.configbool(b'experimental', b'changegroup4')
1696 or requirements.REVLOGV2_REQUIREMENT in repo.requirements
1697 )
1698 if not want_v4:
1699 versions.discard(b'04')
1697 1700 return versions
1698 1701
1699 1702
1700 1703 # Changegroup versions that can be applied to the repo
1701 1704 def supportedincomingversions(repo):
1702 1705 return allsupportedversions(repo)
1703 1706
1704 1707
1705 1708 # Changegroup versions that can be created from the repo
1706 1709 def supportedoutgoingversions(repo):
1707 1710 versions = allsupportedversions(repo)
1708 1711 if scmutil.istreemanifest(repo):
1709 1712 # Versions 01 and 02 support only flat manifests and it's just too
1710 1713 # expensive to convert between the flat manifest and tree manifest on
1711 1714 # the fly. Since tree manifests are hashed differently, all of history
1712 1715 # would have to be converted. Instead, we simply don't even pretend to
1713 1716 # support versions 01 and 02.
1714 1717 versions.discard(b'01')
1715 1718 versions.discard(b'02')
1716 1719 if requirements.NARROW_REQUIREMENT in repo.requirements:
1717 1720 # Versions 01 and 02 don't support revlog flags, and we need to
1718 1721 # support that for stripping and unbundling to work.
1719 1722 versions.discard(b'01')
1720 1723 versions.discard(b'02')
1721 1724 if LFS_REQUIREMENT in repo.requirements:
1722 1725 # Versions 01 and 02 don't support revlog flags, and we need to
1723 1726 # mark LFS entries with REVIDX_EXTSTORED.
1724 1727 versions.discard(b'01')
1725 1728 versions.discard(b'02')
1726 1729
1727 1730 return versions
1728 1731
1729 1732
1730 1733 def localversion(repo):
1731 1734 # Finds the best version to use for bundles that are meant to be used
1732 1735 # locally, such as those from strip and shelve, and temporary bundles.
1733 1736 return max(supportedoutgoingversions(repo))
1734 1737
1735 1738
1736 1739 def safeversion(repo):
1737 1740 # Finds the smallest version that it's safe to assume clients of the repo
1738 1741 # will support. For example, all hg versions that support generaldelta also
1739 1742 # support changegroup 02.
1740 1743 versions = supportedoutgoingversions(repo)
1741 1744 if requirements.GENERALDELTA_REQUIREMENT in repo.requirements:
1742 1745 versions.discard(b'01')
1743 1746 assert versions
1744 1747 return min(versions)
1745 1748
1746 1749
1747 1750 def getbundler(
1748 1751 version,
1749 1752 repo,
1750 1753 bundlecaps=None,
1751 1754 oldmatcher=None,
1752 1755 matcher=None,
1753 1756 ellipses=False,
1754 1757 shallow=False,
1755 1758 ellipsisroots=None,
1756 1759 fullnodes=None,
1757 1760 remote_sidedata=None,
1758 1761 ):
1759 1762 assert version in supportedoutgoingversions(repo)
1760 1763
1761 1764 if matcher is None:
1762 1765 matcher = matchmod.always()
1763 1766 if oldmatcher is None:
1764 1767 oldmatcher = matchmod.never()
1765 1768
1766 1769 if version == b'01' and not matcher.always():
1767 1770 raise error.ProgrammingError(
1768 1771 b'version 01 changegroups do not support sparse file matchers'
1769 1772 )
1770 1773
1771 1774 if ellipses and version in (b'01', b'02'):
1772 1775 raise error.Abort(
1773 1776 _(
1774 1777 b'ellipsis nodes require at least cg3 on client and server, '
1775 1778 b'but negotiated version %s'
1776 1779 )
1777 1780 % version
1778 1781 )
1779 1782
1780 1783 # Requested files could include files not in the local store. So
1781 1784 # filter those out.
1782 1785 matcher = repo.narrowmatch(matcher)
1783 1786
1784 1787 fn = _packermap[version][0]
1785 1788 return fn(
1786 1789 repo,
1787 1790 oldmatcher,
1788 1791 matcher,
1789 1792 bundlecaps,
1790 1793 ellipses=ellipses,
1791 1794 shallow=shallow,
1792 1795 ellipsisroots=ellipsisroots,
1793 1796 fullnodes=fullnodes,
1794 1797 remote_sidedata=remote_sidedata,
1795 1798 )
1796 1799
1797 1800
1798 1801 def getunbundler(version, fh, alg, extras=None):
1799 1802 return _packermap[version][1](fh, alg, extras=extras)
1800 1803
1801 1804
1802 1805 def _changegroupinfo(repo, nodes, source):
1803 1806 if repo.ui.verbose or source == b'bundle':
1804 1807 repo.ui.status(_(b"%d changesets found\n") % len(nodes))
1805 1808 if repo.ui.debugflag:
1806 1809 repo.ui.debug(b"list of changesets:\n")
1807 1810 for node in nodes:
1808 1811 repo.ui.debug(b"%s\n" % hex(node))
1809 1812
1810 1813
1811 1814 def makechangegroup(
1812 1815 repo, outgoing, version, source, fastpath=False, bundlecaps=None
1813 1816 ):
1814 1817 cgstream = makestream(
1815 1818 repo,
1816 1819 outgoing,
1817 1820 version,
1818 1821 source,
1819 1822 fastpath=fastpath,
1820 1823 bundlecaps=bundlecaps,
1821 1824 )
1822 1825 return getunbundler(
1823 1826 version,
1824 1827 util.chunkbuffer(cgstream),
1825 1828 None,
1826 1829 {b'clcount': len(outgoing.missing)},
1827 1830 )
1828 1831
1829 1832
1830 1833 def makestream(
1831 1834 repo,
1832 1835 outgoing,
1833 1836 version,
1834 1837 source,
1835 1838 fastpath=False,
1836 1839 bundlecaps=None,
1837 1840 matcher=None,
1838 1841 remote_sidedata=None,
1839 1842 ):
1840 1843 bundler = getbundler(
1841 1844 version,
1842 1845 repo,
1843 1846 bundlecaps=bundlecaps,
1844 1847 matcher=matcher,
1845 1848 remote_sidedata=remote_sidedata,
1846 1849 )
1847 1850
1848 1851 repo = repo.unfiltered()
1849 1852 commonrevs = outgoing.common
1850 1853 csets = outgoing.missing
1851 1854 heads = outgoing.ancestorsof
1852 1855 # We go through the fast path if we get told to, or if all (unfiltered
1853 1856 # heads have been requested (since we then know there all linkrevs will
1854 1857 # be pulled by the client).
1855 1858 heads.sort()
1856 1859 fastpathlinkrev = fastpath or (
1857 1860 repo.filtername is None and heads == sorted(repo.heads())
1858 1861 )
1859 1862
1860 1863 repo.hook(b'preoutgoing', throw=True, source=source)
1861 1864 _changegroupinfo(repo, csets, source)
1862 1865 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
1863 1866
1864 1867
1865 1868 def _addchangegroupfiles(
1866 1869 repo,
1867 1870 source,
1868 1871 revmap,
1869 1872 trp,
1870 1873 expectedfiles,
1871 1874 needfiles,
1872 1875 addrevisioncb=None,
1873 1876 ):
1874 1877 revisions = 0
1875 1878 files = 0
1876 1879 progress = repo.ui.makeprogress(
1877 1880 _(b'files'), unit=_(b'files'), total=expectedfiles
1878 1881 )
1879 1882 for chunkdata in iter(source.filelogheader, {}):
1880 1883 files += 1
1881 1884 f = chunkdata[b"filename"]
1882 1885 repo.ui.debug(b"adding %s revisions\n" % f)
1883 1886 progress.increment()
1884 1887 fl = repo.file(f)
1885 1888 o = len(fl)
1886 1889 try:
1887 1890 deltas = source.deltaiter()
1888 1891 added = fl.addgroup(
1889 1892 deltas,
1890 1893 revmap,
1891 1894 trp,
1892 1895 addrevisioncb=addrevisioncb,
1893 1896 )
1894 1897 if not added:
1895 1898 raise error.Abort(_(b"received file revlog group is empty"))
1896 1899 except error.CensoredBaseError as e:
1897 1900 raise error.Abort(_(b"received delta base is censored: %s") % e)
1898 1901 revisions += len(fl) - o
1899 1902 if f in needfiles:
1900 1903 needs = needfiles[f]
1901 1904 for new in pycompat.xrange(o, len(fl)):
1902 1905 n = fl.node(new)
1903 1906 if n in needs:
1904 1907 needs.remove(n)
1905 1908 else:
1906 1909 raise error.Abort(_(b"received spurious file revlog entry"))
1907 1910 if not needs:
1908 1911 del needfiles[f]
1909 1912 progress.complete()
1910 1913
1911 1914 for f, needs in pycompat.iteritems(needfiles):
1912 1915 fl = repo.file(f)
1913 1916 for n in needs:
1914 1917 try:
1915 1918 fl.rev(n)
1916 1919 except error.LookupError:
1917 1920 raise error.Abort(
1918 1921 _(b'missing file data for %s:%s - run hg verify')
1919 1922 % (f, hex(n))
1920 1923 )
1921 1924
1922 1925 return revisions, files
1923 1926
1924 1927
1925 1928 def get_sidedata_helpers(repo, remote_sd_categories, pull=False):
1926 1929 # Computers for computing sidedata on-the-fly
1927 1930 sd_computers = collections.defaultdict(list)
1928 1931 # Computers for categories to remove from sidedata
1929 1932 sd_removers = collections.defaultdict(list)
1930 1933
1931 1934 to_generate = remote_sd_categories - repo._wanted_sidedata
1932 1935 to_remove = repo._wanted_sidedata - remote_sd_categories
1933 1936 if pull:
1934 1937 to_generate, to_remove = to_remove, to_generate
1935 1938
1936 1939 for revlog_kind, computers in repo._sidedata_computers.items():
1937 1940 for category, computer in computers.items():
1938 1941 if category in to_generate:
1939 1942 sd_computers[revlog_kind].append(computer)
1940 1943 if category in to_remove:
1941 1944 sd_removers[revlog_kind].append(computer)
1942 1945
1943 1946 sidedata_helpers = (repo, sd_computers, sd_removers)
1944 1947 return sidedata_helpers
@@ -1,2686 +1,2691 b''
1 1 # configitems.py - centralized declaration of configuration option
2 2 #
3 3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import functools
11 11 import re
12 12
13 13 from . import (
14 14 encoding,
15 15 error,
16 16 )
17 17
18 18
19 19 def loadconfigtable(ui, extname, configtable):
20 20 """update config item known to the ui with the extension ones"""
21 21 for section, items in sorted(configtable.items()):
22 22 knownitems = ui._knownconfig.setdefault(section, itemregister())
23 23 knownkeys = set(knownitems)
24 24 newkeys = set(items)
25 25 for key in sorted(knownkeys & newkeys):
26 26 msg = b"extension '%s' overwrite config item '%s.%s'"
27 27 msg %= (extname, section, key)
28 28 ui.develwarn(msg, config=b'warn-config')
29 29
30 30 knownitems.update(items)
31 31
32 32
33 33 class configitem(object):
34 34 """represent a known config item
35 35
36 36 :section: the official config section where to find this item,
37 37 :name: the official name within the section,
38 38 :default: default value for this item,
39 39 :alias: optional list of tuples as alternatives,
40 40 :generic: this is a generic definition, match name using regular expression.
41 41 """
42 42
43 43 def __init__(
44 44 self,
45 45 section,
46 46 name,
47 47 default=None,
48 48 alias=(),
49 49 generic=False,
50 50 priority=0,
51 51 experimental=False,
52 52 ):
53 53 self.section = section
54 54 self.name = name
55 55 self.default = default
56 56 self.alias = list(alias)
57 57 self.generic = generic
58 58 self.priority = priority
59 59 self.experimental = experimental
60 60 self._re = None
61 61 if generic:
62 62 self._re = re.compile(self.name)
63 63
64 64
65 65 class itemregister(dict):
66 66 """A specialized dictionary that can handle wild-card selection"""
67 67
68 68 def __init__(self):
69 69 super(itemregister, self).__init__()
70 70 self._generics = set()
71 71
72 72 def update(self, other):
73 73 super(itemregister, self).update(other)
74 74 self._generics.update(other._generics)
75 75
76 76 def __setitem__(self, key, item):
77 77 super(itemregister, self).__setitem__(key, item)
78 78 if item.generic:
79 79 self._generics.add(item)
80 80
81 81 def get(self, key):
82 82 baseitem = super(itemregister, self).get(key)
83 83 if baseitem is not None and not baseitem.generic:
84 84 return baseitem
85 85
86 86 # search for a matching generic item
87 87 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
88 88 for item in generics:
89 89 # we use 'match' instead of 'search' to make the matching simpler
90 90 # for people unfamiliar with regular expression. Having the match
91 91 # rooted to the start of the string will produce less surprising
92 92 # result for user writing simple regex for sub-attribute.
93 93 #
94 94 # For example using "color\..*" match produces an unsurprising
95 95 # result, while using search could suddenly match apparently
96 96 # unrelated configuration that happens to contains "color."
97 97 # anywhere. This is a tradeoff where we favor requiring ".*" on
98 98 # some match to avoid the need to prefix most pattern with "^".
99 99 # The "^" seems more error prone.
100 100 if item._re.match(key):
101 101 return item
102 102
103 103 return None
104 104
105 105
106 106 coreitems = {}
107 107
108 108
109 109 def _register(configtable, *args, **kwargs):
110 110 item = configitem(*args, **kwargs)
111 111 section = configtable.setdefault(item.section, itemregister())
112 112 if item.name in section:
113 113 msg = b"duplicated config item registration for '%s.%s'"
114 114 raise error.ProgrammingError(msg % (item.section, item.name))
115 115 section[item.name] = item
116 116
117 117
118 118 # special value for case where the default is derived from other values
119 119 dynamicdefault = object()
120 120
121 121 # Registering actual config items
122 122
123 123
124 124 def getitemregister(configtable):
125 125 f = functools.partial(_register, configtable)
126 126 # export pseudo enum as configitem.*
127 127 f.dynamicdefault = dynamicdefault
128 128 return f
129 129
130 130
131 131 coreconfigitem = getitemregister(coreitems)
132 132
133 133
134 134 def _registerdiffopts(section, configprefix=b''):
135 135 coreconfigitem(
136 136 section,
137 137 configprefix + b'nodates',
138 138 default=False,
139 139 )
140 140 coreconfigitem(
141 141 section,
142 142 configprefix + b'showfunc',
143 143 default=False,
144 144 )
145 145 coreconfigitem(
146 146 section,
147 147 configprefix + b'unified',
148 148 default=None,
149 149 )
150 150 coreconfigitem(
151 151 section,
152 152 configprefix + b'git',
153 153 default=False,
154 154 )
155 155 coreconfigitem(
156 156 section,
157 157 configprefix + b'ignorews',
158 158 default=False,
159 159 )
160 160 coreconfigitem(
161 161 section,
162 162 configprefix + b'ignorewsamount',
163 163 default=False,
164 164 )
165 165 coreconfigitem(
166 166 section,
167 167 configprefix + b'ignoreblanklines',
168 168 default=False,
169 169 )
170 170 coreconfigitem(
171 171 section,
172 172 configprefix + b'ignorewseol',
173 173 default=False,
174 174 )
175 175 coreconfigitem(
176 176 section,
177 177 configprefix + b'nobinary',
178 178 default=False,
179 179 )
180 180 coreconfigitem(
181 181 section,
182 182 configprefix + b'noprefix',
183 183 default=False,
184 184 )
185 185 coreconfigitem(
186 186 section,
187 187 configprefix + b'word-diff',
188 188 default=False,
189 189 )
190 190
191 191
192 192 coreconfigitem(
193 193 b'alias',
194 194 b'.*',
195 195 default=dynamicdefault,
196 196 generic=True,
197 197 )
198 198 coreconfigitem(
199 199 b'auth',
200 200 b'cookiefile',
201 201 default=None,
202 202 )
203 203 _registerdiffopts(section=b'annotate')
204 204 # bookmarks.pushing: internal hack for discovery
205 205 coreconfigitem(
206 206 b'bookmarks',
207 207 b'pushing',
208 208 default=list,
209 209 )
210 210 # bundle.mainreporoot: internal hack for bundlerepo
211 211 coreconfigitem(
212 212 b'bundle',
213 213 b'mainreporoot',
214 214 default=b'',
215 215 )
216 216 coreconfigitem(
217 217 b'censor',
218 218 b'policy',
219 219 default=b'abort',
220 220 experimental=True,
221 221 )
222 222 coreconfigitem(
223 223 b'chgserver',
224 224 b'idletimeout',
225 225 default=3600,
226 226 )
227 227 coreconfigitem(
228 228 b'chgserver',
229 229 b'skiphash',
230 230 default=False,
231 231 )
232 232 coreconfigitem(
233 233 b'cmdserver',
234 234 b'log',
235 235 default=None,
236 236 )
237 237 coreconfigitem(
238 238 b'cmdserver',
239 239 b'max-log-files',
240 240 default=7,
241 241 )
242 242 coreconfigitem(
243 243 b'cmdserver',
244 244 b'max-log-size',
245 245 default=b'1 MB',
246 246 )
247 247 coreconfigitem(
248 248 b'cmdserver',
249 249 b'max-repo-cache',
250 250 default=0,
251 251 experimental=True,
252 252 )
253 253 coreconfigitem(
254 254 b'cmdserver',
255 255 b'message-encodings',
256 256 default=list,
257 257 )
258 258 coreconfigitem(
259 259 b'cmdserver',
260 260 b'track-log',
261 261 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
262 262 )
263 263 coreconfigitem(
264 264 b'cmdserver',
265 265 b'shutdown-on-interrupt',
266 266 default=True,
267 267 )
268 268 coreconfigitem(
269 269 b'color',
270 270 b'.*',
271 271 default=None,
272 272 generic=True,
273 273 )
274 274 coreconfigitem(
275 275 b'color',
276 276 b'mode',
277 277 default=b'auto',
278 278 )
279 279 coreconfigitem(
280 280 b'color',
281 281 b'pagermode',
282 282 default=dynamicdefault,
283 283 )
284 284 coreconfigitem(
285 285 b'command-templates',
286 286 b'graphnode',
287 287 default=None,
288 288 alias=[(b'ui', b'graphnodetemplate')],
289 289 )
290 290 coreconfigitem(
291 291 b'command-templates',
292 292 b'log',
293 293 default=None,
294 294 alias=[(b'ui', b'logtemplate')],
295 295 )
296 296 coreconfigitem(
297 297 b'command-templates',
298 298 b'mergemarker',
299 299 default=(
300 300 b'{node|short} '
301 301 b'{ifeq(tags, "tip", "", '
302 302 b'ifeq(tags, "", "", "{tags} "))}'
303 303 b'{if(bookmarks, "{bookmarks} ")}'
304 304 b'{ifeq(branch, "default", "", "{branch} ")}'
305 305 b'- {author|user}: {desc|firstline}'
306 306 ),
307 307 alias=[(b'ui', b'mergemarkertemplate')],
308 308 )
309 309 coreconfigitem(
310 310 b'command-templates',
311 311 b'pre-merge-tool-output',
312 312 default=None,
313 313 alias=[(b'ui', b'pre-merge-tool-output-template')],
314 314 )
315 315 coreconfigitem(
316 316 b'command-templates',
317 317 b'oneline-summary',
318 318 default=None,
319 319 )
320 320 coreconfigitem(
321 321 b'command-templates',
322 322 b'oneline-summary.*',
323 323 default=dynamicdefault,
324 324 generic=True,
325 325 )
326 326 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
327 327 coreconfigitem(
328 328 b'commands',
329 329 b'commit.post-status',
330 330 default=False,
331 331 )
332 332 coreconfigitem(
333 333 b'commands',
334 334 b'grep.all-files',
335 335 default=False,
336 336 experimental=True,
337 337 )
338 338 coreconfigitem(
339 339 b'commands',
340 340 b'merge.require-rev',
341 341 default=False,
342 342 )
343 343 coreconfigitem(
344 344 b'commands',
345 345 b'push.require-revs',
346 346 default=False,
347 347 )
348 348 coreconfigitem(
349 349 b'commands',
350 350 b'resolve.confirm',
351 351 default=False,
352 352 )
353 353 coreconfigitem(
354 354 b'commands',
355 355 b'resolve.explicit-re-merge',
356 356 default=False,
357 357 )
358 358 coreconfigitem(
359 359 b'commands',
360 360 b'resolve.mark-check',
361 361 default=b'none',
362 362 )
363 363 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
364 364 coreconfigitem(
365 365 b'commands',
366 366 b'show.aliasprefix',
367 367 default=list,
368 368 )
369 369 coreconfigitem(
370 370 b'commands',
371 371 b'status.relative',
372 372 default=False,
373 373 )
374 374 coreconfigitem(
375 375 b'commands',
376 376 b'status.skipstates',
377 377 default=[],
378 378 experimental=True,
379 379 )
380 380 coreconfigitem(
381 381 b'commands',
382 382 b'status.terse',
383 383 default=b'',
384 384 )
385 385 coreconfigitem(
386 386 b'commands',
387 387 b'status.verbose',
388 388 default=False,
389 389 )
390 390 coreconfigitem(
391 391 b'commands',
392 392 b'update.check',
393 393 default=None,
394 394 )
395 395 coreconfigitem(
396 396 b'commands',
397 397 b'update.requiredest',
398 398 default=False,
399 399 )
400 400 coreconfigitem(
401 401 b'committemplate',
402 402 b'.*',
403 403 default=None,
404 404 generic=True,
405 405 )
406 406 coreconfigitem(
407 407 b'convert',
408 408 b'bzr.saverev',
409 409 default=True,
410 410 )
411 411 coreconfigitem(
412 412 b'convert',
413 413 b'cvsps.cache',
414 414 default=True,
415 415 )
416 416 coreconfigitem(
417 417 b'convert',
418 418 b'cvsps.fuzz',
419 419 default=60,
420 420 )
421 421 coreconfigitem(
422 422 b'convert',
423 423 b'cvsps.logencoding',
424 424 default=None,
425 425 )
426 426 coreconfigitem(
427 427 b'convert',
428 428 b'cvsps.mergefrom',
429 429 default=None,
430 430 )
431 431 coreconfigitem(
432 432 b'convert',
433 433 b'cvsps.mergeto',
434 434 default=None,
435 435 )
436 436 coreconfigitem(
437 437 b'convert',
438 438 b'git.committeractions',
439 439 default=lambda: [b'messagedifferent'],
440 440 )
441 441 coreconfigitem(
442 442 b'convert',
443 443 b'git.extrakeys',
444 444 default=list,
445 445 )
446 446 coreconfigitem(
447 447 b'convert',
448 448 b'git.findcopiesharder',
449 449 default=False,
450 450 )
451 451 coreconfigitem(
452 452 b'convert',
453 453 b'git.remoteprefix',
454 454 default=b'remote',
455 455 )
456 456 coreconfigitem(
457 457 b'convert',
458 458 b'git.renamelimit',
459 459 default=400,
460 460 )
461 461 coreconfigitem(
462 462 b'convert',
463 463 b'git.saverev',
464 464 default=True,
465 465 )
466 466 coreconfigitem(
467 467 b'convert',
468 468 b'git.similarity',
469 469 default=50,
470 470 )
471 471 coreconfigitem(
472 472 b'convert',
473 473 b'git.skipsubmodules',
474 474 default=False,
475 475 )
476 476 coreconfigitem(
477 477 b'convert',
478 478 b'hg.clonebranches',
479 479 default=False,
480 480 )
481 481 coreconfigitem(
482 482 b'convert',
483 483 b'hg.ignoreerrors',
484 484 default=False,
485 485 )
486 486 coreconfigitem(
487 487 b'convert',
488 488 b'hg.preserve-hash',
489 489 default=False,
490 490 )
491 491 coreconfigitem(
492 492 b'convert',
493 493 b'hg.revs',
494 494 default=None,
495 495 )
496 496 coreconfigitem(
497 497 b'convert',
498 498 b'hg.saverev',
499 499 default=False,
500 500 )
501 501 coreconfigitem(
502 502 b'convert',
503 503 b'hg.sourcename',
504 504 default=None,
505 505 )
506 506 coreconfigitem(
507 507 b'convert',
508 508 b'hg.startrev',
509 509 default=None,
510 510 )
511 511 coreconfigitem(
512 512 b'convert',
513 513 b'hg.tagsbranch',
514 514 default=b'default',
515 515 )
516 516 coreconfigitem(
517 517 b'convert',
518 518 b'hg.usebranchnames',
519 519 default=True,
520 520 )
521 521 coreconfigitem(
522 522 b'convert',
523 523 b'ignoreancestorcheck',
524 524 default=False,
525 525 experimental=True,
526 526 )
527 527 coreconfigitem(
528 528 b'convert',
529 529 b'localtimezone',
530 530 default=False,
531 531 )
532 532 coreconfigitem(
533 533 b'convert',
534 534 b'p4.encoding',
535 535 default=dynamicdefault,
536 536 )
537 537 coreconfigitem(
538 538 b'convert',
539 539 b'p4.startrev',
540 540 default=0,
541 541 )
542 542 coreconfigitem(
543 543 b'convert',
544 544 b'skiptags',
545 545 default=False,
546 546 )
547 547 coreconfigitem(
548 548 b'convert',
549 549 b'svn.debugsvnlog',
550 550 default=True,
551 551 )
552 552 coreconfigitem(
553 553 b'convert',
554 554 b'svn.trunk',
555 555 default=None,
556 556 )
557 557 coreconfigitem(
558 558 b'convert',
559 559 b'svn.tags',
560 560 default=None,
561 561 )
562 562 coreconfigitem(
563 563 b'convert',
564 564 b'svn.branches',
565 565 default=None,
566 566 )
567 567 coreconfigitem(
568 568 b'convert',
569 569 b'svn.startrev',
570 570 default=0,
571 571 )
572 572 coreconfigitem(
573 573 b'convert',
574 574 b'svn.dangerous-set-commit-dates',
575 575 default=False,
576 576 )
577 577 coreconfigitem(
578 578 b'debug',
579 579 b'dirstate.delaywrite',
580 580 default=0,
581 581 )
582 582 coreconfigitem(
583 583 b'debug',
584 584 b'revlog.verifyposition.changelog',
585 585 default=b'',
586 586 )
587 587 coreconfigitem(
588 588 b'defaults',
589 589 b'.*',
590 590 default=None,
591 591 generic=True,
592 592 )
593 593 coreconfigitem(
594 594 b'devel',
595 595 b'all-warnings',
596 596 default=False,
597 597 )
598 598 coreconfigitem(
599 599 b'devel',
600 600 b'bundle2.debug',
601 601 default=False,
602 602 )
603 603 coreconfigitem(
604 604 b'devel',
605 605 b'bundle.delta',
606 606 default=b'',
607 607 )
608 608 coreconfigitem(
609 609 b'devel',
610 610 b'cache-vfs',
611 611 default=None,
612 612 )
613 613 coreconfigitem(
614 614 b'devel',
615 615 b'check-locks',
616 616 default=False,
617 617 )
618 618 coreconfigitem(
619 619 b'devel',
620 620 b'check-relroot',
621 621 default=False,
622 622 )
623 623 # Track copy information for all file, not just "added" one (very slow)
624 624 coreconfigitem(
625 625 b'devel',
626 626 b'copy-tracing.trace-all-files',
627 627 default=False,
628 628 )
629 629 coreconfigitem(
630 630 b'devel',
631 631 b'default-date',
632 632 default=None,
633 633 )
634 634 coreconfigitem(
635 635 b'devel',
636 636 b'deprec-warn',
637 637 default=False,
638 638 )
639 639 coreconfigitem(
640 640 b'devel',
641 641 b'disableloaddefaultcerts',
642 642 default=False,
643 643 )
644 644 coreconfigitem(
645 645 b'devel',
646 646 b'warn-empty-changegroup',
647 647 default=False,
648 648 )
649 649 coreconfigitem(
650 650 b'devel',
651 651 b'legacy.exchange',
652 652 default=list,
653 653 )
654 654 # When True, revlogs use a special reference version of the nodemap, that is not
655 655 # performant but is "known" to behave properly.
656 656 coreconfigitem(
657 657 b'devel',
658 658 b'persistent-nodemap',
659 659 default=False,
660 660 )
661 661 coreconfigitem(
662 662 b'devel',
663 663 b'servercafile',
664 664 default=b'',
665 665 )
666 666 coreconfigitem(
667 667 b'devel',
668 668 b'serverexactprotocol',
669 669 default=b'',
670 670 )
671 671 coreconfigitem(
672 672 b'devel',
673 673 b'serverrequirecert',
674 674 default=False,
675 675 )
676 676 coreconfigitem(
677 677 b'devel',
678 678 b'strip-obsmarkers',
679 679 default=True,
680 680 )
681 681 coreconfigitem(
682 682 b'devel',
683 683 b'warn-config',
684 684 default=None,
685 685 )
686 686 coreconfigitem(
687 687 b'devel',
688 688 b'warn-config-default',
689 689 default=None,
690 690 )
691 691 coreconfigitem(
692 692 b'devel',
693 693 b'user.obsmarker',
694 694 default=None,
695 695 )
696 696 coreconfigitem(
697 697 b'devel',
698 698 b'warn-config-unknown',
699 699 default=None,
700 700 )
701 701 coreconfigitem(
702 702 b'devel',
703 703 b'debug.copies',
704 704 default=False,
705 705 )
706 706 coreconfigitem(
707 707 b'devel',
708 708 b'copy-tracing.multi-thread',
709 709 default=True,
710 710 )
711 711 coreconfigitem(
712 712 b'devel',
713 713 b'debug.extensions',
714 714 default=False,
715 715 )
716 716 coreconfigitem(
717 717 b'devel',
718 718 b'debug.repo-filters',
719 719 default=False,
720 720 )
721 721 coreconfigitem(
722 722 b'devel',
723 723 b'debug.peer-request',
724 724 default=False,
725 725 )
726 726 # If discovery.exchange-heads is False, the discovery will not start with
727 727 # remote head fetching and local head querying.
728 728 coreconfigitem(
729 729 b'devel',
730 730 b'discovery.exchange-heads',
731 731 default=True,
732 732 )
733 733 # If discovery.grow-sample is False, the sample size used in set discovery will
734 734 # not be increased through the process
735 735 coreconfigitem(
736 736 b'devel',
737 737 b'discovery.grow-sample',
738 738 default=True,
739 739 )
740 740 # When discovery.grow-sample.dynamic is True, the default, the sample size is
741 741 # adapted to the shape of the undecided set (it is set to the max of:
742 742 # <target-size>, len(roots(undecided)), len(heads(undecided)
743 743 coreconfigitem(
744 744 b'devel',
745 745 b'discovery.grow-sample.dynamic',
746 746 default=True,
747 747 )
748 748 # discovery.grow-sample.rate control the rate at which the sample grow
749 749 coreconfigitem(
750 750 b'devel',
751 751 b'discovery.grow-sample.rate',
752 752 default=1.05,
753 753 )
754 754 # If discovery.randomize is False, random sampling during discovery are
755 755 # deterministic. It is meant for integration tests.
756 756 coreconfigitem(
757 757 b'devel',
758 758 b'discovery.randomize',
759 759 default=True,
760 760 )
761 761 # Control the initial size of the discovery sample
762 762 coreconfigitem(
763 763 b'devel',
764 764 b'discovery.sample-size',
765 765 default=200,
766 766 )
767 767 # Control the initial size of the discovery for initial change
768 768 coreconfigitem(
769 769 b'devel',
770 770 b'discovery.sample-size.initial',
771 771 default=100,
772 772 )
773 773 _registerdiffopts(section=b'diff')
774 774 coreconfigitem(
775 775 b'diff',
776 776 b'merge',
777 777 default=False,
778 778 experimental=True,
779 779 )
780 780 coreconfigitem(
781 781 b'email',
782 782 b'bcc',
783 783 default=None,
784 784 )
785 785 coreconfigitem(
786 786 b'email',
787 787 b'cc',
788 788 default=None,
789 789 )
790 790 coreconfigitem(
791 791 b'email',
792 792 b'charsets',
793 793 default=list,
794 794 )
795 795 coreconfigitem(
796 796 b'email',
797 797 b'from',
798 798 default=None,
799 799 )
800 800 coreconfigitem(
801 801 b'email',
802 802 b'method',
803 803 default=b'smtp',
804 804 )
805 805 coreconfigitem(
806 806 b'email',
807 807 b'reply-to',
808 808 default=None,
809 809 )
810 810 coreconfigitem(
811 811 b'email',
812 812 b'to',
813 813 default=None,
814 814 )
815 815 coreconfigitem(
816 816 b'experimental',
817 817 b'archivemetatemplate',
818 818 default=dynamicdefault,
819 819 )
820 820 coreconfigitem(
821 821 b'experimental',
822 822 b'auto-publish',
823 823 default=b'publish',
824 824 )
825 825 coreconfigitem(
826 826 b'experimental',
827 827 b'bundle-phases',
828 828 default=False,
829 829 )
830 830 coreconfigitem(
831 831 b'experimental',
832 832 b'bundle2-advertise',
833 833 default=True,
834 834 )
835 835 coreconfigitem(
836 836 b'experimental',
837 837 b'bundle2-output-capture',
838 838 default=False,
839 839 )
840 840 coreconfigitem(
841 841 b'experimental',
842 842 b'bundle2.pushback',
843 843 default=False,
844 844 )
845 845 coreconfigitem(
846 846 b'experimental',
847 847 b'bundle2lazylocking',
848 848 default=False,
849 849 )
850 850 coreconfigitem(
851 851 b'experimental',
852 852 b'bundlecomplevel',
853 853 default=None,
854 854 )
855 855 coreconfigitem(
856 856 b'experimental',
857 857 b'bundlecomplevel.bzip2',
858 858 default=None,
859 859 )
860 860 coreconfigitem(
861 861 b'experimental',
862 862 b'bundlecomplevel.gzip',
863 863 default=None,
864 864 )
865 865 coreconfigitem(
866 866 b'experimental',
867 867 b'bundlecomplevel.none',
868 868 default=None,
869 869 )
870 870 coreconfigitem(
871 871 b'experimental',
872 872 b'bundlecomplevel.zstd',
873 873 default=None,
874 874 )
875 875 coreconfigitem(
876 876 b'experimental',
877 877 b'bundlecompthreads',
878 878 default=None,
879 879 )
880 880 coreconfigitem(
881 881 b'experimental',
882 882 b'bundlecompthreads.bzip2',
883 883 default=None,
884 884 )
885 885 coreconfigitem(
886 886 b'experimental',
887 887 b'bundlecompthreads.gzip',
888 888 default=None,
889 889 )
890 890 coreconfigitem(
891 891 b'experimental',
892 892 b'bundlecompthreads.none',
893 893 default=None,
894 894 )
895 895 coreconfigitem(
896 896 b'experimental',
897 897 b'bundlecompthreads.zstd',
898 898 default=None,
899 899 )
900 900 coreconfigitem(
901 901 b'experimental',
902 902 b'changegroup3',
903 903 default=False,
904 904 )
905 905 coreconfigitem(
906 906 b'experimental',
907 b'changegroup4',
908 default=False,
909 )
910 coreconfigitem(
911 b'experimental',
907 912 b'cleanup-as-archived',
908 913 default=False,
909 914 )
910 915 coreconfigitem(
911 916 b'experimental',
912 917 b'clientcompressionengines',
913 918 default=list,
914 919 )
915 920 coreconfigitem(
916 921 b'experimental',
917 922 b'copytrace',
918 923 default=b'on',
919 924 )
920 925 coreconfigitem(
921 926 b'experimental',
922 927 b'copytrace.movecandidateslimit',
923 928 default=100,
924 929 )
925 930 coreconfigitem(
926 931 b'experimental',
927 932 b'copytrace.sourcecommitlimit',
928 933 default=100,
929 934 )
930 935 coreconfigitem(
931 936 b'experimental',
932 937 b'copies.read-from',
933 938 default=b"filelog-only",
934 939 )
935 940 coreconfigitem(
936 941 b'experimental',
937 942 b'copies.write-to',
938 943 default=b'filelog-only',
939 944 )
940 945 coreconfigitem(
941 946 b'experimental',
942 947 b'crecordtest',
943 948 default=None,
944 949 )
945 950 coreconfigitem(
946 951 b'experimental',
947 952 b'directaccess',
948 953 default=False,
949 954 )
950 955 coreconfigitem(
951 956 b'experimental',
952 957 b'directaccess.revnums',
953 958 default=False,
954 959 )
955 960 coreconfigitem(
956 961 b'experimental',
957 962 b'editortmpinhg',
958 963 default=False,
959 964 )
960 965 coreconfigitem(
961 966 b'experimental',
962 967 b'evolution',
963 968 default=list,
964 969 )
965 970 coreconfigitem(
966 971 b'experimental',
967 972 b'evolution.allowdivergence',
968 973 default=False,
969 974 alias=[(b'experimental', b'allowdivergence')],
970 975 )
971 976 coreconfigitem(
972 977 b'experimental',
973 978 b'evolution.allowunstable',
974 979 default=None,
975 980 )
976 981 coreconfigitem(
977 982 b'experimental',
978 983 b'evolution.createmarkers',
979 984 default=None,
980 985 )
981 986 coreconfigitem(
982 987 b'experimental',
983 988 b'evolution.effect-flags',
984 989 default=True,
985 990 alias=[(b'experimental', b'effect-flags')],
986 991 )
987 992 coreconfigitem(
988 993 b'experimental',
989 994 b'evolution.exchange',
990 995 default=None,
991 996 )
992 997 coreconfigitem(
993 998 b'experimental',
994 999 b'evolution.bundle-obsmarker',
995 1000 default=False,
996 1001 )
997 1002 coreconfigitem(
998 1003 b'experimental',
999 1004 b'evolution.bundle-obsmarker:mandatory',
1000 1005 default=True,
1001 1006 )
1002 1007 coreconfigitem(
1003 1008 b'experimental',
1004 1009 b'log.topo',
1005 1010 default=False,
1006 1011 )
1007 1012 coreconfigitem(
1008 1013 b'experimental',
1009 1014 b'evolution.report-instabilities',
1010 1015 default=True,
1011 1016 )
1012 1017 coreconfigitem(
1013 1018 b'experimental',
1014 1019 b'evolution.track-operation',
1015 1020 default=True,
1016 1021 )
1017 1022 # repo-level config to exclude a revset visibility
1018 1023 #
1019 1024 # The target use case is to use `share` to expose different subset of the same
1020 1025 # repository, especially server side. See also `server.view`.
1021 1026 coreconfigitem(
1022 1027 b'experimental',
1023 1028 b'extra-filter-revs',
1024 1029 default=None,
1025 1030 )
1026 1031 coreconfigitem(
1027 1032 b'experimental',
1028 1033 b'maxdeltachainspan',
1029 1034 default=-1,
1030 1035 )
1031 1036 # tracks files which were undeleted (merge might delete them but we explicitly
1032 1037 # kept/undeleted them) and creates new filenodes for them
1033 1038 coreconfigitem(
1034 1039 b'experimental',
1035 1040 b'merge-track-salvaged',
1036 1041 default=False,
1037 1042 )
1038 1043 coreconfigitem(
1039 1044 b'experimental',
1040 1045 b'mergetempdirprefix',
1041 1046 default=None,
1042 1047 )
1043 1048 coreconfigitem(
1044 1049 b'experimental',
1045 1050 b'mmapindexthreshold',
1046 1051 default=None,
1047 1052 )
1048 1053 coreconfigitem(
1049 1054 b'experimental',
1050 1055 b'narrow',
1051 1056 default=False,
1052 1057 )
1053 1058 coreconfigitem(
1054 1059 b'experimental',
1055 1060 b'nonnormalparanoidcheck',
1056 1061 default=False,
1057 1062 )
1058 1063 coreconfigitem(
1059 1064 b'experimental',
1060 1065 b'exportableenviron',
1061 1066 default=list,
1062 1067 )
1063 1068 coreconfigitem(
1064 1069 b'experimental',
1065 1070 b'extendedheader.index',
1066 1071 default=None,
1067 1072 )
1068 1073 coreconfigitem(
1069 1074 b'experimental',
1070 1075 b'extendedheader.similarity',
1071 1076 default=False,
1072 1077 )
1073 1078 coreconfigitem(
1074 1079 b'experimental',
1075 1080 b'graphshorten',
1076 1081 default=False,
1077 1082 )
1078 1083 coreconfigitem(
1079 1084 b'experimental',
1080 1085 b'graphstyle.parent',
1081 1086 default=dynamicdefault,
1082 1087 )
1083 1088 coreconfigitem(
1084 1089 b'experimental',
1085 1090 b'graphstyle.missing',
1086 1091 default=dynamicdefault,
1087 1092 )
1088 1093 coreconfigitem(
1089 1094 b'experimental',
1090 1095 b'graphstyle.grandparent',
1091 1096 default=dynamicdefault,
1092 1097 )
1093 1098 coreconfigitem(
1094 1099 b'experimental',
1095 1100 b'hook-track-tags',
1096 1101 default=False,
1097 1102 )
1098 1103 coreconfigitem(
1099 1104 b'experimental',
1100 1105 b'httppeer.advertise-v2',
1101 1106 default=False,
1102 1107 )
1103 1108 coreconfigitem(
1104 1109 b'experimental',
1105 1110 b'httppeer.v2-encoder-order',
1106 1111 default=None,
1107 1112 )
1108 1113 coreconfigitem(
1109 1114 b'experimental',
1110 1115 b'httppostargs',
1111 1116 default=False,
1112 1117 )
1113 1118 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1114 1119 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1115 1120
1116 1121 coreconfigitem(
1117 1122 b'experimental',
1118 1123 b'obsmarkers-exchange-debug',
1119 1124 default=False,
1120 1125 )
1121 1126 coreconfigitem(
1122 1127 b'experimental',
1123 1128 b'remotenames',
1124 1129 default=False,
1125 1130 )
1126 1131 coreconfigitem(
1127 1132 b'experimental',
1128 1133 b'removeemptydirs',
1129 1134 default=True,
1130 1135 )
1131 1136 coreconfigitem(
1132 1137 b'experimental',
1133 1138 b'revert.interactive.select-to-keep',
1134 1139 default=False,
1135 1140 )
1136 1141 coreconfigitem(
1137 1142 b'experimental',
1138 1143 b'revisions.prefixhexnode',
1139 1144 default=False,
1140 1145 )
1141 1146 coreconfigitem(
1142 1147 b'experimental',
1143 1148 b'revlogv2',
1144 1149 default=None,
1145 1150 )
1146 1151 coreconfigitem(
1147 1152 b'experimental',
1148 1153 b'revisions.disambiguatewithin',
1149 1154 default=None,
1150 1155 )
1151 1156 coreconfigitem(
1152 1157 b'experimental',
1153 1158 b'rust.index',
1154 1159 default=False,
1155 1160 )
1156 1161 coreconfigitem(
1157 1162 b'experimental',
1158 1163 b'server.filesdata.recommended-batch-size',
1159 1164 default=50000,
1160 1165 )
1161 1166 coreconfigitem(
1162 1167 b'experimental',
1163 1168 b'server.manifestdata.recommended-batch-size',
1164 1169 default=100000,
1165 1170 )
1166 1171 coreconfigitem(
1167 1172 b'experimental',
1168 1173 b'server.stream-narrow-clones',
1169 1174 default=False,
1170 1175 )
1171 1176 coreconfigitem(
1172 1177 b'experimental',
1173 1178 b'single-head-per-branch',
1174 1179 default=False,
1175 1180 )
1176 1181 coreconfigitem(
1177 1182 b'experimental',
1178 1183 b'single-head-per-branch:account-closed-heads',
1179 1184 default=False,
1180 1185 )
1181 1186 coreconfigitem(
1182 1187 b'experimental',
1183 1188 b'single-head-per-branch:public-changes-only',
1184 1189 default=False,
1185 1190 )
1186 1191 coreconfigitem(
1187 1192 b'experimental',
1188 1193 b'sshserver.support-v2',
1189 1194 default=False,
1190 1195 )
1191 1196 coreconfigitem(
1192 1197 b'experimental',
1193 1198 b'sparse-read',
1194 1199 default=False,
1195 1200 )
1196 1201 coreconfigitem(
1197 1202 b'experimental',
1198 1203 b'sparse-read.density-threshold',
1199 1204 default=0.50,
1200 1205 )
1201 1206 coreconfigitem(
1202 1207 b'experimental',
1203 1208 b'sparse-read.min-gap-size',
1204 1209 default=b'65K',
1205 1210 )
1206 1211 coreconfigitem(
1207 1212 b'experimental',
1208 1213 b'treemanifest',
1209 1214 default=False,
1210 1215 )
1211 1216 coreconfigitem(
1212 1217 b'experimental',
1213 1218 b'update.atomic-file',
1214 1219 default=False,
1215 1220 )
1216 1221 coreconfigitem(
1217 1222 b'experimental',
1218 1223 b'sshpeer.advertise-v2',
1219 1224 default=False,
1220 1225 )
1221 1226 coreconfigitem(
1222 1227 b'experimental',
1223 1228 b'web.apiserver',
1224 1229 default=False,
1225 1230 )
1226 1231 coreconfigitem(
1227 1232 b'experimental',
1228 1233 b'web.api.http-v2',
1229 1234 default=False,
1230 1235 )
1231 1236 coreconfigitem(
1232 1237 b'experimental',
1233 1238 b'web.api.debugreflect',
1234 1239 default=False,
1235 1240 )
1236 1241 coreconfigitem(
1237 1242 b'experimental',
1238 1243 b'worker.wdir-get-thread-safe',
1239 1244 default=False,
1240 1245 )
1241 1246 coreconfigitem(
1242 1247 b'experimental',
1243 1248 b'worker.repository-upgrade',
1244 1249 default=False,
1245 1250 )
1246 1251 coreconfigitem(
1247 1252 b'experimental',
1248 1253 b'xdiff',
1249 1254 default=False,
1250 1255 )
1251 1256 coreconfigitem(
1252 1257 b'extensions',
1253 1258 b'.*',
1254 1259 default=None,
1255 1260 generic=True,
1256 1261 )
1257 1262 coreconfigitem(
1258 1263 b'extdata',
1259 1264 b'.*',
1260 1265 default=None,
1261 1266 generic=True,
1262 1267 )
1263 1268 coreconfigitem(
1264 1269 b'format',
1265 1270 b'bookmarks-in-store',
1266 1271 default=False,
1267 1272 )
1268 1273 coreconfigitem(
1269 1274 b'format',
1270 1275 b'chunkcachesize',
1271 1276 default=None,
1272 1277 experimental=True,
1273 1278 )
1274 1279 coreconfigitem(
1275 1280 b'format',
1276 1281 b'dotencode',
1277 1282 default=True,
1278 1283 )
1279 1284 coreconfigitem(
1280 1285 b'format',
1281 1286 b'generaldelta',
1282 1287 default=False,
1283 1288 experimental=True,
1284 1289 )
1285 1290 coreconfigitem(
1286 1291 b'format',
1287 1292 b'manifestcachesize',
1288 1293 default=None,
1289 1294 experimental=True,
1290 1295 )
1291 1296 coreconfigitem(
1292 1297 b'format',
1293 1298 b'maxchainlen',
1294 1299 default=dynamicdefault,
1295 1300 experimental=True,
1296 1301 )
1297 1302 coreconfigitem(
1298 1303 b'format',
1299 1304 b'obsstore-version',
1300 1305 default=None,
1301 1306 )
1302 1307 coreconfigitem(
1303 1308 b'format',
1304 1309 b'sparse-revlog',
1305 1310 default=True,
1306 1311 )
1307 1312 coreconfigitem(
1308 1313 b'format',
1309 1314 b'revlog-compression',
1310 1315 default=lambda: [b'zstd', b'zlib'],
1311 1316 alias=[(b'experimental', b'format.compression')],
1312 1317 )
1313 1318 coreconfigitem(
1314 1319 b'format',
1315 1320 b'usefncache',
1316 1321 default=True,
1317 1322 )
1318 1323 coreconfigitem(
1319 1324 b'format',
1320 1325 b'usegeneraldelta',
1321 1326 default=True,
1322 1327 )
1323 1328 coreconfigitem(
1324 1329 b'format',
1325 1330 b'usestore',
1326 1331 default=True,
1327 1332 )
1328 1333
1329 1334
1330 1335 def _persistent_nodemap_default():
1331 1336 """compute `use-persistent-nodemap` default value
1332 1337
1333 1338 The feature is disabled unless a fast implementation is available.
1334 1339 """
1335 1340 from . import policy
1336 1341
1337 1342 return policy.importrust('revlog') is not None
1338 1343
1339 1344
1340 1345 coreconfigitem(
1341 1346 b'format',
1342 1347 b'use-persistent-nodemap',
1343 1348 default=_persistent_nodemap_default,
1344 1349 )
1345 1350 # TODO needs to grow a docket file to at least store the last offset of the data
1346 1351 # file when rewriting sidedata.
1347 1352 # Will also need a way of dealing with garbage data if we allow rewriting
1348 1353 # *existing* sidedata.
1349 1354 # Exchange-wise, we will also need to do something more efficient than keeping
1350 1355 # references to the affected revlogs, especially memory-wise when rewriting
1351 1356 # sidedata.
1352 1357 # Also... compress the sidedata? (this should be coming very soon)
1353 1358 coreconfigitem(
1354 1359 b'format',
1355 1360 b'exp-revlogv2.2',
1356 1361 default=False,
1357 1362 experimental=True,
1358 1363 )
1359 1364 coreconfigitem(
1360 1365 b'format',
1361 1366 b'exp-use-copies-side-data-changeset',
1362 1367 default=False,
1363 1368 experimental=True,
1364 1369 )
1365 1370 coreconfigitem(
1366 1371 b'format',
1367 1372 b'exp-use-side-data',
1368 1373 default=False,
1369 1374 experimental=True,
1370 1375 )
1371 1376 coreconfigitem(
1372 1377 b'format',
1373 1378 b'use-share-safe',
1374 1379 default=False,
1375 1380 )
1376 1381 coreconfigitem(
1377 1382 b'format',
1378 1383 b'internal-phase',
1379 1384 default=False,
1380 1385 experimental=True,
1381 1386 )
1382 1387 coreconfigitem(
1383 1388 b'fsmonitor',
1384 1389 b'warn_when_unused',
1385 1390 default=True,
1386 1391 )
1387 1392 coreconfigitem(
1388 1393 b'fsmonitor',
1389 1394 b'warn_update_file_count',
1390 1395 default=50000,
1391 1396 )
1392 1397 coreconfigitem(
1393 1398 b'fsmonitor',
1394 1399 b'warn_update_file_count_rust',
1395 1400 default=400000,
1396 1401 )
1397 1402 coreconfigitem(
1398 1403 b'help',
1399 1404 br'hidden-command\..*',
1400 1405 default=False,
1401 1406 generic=True,
1402 1407 )
1403 1408 coreconfigitem(
1404 1409 b'help',
1405 1410 br'hidden-topic\..*',
1406 1411 default=False,
1407 1412 generic=True,
1408 1413 )
1409 1414 coreconfigitem(
1410 1415 b'hooks',
1411 1416 b'[^:]*',
1412 1417 default=dynamicdefault,
1413 1418 generic=True,
1414 1419 )
1415 1420 coreconfigitem(
1416 1421 b'hooks',
1417 1422 b'.*:run-with-plain',
1418 1423 default=True,
1419 1424 generic=True,
1420 1425 )
1421 1426 coreconfigitem(
1422 1427 b'hgweb-paths',
1423 1428 b'.*',
1424 1429 default=list,
1425 1430 generic=True,
1426 1431 )
1427 1432 coreconfigitem(
1428 1433 b'hostfingerprints',
1429 1434 b'.*',
1430 1435 default=list,
1431 1436 generic=True,
1432 1437 )
1433 1438 coreconfigitem(
1434 1439 b'hostsecurity',
1435 1440 b'ciphers',
1436 1441 default=None,
1437 1442 )
1438 1443 coreconfigitem(
1439 1444 b'hostsecurity',
1440 1445 b'minimumprotocol',
1441 1446 default=dynamicdefault,
1442 1447 )
1443 1448 coreconfigitem(
1444 1449 b'hostsecurity',
1445 1450 b'.*:minimumprotocol$',
1446 1451 default=dynamicdefault,
1447 1452 generic=True,
1448 1453 )
1449 1454 coreconfigitem(
1450 1455 b'hostsecurity',
1451 1456 b'.*:ciphers$',
1452 1457 default=dynamicdefault,
1453 1458 generic=True,
1454 1459 )
1455 1460 coreconfigitem(
1456 1461 b'hostsecurity',
1457 1462 b'.*:fingerprints$',
1458 1463 default=list,
1459 1464 generic=True,
1460 1465 )
1461 1466 coreconfigitem(
1462 1467 b'hostsecurity',
1463 1468 b'.*:verifycertsfile$',
1464 1469 default=None,
1465 1470 generic=True,
1466 1471 )
1467 1472
1468 1473 coreconfigitem(
1469 1474 b'http_proxy',
1470 1475 b'always',
1471 1476 default=False,
1472 1477 )
1473 1478 coreconfigitem(
1474 1479 b'http_proxy',
1475 1480 b'host',
1476 1481 default=None,
1477 1482 )
1478 1483 coreconfigitem(
1479 1484 b'http_proxy',
1480 1485 b'no',
1481 1486 default=list,
1482 1487 )
1483 1488 coreconfigitem(
1484 1489 b'http_proxy',
1485 1490 b'passwd',
1486 1491 default=None,
1487 1492 )
1488 1493 coreconfigitem(
1489 1494 b'http_proxy',
1490 1495 b'user',
1491 1496 default=None,
1492 1497 )
1493 1498
1494 1499 coreconfigitem(
1495 1500 b'http',
1496 1501 b'timeout',
1497 1502 default=None,
1498 1503 )
1499 1504
1500 1505 coreconfigitem(
1501 1506 b'logtoprocess',
1502 1507 b'commandexception',
1503 1508 default=None,
1504 1509 )
1505 1510 coreconfigitem(
1506 1511 b'logtoprocess',
1507 1512 b'commandfinish',
1508 1513 default=None,
1509 1514 )
1510 1515 coreconfigitem(
1511 1516 b'logtoprocess',
1512 1517 b'command',
1513 1518 default=None,
1514 1519 )
1515 1520 coreconfigitem(
1516 1521 b'logtoprocess',
1517 1522 b'develwarn',
1518 1523 default=None,
1519 1524 )
1520 1525 coreconfigitem(
1521 1526 b'logtoprocess',
1522 1527 b'uiblocked',
1523 1528 default=None,
1524 1529 )
1525 1530 coreconfigitem(
1526 1531 b'merge',
1527 1532 b'checkunknown',
1528 1533 default=b'abort',
1529 1534 )
1530 1535 coreconfigitem(
1531 1536 b'merge',
1532 1537 b'checkignored',
1533 1538 default=b'abort',
1534 1539 )
1535 1540 coreconfigitem(
1536 1541 b'experimental',
1537 1542 b'merge.checkpathconflicts',
1538 1543 default=False,
1539 1544 )
1540 1545 coreconfigitem(
1541 1546 b'merge',
1542 1547 b'followcopies',
1543 1548 default=True,
1544 1549 )
1545 1550 coreconfigitem(
1546 1551 b'merge',
1547 1552 b'on-failure',
1548 1553 default=b'continue',
1549 1554 )
1550 1555 coreconfigitem(
1551 1556 b'merge',
1552 1557 b'preferancestor',
1553 1558 default=lambda: [b'*'],
1554 1559 experimental=True,
1555 1560 )
1556 1561 coreconfigitem(
1557 1562 b'merge',
1558 1563 b'strict-capability-check',
1559 1564 default=False,
1560 1565 )
1561 1566 coreconfigitem(
1562 1567 b'merge-tools',
1563 1568 b'.*',
1564 1569 default=None,
1565 1570 generic=True,
1566 1571 )
1567 1572 coreconfigitem(
1568 1573 b'merge-tools',
1569 1574 br'.*\.args$',
1570 1575 default=b"$local $base $other",
1571 1576 generic=True,
1572 1577 priority=-1,
1573 1578 )
1574 1579 coreconfigitem(
1575 1580 b'merge-tools',
1576 1581 br'.*\.binary$',
1577 1582 default=False,
1578 1583 generic=True,
1579 1584 priority=-1,
1580 1585 )
1581 1586 coreconfigitem(
1582 1587 b'merge-tools',
1583 1588 br'.*\.check$',
1584 1589 default=list,
1585 1590 generic=True,
1586 1591 priority=-1,
1587 1592 )
1588 1593 coreconfigitem(
1589 1594 b'merge-tools',
1590 1595 br'.*\.checkchanged$',
1591 1596 default=False,
1592 1597 generic=True,
1593 1598 priority=-1,
1594 1599 )
1595 1600 coreconfigitem(
1596 1601 b'merge-tools',
1597 1602 br'.*\.executable$',
1598 1603 default=dynamicdefault,
1599 1604 generic=True,
1600 1605 priority=-1,
1601 1606 )
1602 1607 coreconfigitem(
1603 1608 b'merge-tools',
1604 1609 br'.*\.fixeol$',
1605 1610 default=False,
1606 1611 generic=True,
1607 1612 priority=-1,
1608 1613 )
1609 1614 coreconfigitem(
1610 1615 b'merge-tools',
1611 1616 br'.*\.gui$',
1612 1617 default=False,
1613 1618 generic=True,
1614 1619 priority=-1,
1615 1620 )
1616 1621 coreconfigitem(
1617 1622 b'merge-tools',
1618 1623 br'.*\.mergemarkers$',
1619 1624 default=b'basic',
1620 1625 generic=True,
1621 1626 priority=-1,
1622 1627 )
1623 1628 coreconfigitem(
1624 1629 b'merge-tools',
1625 1630 br'.*\.mergemarkertemplate$',
1626 1631 default=dynamicdefault, # take from command-templates.mergemarker
1627 1632 generic=True,
1628 1633 priority=-1,
1629 1634 )
1630 1635 coreconfigitem(
1631 1636 b'merge-tools',
1632 1637 br'.*\.priority$',
1633 1638 default=0,
1634 1639 generic=True,
1635 1640 priority=-1,
1636 1641 )
1637 1642 coreconfigitem(
1638 1643 b'merge-tools',
1639 1644 br'.*\.premerge$',
1640 1645 default=dynamicdefault,
1641 1646 generic=True,
1642 1647 priority=-1,
1643 1648 )
1644 1649 coreconfigitem(
1645 1650 b'merge-tools',
1646 1651 br'.*\.symlink$',
1647 1652 default=False,
1648 1653 generic=True,
1649 1654 priority=-1,
1650 1655 )
1651 1656 coreconfigitem(
1652 1657 b'pager',
1653 1658 b'attend-.*',
1654 1659 default=dynamicdefault,
1655 1660 generic=True,
1656 1661 )
1657 1662 coreconfigitem(
1658 1663 b'pager',
1659 1664 b'ignore',
1660 1665 default=list,
1661 1666 )
1662 1667 coreconfigitem(
1663 1668 b'pager',
1664 1669 b'pager',
1665 1670 default=dynamicdefault,
1666 1671 )
1667 1672 coreconfigitem(
1668 1673 b'patch',
1669 1674 b'eol',
1670 1675 default=b'strict',
1671 1676 )
1672 1677 coreconfigitem(
1673 1678 b'patch',
1674 1679 b'fuzz',
1675 1680 default=2,
1676 1681 )
1677 1682 coreconfigitem(
1678 1683 b'paths',
1679 1684 b'default',
1680 1685 default=None,
1681 1686 )
1682 1687 coreconfigitem(
1683 1688 b'paths',
1684 1689 b'default-push',
1685 1690 default=None,
1686 1691 )
1687 1692 coreconfigitem(
1688 1693 b'paths',
1689 1694 b'.*',
1690 1695 default=None,
1691 1696 generic=True,
1692 1697 )
1693 1698 coreconfigitem(
1694 1699 b'phases',
1695 1700 b'checksubrepos',
1696 1701 default=b'follow',
1697 1702 )
1698 1703 coreconfigitem(
1699 1704 b'phases',
1700 1705 b'new-commit',
1701 1706 default=b'draft',
1702 1707 )
1703 1708 coreconfigitem(
1704 1709 b'phases',
1705 1710 b'publish',
1706 1711 default=True,
1707 1712 )
1708 1713 coreconfigitem(
1709 1714 b'profiling',
1710 1715 b'enabled',
1711 1716 default=False,
1712 1717 )
1713 1718 coreconfigitem(
1714 1719 b'profiling',
1715 1720 b'format',
1716 1721 default=b'text',
1717 1722 )
1718 1723 coreconfigitem(
1719 1724 b'profiling',
1720 1725 b'freq',
1721 1726 default=1000,
1722 1727 )
1723 1728 coreconfigitem(
1724 1729 b'profiling',
1725 1730 b'limit',
1726 1731 default=30,
1727 1732 )
1728 1733 coreconfigitem(
1729 1734 b'profiling',
1730 1735 b'nested',
1731 1736 default=0,
1732 1737 )
1733 1738 coreconfigitem(
1734 1739 b'profiling',
1735 1740 b'output',
1736 1741 default=None,
1737 1742 )
1738 1743 coreconfigitem(
1739 1744 b'profiling',
1740 1745 b'showmax',
1741 1746 default=0.999,
1742 1747 )
1743 1748 coreconfigitem(
1744 1749 b'profiling',
1745 1750 b'showmin',
1746 1751 default=dynamicdefault,
1747 1752 )
1748 1753 coreconfigitem(
1749 1754 b'profiling',
1750 1755 b'showtime',
1751 1756 default=True,
1752 1757 )
1753 1758 coreconfigitem(
1754 1759 b'profiling',
1755 1760 b'sort',
1756 1761 default=b'inlinetime',
1757 1762 )
1758 1763 coreconfigitem(
1759 1764 b'profiling',
1760 1765 b'statformat',
1761 1766 default=b'hotpath',
1762 1767 )
1763 1768 coreconfigitem(
1764 1769 b'profiling',
1765 1770 b'time-track',
1766 1771 default=dynamicdefault,
1767 1772 )
1768 1773 coreconfigitem(
1769 1774 b'profiling',
1770 1775 b'type',
1771 1776 default=b'stat',
1772 1777 )
1773 1778 coreconfigitem(
1774 1779 b'progress',
1775 1780 b'assume-tty',
1776 1781 default=False,
1777 1782 )
1778 1783 coreconfigitem(
1779 1784 b'progress',
1780 1785 b'changedelay',
1781 1786 default=1,
1782 1787 )
1783 1788 coreconfigitem(
1784 1789 b'progress',
1785 1790 b'clear-complete',
1786 1791 default=True,
1787 1792 )
1788 1793 coreconfigitem(
1789 1794 b'progress',
1790 1795 b'debug',
1791 1796 default=False,
1792 1797 )
1793 1798 coreconfigitem(
1794 1799 b'progress',
1795 1800 b'delay',
1796 1801 default=3,
1797 1802 )
1798 1803 coreconfigitem(
1799 1804 b'progress',
1800 1805 b'disable',
1801 1806 default=False,
1802 1807 )
1803 1808 coreconfigitem(
1804 1809 b'progress',
1805 1810 b'estimateinterval',
1806 1811 default=60.0,
1807 1812 )
1808 1813 coreconfigitem(
1809 1814 b'progress',
1810 1815 b'format',
1811 1816 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
1812 1817 )
1813 1818 coreconfigitem(
1814 1819 b'progress',
1815 1820 b'refresh',
1816 1821 default=0.1,
1817 1822 )
1818 1823 coreconfigitem(
1819 1824 b'progress',
1820 1825 b'width',
1821 1826 default=dynamicdefault,
1822 1827 )
1823 1828 coreconfigitem(
1824 1829 b'pull',
1825 1830 b'confirm',
1826 1831 default=False,
1827 1832 )
1828 1833 coreconfigitem(
1829 1834 b'push',
1830 1835 b'pushvars.server',
1831 1836 default=False,
1832 1837 )
1833 1838 coreconfigitem(
1834 1839 b'rewrite',
1835 1840 b'backup-bundle',
1836 1841 default=True,
1837 1842 alias=[(b'ui', b'history-editing-backup')],
1838 1843 )
1839 1844 coreconfigitem(
1840 1845 b'rewrite',
1841 1846 b'update-timestamp',
1842 1847 default=False,
1843 1848 )
1844 1849 coreconfigitem(
1845 1850 b'rewrite',
1846 1851 b'empty-successor',
1847 1852 default=b'skip',
1848 1853 experimental=True,
1849 1854 )
1850 1855 coreconfigitem(
1851 1856 b'storage',
1852 1857 b'new-repo-backend',
1853 1858 default=b'revlogv1',
1854 1859 experimental=True,
1855 1860 )
1856 1861 coreconfigitem(
1857 1862 b'storage',
1858 1863 b'revlog.optimize-delta-parent-choice',
1859 1864 default=True,
1860 1865 alias=[(b'format', b'aggressivemergedeltas')],
1861 1866 )
1862 1867 # experimental as long as rust is experimental (or a C version is implemented)
1863 1868 coreconfigitem(
1864 1869 b'storage',
1865 1870 b'revlog.persistent-nodemap.mmap',
1866 1871 default=True,
1867 1872 )
1868 1873 # experimental as long as format.use-persistent-nodemap is.
1869 1874 coreconfigitem(
1870 1875 b'storage',
1871 1876 b'revlog.persistent-nodemap.slow-path',
1872 1877 default=b"abort",
1873 1878 )
1874 1879
1875 1880 coreconfigitem(
1876 1881 b'storage',
1877 1882 b'revlog.reuse-external-delta',
1878 1883 default=True,
1879 1884 )
1880 1885 coreconfigitem(
1881 1886 b'storage',
1882 1887 b'revlog.reuse-external-delta-parent',
1883 1888 default=None,
1884 1889 )
1885 1890 coreconfigitem(
1886 1891 b'storage',
1887 1892 b'revlog.zlib.level',
1888 1893 default=None,
1889 1894 )
1890 1895 coreconfigitem(
1891 1896 b'storage',
1892 1897 b'revlog.zstd.level',
1893 1898 default=None,
1894 1899 )
1895 1900 coreconfigitem(
1896 1901 b'server',
1897 1902 b'bookmarks-pushkey-compat',
1898 1903 default=True,
1899 1904 )
1900 1905 coreconfigitem(
1901 1906 b'server',
1902 1907 b'bundle1',
1903 1908 default=True,
1904 1909 )
1905 1910 coreconfigitem(
1906 1911 b'server',
1907 1912 b'bundle1gd',
1908 1913 default=None,
1909 1914 )
1910 1915 coreconfigitem(
1911 1916 b'server',
1912 1917 b'bundle1.pull',
1913 1918 default=None,
1914 1919 )
1915 1920 coreconfigitem(
1916 1921 b'server',
1917 1922 b'bundle1gd.pull',
1918 1923 default=None,
1919 1924 )
1920 1925 coreconfigitem(
1921 1926 b'server',
1922 1927 b'bundle1.push',
1923 1928 default=None,
1924 1929 )
1925 1930 coreconfigitem(
1926 1931 b'server',
1927 1932 b'bundle1gd.push',
1928 1933 default=None,
1929 1934 )
1930 1935 coreconfigitem(
1931 1936 b'server',
1932 1937 b'bundle2.stream',
1933 1938 default=True,
1934 1939 alias=[(b'experimental', b'bundle2.stream')],
1935 1940 )
1936 1941 coreconfigitem(
1937 1942 b'server',
1938 1943 b'compressionengines',
1939 1944 default=list,
1940 1945 )
1941 1946 coreconfigitem(
1942 1947 b'server',
1943 1948 b'concurrent-push-mode',
1944 1949 default=b'check-related',
1945 1950 )
1946 1951 coreconfigitem(
1947 1952 b'server',
1948 1953 b'disablefullbundle',
1949 1954 default=False,
1950 1955 )
1951 1956 coreconfigitem(
1952 1957 b'server',
1953 1958 b'maxhttpheaderlen',
1954 1959 default=1024,
1955 1960 )
1956 1961 coreconfigitem(
1957 1962 b'server',
1958 1963 b'pullbundle',
1959 1964 default=False,
1960 1965 )
1961 1966 coreconfigitem(
1962 1967 b'server',
1963 1968 b'preferuncompressed',
1964 1969 default=False,
1965 1970 )
1966 1971 coreconfigitem(
1967 1972 b'server',
1968 1973 b'streamunbundle',
1969 1974 default=False,
1970 1975 )
1971 1976 coreconfigitem(
1972 1977 b'server',
1973 1978 b'uncompressed',
1974 1979 default=True,
1975 1980 )
1976 1981 coreconfigitem(
1977 1982 b'server',
1978 1983 b'uncompressedallowsecret',
1979 1984 default=False,
1980 1985 )
1981 1986 coreconfigitem(
1982 1987 b'server',
1983 1988 b'view',
1984 1989 default=b'served',
1985 1990 )
1986 1991 coreconfigitem(
1987 1992 b'server',
1988 1993 b'validate',
1989 1994 default=False,
1990 1995 )
1991 1996 coreconfigitem(
1992 1997 b'server',
1993 1998 b'zliblevel',
1994 1999 default=-1,
1995 2000 )
1996 2001 coreconfigitem(
1997 2002 b'server',
1998 2003 b'zstdlevel',
1999 2004 default=3,
2000 2005 )
2001 2006 coreconfigitem(
2002 2007 b'share',
2003 2008 b'pool',
2004 2009 default=None,
2005 2010 )
2006 2011 coreconfigitem(
2007 2012 b'share',
2008 2013 b'poolnaming',
2009 2014 default=b'identity',
2010 2015 )
2011 2016 coreconfigitem(
2012 2017 b'share',
2013 2018 b'safe-mismatch.source-not-safe',
2014 2019 default=b'abort',
2015 2020 )
2016 2021 coreconfigitem(
2017 2022 b'share',
2018 2023 b'safe-mismatch.source-safe',
2019 2024 default=b'abort',
2020 2025 )
2021 2026 coreconfigitem(
2022 2027 b'share',
2023 2028 b'safe-mismatch.source-not-safe.warn',
2024 2029 default=True,
2025 2030 )
2026 2031 coreconfigitem(
2027 2032 b'share',
2028 2033 b'safe-mismatch.source-safe.warn',
2029 2034 default=True,
2030 2035 )
2031 2036 coreconfigitem(
2032 2037 b'shelve',
2033 2038 b'maxbackups',
2034 2039 default=10,
2035 2040 )
2036 2041 coreconfigitem(
2037 2042 b'smtp',
2038 2043 b'host',
2039 2044 default=None,
2040 2045 )
2041 2046 coreconfigitem(
2042 2047 b'smtp',
2043 2048 b'local_hostname',
2044 2049 default=None,
2045 2050 )
2046 2051 coreconfigitem(
2047 2052 b'smtp',
2048 2053 b'password',
2049 2054 default=None,
2050 2055 )
2051 2056 coreconfigitem(
2052 2057 b'smtp',
2053 2058 b'port',
2054 2059 default=dynamicdefault,
2055 2060 )
2056 2061 coreconfigitem(
2057 2062 b'smtp',
2058 2063 b'tls',
2059 2064 default=b'none',
2060 2065 )
2061 2066 coreconfigitem(
2062 2067 b'smtp',
2063 2068 b'username',
2064 2069 default=None,
2065 2070 )
2066 2071 coreconfigitem(
2067 2072 b'sparse',
2068 2073 b'missingwarning',
2069 2074 default=True,
2070 2075 experimental=True,
2071 2076 )
2072 2077 coreconfigitem(
2073 2078 b'subrepos',
2074 2079 b'allowed',
2075 2080 default=dynamicdefault, # to make backporting simpler
2076 2081 )
2077 2082 coreconfigitem(
2078 2083 b'subrepos',
2079 2084 b'hg:allowed',
2080 2085 default=dynamicdefault,
2081 2086 )
2082 2087 coreconfigitem(
2083 2088 b'subrepos',
2084 2089 b'git:allowed',
2085 2090 default=dynamicdefault,
2086 2091 )
2087 2092 coreconfigitem(
2088 2093 b'subrepos',
2089 2094 b'svn:allowed',
2090 2095 default=dynamicdefault,
2091 2096 )
2092 2097 coreconfigitem(
2093 2098 b'templates',
2094 2099 b'.*',
2095 2100 default=None,
2096 2101 generic=True,
2097 2102 )
2098 2103 coreconfigitem(
2099 2104 b'templateconfig',
2100 2105 b'.*',
2101 2106 default=dynamicdefault,
2102 2107 generic=True,
2103 2108 )
2104 2109 coreconfigitem(
2105 2110 b'trusted',
2106 2111 b'groups',
2107 2112 default=list,
2108 2113 )
2109 2114 coreconfigitem(
2110 2115 b'trusted',
2111 2116 b'users',
2112 2117 default=list,
2113 2118 )
2114 2119 coreconfigitem(
2115 2120 b'ui',
2116 2121 b'_usedassubrepo',
2117 2122 default=False,
2118 2123 )
2119 2124 coreconfigitem(
2120 2125 b'ui',
2121 2126 b'allowemptycommit',
2122 2127 default=False,
2123 2128 )
2124 2129 coreconfigitem(
2125 2130 b'ui',
2126 2131 b'archivemeta',
2127 2132 default=True,
2128 2133 )
2129 2134 coreconfigitem(
2130 2135 b'ui',
2131 2136 b'askusername',
2132 2137 default=False,
2133 2138 )
2134 2139 coreconfigitem(
2135 2140 b'ui',
2136 2141 b'available-memory',
2137 2142 default=None,
2138 2143 )
2139 2144
2140 2145 coreconfigitem(
2141 2146 b'ui',
2142 2147 b'clonebundlefallback',
2143 2148 default=False,
2144 2149 )
2145 2150 coreconfigitem(
2146 2151 b'ui',
2147 2152 b'clonebundleprefers',
2148 2153 default=list,
2149 2154 )
2150 2155 coreconfigitem(
2151 2156 b'ui',
2152 2157 b'clonebundles',
2153 2158 default=True,
2154 2159 )
2155 2160 coreconfigitem(
2156 2161 b'ui',
2157 2162 b'color',
2158 2163 default=b'auto',
2159 2164 )
2160 2165 coreconfigitem(
2161 2166 b'ui',
2162 2167 b'commitsubrepos',
2163 2168 default=False,
2164 2169 )
2165 2170 coreconfigitem(
2166 2171 b'ui',
2167 2172 b'debug',
2168 2173 default=False,
2169 2174 )
2170 2175 coreconfigitem(
2171 2176 b'ui',
2172 2177 b'debugger',
2173 2178 default=None,
2174 2179 )
2175 2180 coreconfigitem(
2176 2181 b'ui',
2177 2182 b'editor',
2178 2183 default=dynamicdefault,
2179 2184 )
2180 2185 coreconfigitem(
2181 2186 b'ui',
2182 2187 b'detailed-exit-code',
2183 2188 default=False,
2184 2189 experimental=True,
2185 2190 )
2186 2191 coreconfigitem(
2187 2192 b'ui',
2188 2193 b'fallbackencoding',
2189 2194 default=None,
2190 2195 )
2191 2196 coreconfigitem(
2192 2197 b'ui',
2193 2198 b'forcecwd',
2194 2199 default=None,
2195 2200 )
2196 2201 coreconfigitem(
2197 2202 b'ui',
2198 2203 b'forcemerge',
2199 2204 default=None,
2200 2205 )
2201 2206 coreconfigitem(
2202 2207 b'ui',
2203 2208 b'formatdebug',
2204 2209 default=False,
2205 2210 )
2206 2211 coreconfigitem(
2207 2212 b'ui',
2208 2213 b'formatjson',
2209 2214 default=False,
2210 2215 )
2211 2216 coreconfigitem(
2212 2217 b'ui',
2213 2218 b'formatted',
2214 2219 default=None,
2215 2220 )
2216 2221 coreconfigitem(
2217 2222 b'ui',
2218 2223 b'interactive',
2219 2224 default=None,
2220 2225 )
2221 2226 coreconfigitem(
2222 2227 b'ui',
2223 2228 b'interface',
2224 2229 default=None,
2225 2230 )
2226 2231 coreconfigitem(
2227 2232 b'ui',
2228 2233 b'interface.chunkselector',
2229 2234 default=None,
2230 2235 )
2231 2236 coreconfigitem(
2232 2237 b'ui',
2233 2238 b'large-file-limit',
2234 2239 default=10000000,
2235 2240 )
2236 2241 coreconfigitem(
2237 2242 b'ui',
2238 2243 b'logblockedtimes',
2239 2244 default=False,
2240 2245 )
2241 2246 coreconfigitem(
2242 2247 b'ui',
2243 2248 b'merge',
2244 2249 default=None,
2245 2250 )
2246 2251 coreconfigitem(
2247 2252 b'ui',
2248 2253 b'mergemarkers',
2249 2254 default=b'basic',
2250 2255 )
2251 2256 coreconfigitem(
2252 2257 b'ui',
2253 2258 b'message-output',
2254 2259 default=b'stdio',
2255 2260 )
2256 2261 coreconfigitem(
2257 2262 b'ui',
2258 2263 b'nontty',
2259 2264 default=False,
2260 2265 )
2261 2266 coreconfigitem(
2262 2267 b'ui',
2263 2268 b'origbackuppath',
2264 2269 default=None,
2265 2270 )
2266 2271 coreconfigitem(
2267 2272 b'ui',
2268 2273 b'paginate',
2269 2274 default=True,
2270 2275 )
2271 2276 coreconfigitem(
2272 2277 b'ui',
2273 2278 b'patch',
2274 2279 default=None,
2275 2280 )
2276 2281 coreconfigitem(
2277 2282 b'ui',
2278 2283 b'portablefilenames',
2279 2284 default=b'warn',
2280 2285 )
2281 2286 coreconfigitem(
2282 2287 b'ui',
2283 2288 b'promptecho',
2284 2289 default=False,
2285 2290 )
2286 2291 coreconfigitem(
2287 2292 b'ui',
2288 2293 b'quiet',
2289 2294 default=False,
2290 2295 )
2291 2296 coreconfigitem(
2292 2297 b'ui',
2293 2298 b'quietbookmarkmove',
2294 2299 default=False,
2295 2300 )
2296 2301 coreconfigitem(
2297 2302 b'ui',
2298 2303 b'relative-paths',
2299 2304 default=b'legacy',
2300 2305 )
2301 2306 coreconfigitem(
2302 2307 b'ui',
2303 2308 b'remotecmd',
2304 2309 default=b'hg',
2305 2310 )
2306 2311 coreconfigitem(
2307 2312 b'ui',
2308 2313 b'report_untrusted',
2309 2314 default=True,
2310 2315 )
2311 2316 coreconfigitem(
2312 2317 b'ui',
2313 2318 b'rollback',
2314 2319 default=True,
2315 2320 )
2316 2321 coreconfigitem(
2317 2322 b'ui',
2318 2323 b'signal-safe-lock',
2319 2324 default=True,
2320 2325 )
2321 2326 coreconfigitem(
2322 2327 b'ui',
2323 2328 b'slash',
2324 2329 default=False,
2325 2330 )
2326 2331 coreconfigitem(
2327 2332 b'ui',
2328 2333 b'ssh',
2329 2334 default=b'ssh',
2330 2335 )
2331 2336 coreconfigitem(
2332 2337 b'ui',
2333 2338 b'ssherrorhint',
2334 2339 default=None,
2335 2340 )
2336 2341 coreconfigitem(
2337 2342 b'ui',
2338 2343 b'statuscopies',
2339 2344 default=False,
2340 2345 )
2341 2346 coreconfigitem(
2342 2347 b'ui',
2343 2348 b'strict',
2344 2349 default=False,
2345 2350 )
2346 2351 coreconfigitem(
2347 2352 b'ui',
2348 2353 b'style',
2349 2354 default=b'',
2350 2355 )
2351 2356 coreconfigitem(
2352 2357 b'ui',
2353 2358 b'supportcontact',
2354 2359 default=None,
2355 2360 )
2356 2361 coreconfigitem(
2357 2362 b'ui',
2358 2363 b'textwidth',
2359 2364 default=78,
2360 2365 )
2361 2366 coreconfigitem(
2362 2367 b'ui',
2363 2368 b'timeout',
2364 2369 default=b'600',
2365 2370 )
2366 2371 coreconfigitem(
2367 2372 b'ui',
2368 2373 b'timeout.warn',
2369 2374 default=0,
2370 2375 )
2371 2376 coreconfigitem(
2372 2377 b'ui',
2373 2378 b'timestamp-output',
2374 2379 default=False,
2375 2380 )
2376 2381 coreconfigitem(
2377 2382 b'ui',
2378 2383 b'traceback',
2379 2384 default=False,
2380 2385 )
2381 2386 coreconfigitem(
2382 2387 b'ui',
2383 2388 b'tweakdefaults',
2384 2389 default=False,
2385 2390 )
2386 2391 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2387 2392 coreconfigitem(
2388 2393 b'ui',
2389 2394 b'verbose',
2390 2395 default=False,
2391 2396 )
2392 2397 coreconfigitem(
2393 2398 b'verify',
2394 2399 b'skipflags',
2395 2400 default=None,
2396 2401 )
2397 2402 coreconfigitem(
2398 2403 b'web',
2399 2404 b'allowbz2',
2400 2405 default=False,
2401 2406 )
2402 2407 coreconfigitem(
2403 2408 b'web',
2404 2409 b'allowgz',
2405 2410 default=False,
2406 2411 )
2407 2412 coreconfigitem(
2408 2413 b'web',
2409 2414 b'allow-pull',
2410 2415 alias=[(b'web', b'allowpull')],
2411 2416 default=True,
2412 2417 )
2413 2418 coreconfigitem(
2414 2419 b'web',
2415 2420 b'allow-push',
2416 2421 alias=[(b'web', b'allow_push')],
2417 2422 default=list,
2418 2423 )
2419 2424 coreconfigitem(
2420 2425 b'web',
2421 2426 b'allowzip',
2422 2427 default=False,
2423 2428 )
2424 2429 coreconfigitem(
2425 2430 b'web',
2426 2431 b'archivesubrepos',
2427 2432 default=False,
2428 2433 )
2429 2434 coreconfigitem(
2430 2435 b'web',
2431 2436 b'cache',
2432 2437 default=True,
2433 2438 )
2434 2439 coreconfigitem(
2435 2440 b'web',
2436 2441 b'comparisoncontext',
2437 2442 default=5,
2438 2443 )
2439 2444 coreconfigitem(
2440 2445 b'web',
2441 2446 b'contact',
2442 2447 default=None,
2443 2448 )
2444 2449 coreconfigitem(
2445 2450 b'web',
2446 2451 b'deny_push',
2447 2452 default=list,
2448 2453 )
2449 2454 coreconfigitem(
2450 2455 b'web',
2451 2456 b'guessmime',
2452 2457 default=False,
2453 2458 )
2454 2459 coreconfigitem(
2455 2460 b'web',
2456 2461 b'hidden',
2457 2462 default=False,
2458 2463 )
2459 2464 coreconfigitem(
2460 2465 b'web',
2461 2466 b'labels',
2462 2467 default=list,
2463 2468 )
2464 2469 coreconfigitem(
2465 2470 b'web',
2466 2471 b'logoimg',
2467 2472 default=b'hglogo.png',
2468 2473 )
2469 2474 coreconfigitem(
2470 2475 b'web',
2471 2476 b'logourl',
2472 2477 default=b'https://mercurial-scm.org/',
2473 2478 )
2474 2479 coreconfigitem(
2475 2480 b'web',
2476 2481 b'accesslog',
2477 2482 default=b'-',
2478 2483 )
2479 2484 coreconfigitem(
2480 2485 b'web',
2481 2486 b'address',
2482 2487 default=b'',
2483 2488 )
2484 2489 coreconfigitem(
2485 2490 b'web',
2486 2491 b'allow-archive',
2487 2492 alias=[(b'web', b'allow_archive')],
2488 2493 default=list,
2489 2494 )
2490 2495 coreconfigitem(
2491 2496 b'web',
2492 2497 b'allow_read',
2493 2498 default=list,
2494 2499 )
2495 2500 coreconfigitem(
2496 2501 b'web',
2497 2502 b'baseurl',
2498 2503 default=None,
2499 2504 )
2500 2505 coreconfigitem(
2501 2506 b'web',
2502 2507 b'cacerts',
2503 2508 default=None,
2504 2509 )
2505 2510 coreconfigitem(
2506 2511 b'web',
2507 2512 b'certificate',
2508 2513 default=None,
2509 2514 )
2510 2515 coreconfigitem(
2511 2516 b'web',
2512 2517 b'collapse',
2513 2518 default=False,
2514 2519 )
2515 2520 coreconfigitem(
2516 2521 b'web',
2517 2522 b'csp',
2518 2523 default=None,
2519 2524 )
2520 2525 coreconfigitem(
2521 2526 b'web',
2522 2527 b'deny_read',
2523 2528 default=list,
2524 2529 )
2525 2530 coreconfigitem(
2526 2531 b'web',
2527 2532 b'descend',
2528 2533 default=True,
2529 2534 )
2530 2535 coreconfigitem(
2531 2536 b'web',
2532 2537 b'description',
2533 2538 default=b"",
2534 2539 )
2535 2540 coreconfigitem(
2536 2541 b'web',
2537 2542 b'encoding',
2538 2543 default=lambda: encoding.encoding,
2539 2544 )
2540 2545 coreconfigitem(
2541 2546 b'web',
2542 2547 b'errorlog',
2543 2548 default=b'-',
2544 2549 )
2545 2550 coreconfigitem(
2546 2551 b'web',
2547 2552 b'ipv6',
2548 2553 default=False,
2549 2554 )
2550 2555 coreconfigitem(
2551 2556 b'web',
2552 2557 b'maxchanges',
2553 2558 default=10,
2554 2559 )
2555 2560 coreconfigitem(
2556 2561 b'web',
2557 2562 b'maxfiles',
2558 2563 default=10,
2559 2564 )
2560 2565 coreconfigitem(
2561 2566 b'web',
2562 2567 b'maxshortchanges',
2563 2568 default=60,
2564 2569 )
2565 2570 coreconfigitem(
2566 2571 b'web',
2567 2572 b'motd',
2568 2573 default=b'',
2569 2574 )
2570 2575 coreconfigitem(
2571 2576 b'web',
2572 2577 b'name',
2573 2578 default=dynamicdefault,
2574 2579 )
2575 2580 coreconfigitem(
2576 2581 b'web',
2577 2582 b'port',
2578 2583 default=8000,
2579 2584 )
2580 2585 coreconfigitem(
2581 2586 b'web',
2582 2587 b'prefix',
2583 2588 default=b'',
2584 2589 )
2585 2590 coreconfigitem(
2586 2591 b'web',
2587 2592 b'push_ssl',
2588 2593 default=True,
2589 2594 )
2590 2595 coreconfigitem(
2591 2596 b'web',
2592 2597 b'refreshinterval',
2593 2598 default=20,
2594 2599 )
2595 2600 coreconfigitem(
2596 2601 b'web',
2597 2602 b'server-header',
2598 2603 default=None,
2599 2604 )
2600 2605 coreconfigitem(
2601 2606 b'web',
2602 2607 b'static',
2603 2608 default=None,
2604 2609 )
2605 2610 coreconfigitem(
2606 2611 b'web',
2607 2612 b'staticurl',
2608 2613 default=None,
2609 2614 )
2610 2615 coreconfigitem(
2611 2616 b'web',
2612 2617 b'stripes',
2613 2618 default=1,
2614 2619 )
2615 2620 coreconfigitem(
2616 2621 b'web',
2617 2622 b'style',
2618 2623 default=b'paper',
2619 2624 )
2620 2625 coreconfigitem(
2621 2626 b'web',
2622 2627 b'templates',
2623 2628 default=None,
2624 2629 )
2625 2630 coreconfigitem(
2626 2631 b'web',
2627 2632 b'view',
2628 2633 default=b'served',
2629 2634 experimental=True,
2630 2635 )
2631 2636 coreconfigitem(
2632 2637 b'worker',
2633 2638 b'backgroundclose',
2634 2639 default=dynamicdefault,
2635 2640 )
2636 2641 # Windows defaults to a limit of 512 open files. A buffer of 128
2637 2642 # should give us enough headway.
2638 2643 coreconfigitem(
2639 2644 b'worker',
2640 2645 b'backgroundclosemaxqueue',
2641 2646 default=384,
2642 2647 )
2643 2648 coreconfigitem(
2644 2649 b'worker',
2645 2650 b'backgroundcloseminfilecount',
2646 2651 default=2048,
2647 2652 )
2648 2653 coreconfigitem(
2649 2654 b'worker',
2650 2655 b'backgroundclosethreadcount',
2651 2656 default=4,
2652 2657 )
2653 2658 coreconfigitem(
2654 2659 b'worker',
2655 2660 b'enabled',
2656 2661 default=True,
2657 2662 )
2658 2663 coreconfigitem(
2659 2664 b'worker',
2660 2665 b'numcpus',
2661 2666 default=None,
2662 2667 )
2663 2668
2664 2669 # Rebase related configuration moved to core because other extension are doing
2665 2670 # strange things. For example, shelve import the extensions to reuse some bit
2666 2671 # without formally loading it.
2667 2672 coreconfigitem(
2668 2673 b'commands',
2669 2674 b'rebase.requiredest',
2670 2675 default=False,
2671 2676 )
2672 2677 coreconfigitem(
2673 2678 b'experimental',
2674 2679 b'rebaseskipobsolete',
2675 2680 default=True,
2676 2681 )
2677 2682 coreconfigitem(
2678 2683 b'rebase',
2679 2684 b'singletransaction',
2680 2685 default=False,
2681 2686 )
2682 2687 coreconfigitem(
2683 2688 b'rebase',
2684 2689 b'experimental.inmemory',
2685 2690 default=False,
2686 2691 )
General Comments 0
You need to be logged in to leave comments. Login now