##// END OF EJS Templates
bundle2: graduate bundle2.stream option from experimental to server section...
av6 -
r39757:1b588035 default
parent child Browse files
Show More
@@ -1,2268 +1,2268 b''
1 1 # bundle2.py - generic container format to transmit arbitrary data.
2 2 #
3 3 # Copyright 2013 Facebook, Inc.
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 """Handling of the new bundle2 format
8 8
9 9 The goal of bundle2 is to act as an atomically packet to transmit a set of
10 10 payloads in an application agnostic way. It consist in a sequence of "parts"
11 11 that will be handed to and processed by the application layer.
12 12
13 13
14 14 General format architecture
15 15 ===========================
16 16
17 17 The format is architectured as follow
18 18
19 19 - magic string
20 20 - stream level parameters
21 21 - payload parts (any number)
22 22 - end of stream marker.
23 23
24 24 the Binary format
25 25 ============================
26 26
27 27 All numbers are unsigned and big-endian.
28 28
29 29 stream level parameters
30 30 ------------------------
31 31
32 32 Binary format is as follow
33 33
34 34 :params size: int32
35 35
36 36 The total number of Bytes used by the parameters
37 37
38 38 :params value: arbitrary number of Bytes
39 39
40 40 A blob of `params size` containing the serialized version of all stream level
41 41 parameters.
42 42
43 43 The blob contains a space separated list of parameters. Parameters with value
44 44 are stored in the form `<name>=<value>`. Both name and value are urlquoted.
45 45
46 46 Empty name are obviously forbidden.
47 47
48 48 Name MUST start with a letter. If this first letter is lower case, the
49 49 parameter is advisory and can be safely ignored. However when the first
50 50 letter is capital, the parameter is mandatory and the bundling process MUST
51 51 stop if he is not able to proceed it.
52 52
53 53 Stream parameters use a simple textual format for two main reasons:
54 54
55 55 - Stream level parameters should remain simple and we want to discourage any
56 56 crazy usage.
57 57 - Textual data allow easy human inspection of a bundle2 header in case of
58 58 troubles.
59 59
60 60 Any Applicative level options MUST go into a bundle2 part instead.
61 61
62 62 Payload part
63 63 ------------------------
64 64
65 65 Binary format is as follow
66 66
67 67 :header size: int32
68 68
69 69 The total number of Bytes used by the part header. When the header is empty
70 70 (size = 0) this is interpreted as the end of stream marker.
71 71
72 72 :header:
73 73
74 74 The header defines how to interpret the part. It contains two piece of
75 75 data: the part type, and the part parameters.
76 76
77 77 The part type is used to route an application level handler, that can
78 78 interpret payload.
79 79
80 80 Part parameters are passed to the application level handler. They are
81 81 meant to convey information that will help the application level object to
82 82 interpret the part payload.
83 83
84 84 The binary format of the header is has follow
85 85
86 86 :typesize: (one byte)
87 87
88 88 :parttype: alphanumerical part name (restricted to [a-zA-Z0-9_:-]*)
89 89
90 90 :partid: A 32bits integer (unique in the bundle) that can be used to refer
91 91 to this part.
92 92
93 93 :parameters:
94 94
95 95 Part's parameter may have arbitrary content, the binary structure is::
96 96
97 97 <mandatory-count><advisory-count><param-sizes><param-data>
98 98
99 99 :mandatory-count: 1 byte, number of mandatory parameters
100 100
101 101 :advisory-count: 1 byte, number of advisory parameters
102 102
103 103 :param-sizes:
104 104
105 105 N couple of bytes, where N is the total number of parameters. Each
106 106 couple contains (<size-of-key>, <size-of-value) for one parameter.
107 107
108 108 :param-data:
109 109
110 110 A blob of bytes from which each parameter key and value can be
111 111 retrieved using the list of size couples stored in the previous
112 112 field.
113 113
114 114 Mandatory parameters comes first, then the advisory ones.
115 115
116 116 Each parameter's key MUST be unique within the part.
117 117
118 118 :payload:
119 119
120 120 payload is a series of `<chunksize><chunkdata>`.
121 121
122 122 `chunksize` is an int32, `chunkdata` are plain bytes (as much as
123 123 `chunksize` says)` The payload part is concluded by a zero size chunk.
124 124
125 125 The current implementation always produces either zero or one chunk.
126 126 This is an implementation limitation that will ultimately be lifted.
127 127
128 128 `chunksize` can be negative to trigger special case processing. No such
129 129 processing is in place yet.
130 130
131 131 Bundle processing
132 132 ============================
133 133
134 134 Each part is processed in order using a "part handler". Handler are registered
135 135 for a certain part type.
136 136
137 137 The matching of a part to its handler is case insensitive. The case of the
138 138 part type is used to know if a part is mandatory or advisory. If the Part type
139 139 contains any uppercase char it is considered mandatory. When no handler is
140 140 known for a Mandatory part, the process is aborted and an exception is raised.
141 141 If the part is advisory and no handler is known, the part is ignored. When the
142 142 process is aborted, the full bundle is still read from the stream to keep the
143 143 channel usable. But none of the part read from an abort are processed. In the
144 144 future, dropping the stream may become an option for channel we do not care to
145 145 preserve.
146 146 """
147 147
148 148 from __future__ import absolute_import, division
149 149
150 150 import collections
151 151 import errno
152 152 import os
153 153 import re
154 154 import string
155 155 import struct
156 156 import sys
157 157
158 158 from .i18n import _
159 159 from . import (
160 160 bookmarks,
161 161 changegroup,
162 162 encoding,
163 163 error,
164 164 node as nodemod,
165 165 obsolete,
166 166 phases,
167 167 pushkey,
168 168 pycompat,
169 169 streamclone,
170 170 tags,
171 171 url,
172 172 util,
173 173 )
174 174 from .utils import (
175 175 stringutil,
176 176 )
177 177
178 178 urlerr = util.urlerr
179 179 urlreq = util.urlreq
180 180
181 181 _pack = struct.pack
182 182 _unpack = struct.unpack
183 183
184 184 _fstreamparamsize = '>i'
185 185 _fpartheadersize = '>i'
186 186 _fparttypesize = '>B'
187 187 _fpartid = '>I'
188 188 _fpayloadsize = '>i'
189 189 _fpartparamcount = '>BB'
190 190
191 191 preferedchunksize = 32768
192 192
193 193 _parttypeforbidden = re.compile('[^a-zA-Z0-9_:-]')
194 194
195 195 def outdebug(ui, message):
196 196 """debug regarding output stream (bundling)"""
197 197 if ui.configbool('devel', 'bundle2.debug'):
198 198 ui.debug('bundle2-output: %s\n' % message)
199 199
200 200 def indebug(ui, message):
201 201 """debug on input stream (unbundling)"""
202 202 if ui.configbool('devel', 'bundle2.debug'):
203 203 ui.debug('bundle2-input: %s\n' % message)
204 204
205 205 def validateparttype(parttype):
206 206 """raise ValueError if a parttype contains invalid character"""
207 207 if _parttypeforbidden.search(parttype):
208 208 raise ValueError(parttype)
209 209
210 210 def _makefpartparamsizes(nbparams):
211 211 """return a struct format to read part parameter sizes
212 212
213 213 The number parameters is variable so we need to build that format
214 214 dynamically.
215 215 """
216 216 return '>'+('BB'*nbparams)
217 217
218 218 parthandlermapping = {}
219 219
220 220 def parthandler(parttype, params=()):
221 221 """decorator that register a function as a bundle2 part handler
222 222
223 223 eg::
224 224
225 225 @parthandler('myparttype', ('mandatory', 'param', 'handled'))
226 226 def myparttypehandler(...):
227 227 '''process a part of type "my part".'''
228 228 ...
229 229 """
230 230 validateparttype(parttype)
231 231 def _decorator(func):
232 232 lparttype = parttype.lower() # enforce lower case matching.
233 233 assert lparttype not in parthandlermapping
234 234 parthandlermapping[lparttype] = func
235 235 func.params = frozenset(params)
236 236 return func
237 237 return _decorator
238 238
239 239 class unbundlerecords(object):
240 240 """keep record of what happens during and unbundle
241 241
242 242 New records are added using `records.add('cat', obj)`. Where 'cat' is a
243 243 category of record and obj is an arbitrary object.
244 244
245 245 `records['cat']` will return all entries of this category 'cat'.
246 246
247 247 Iterating on the object itself will yield `('category', obj)` tuples
248 248 for all entries.
249 249
250 250 All iterations happens in chronological order.
251 251 """
252 252
253 253 def __init__(self):
254 254 self._categories = {}
255 255 self._sequences = []
256 256 self._replies = {}
257 257
258 258 def add(self, category, entry, inreplyto=None):
259 259 """add a new record of a given category.
260 260
261 261 The entry can then be retrieved in the list returned by
262 262 self['category']."""
263 263 self._categories.setdefault(category, []).append(entry)
264 264 self._sequences.append((category, entry))
265 265 if inreplyto is not None:
266 266 self.getreplies(inreplyto).add(category, entry)
267 267
268 268 def getreplies(self, partid):
269 269 """get the records that are replies to a specific part"""
270 270 return self._replies.setdefault(partid, unbundlerecords())
271 271
272 272 def __getitem__(self, cat):
273 273 return tuple(self._categories.get(cat, ()))
274 274
275 275 def __iter__(self):
276 276 return iter(self._sequences)
277 277
278 278 def __len__(self):
279 279 return len(self._sequences)
280 280
281 281 def __nonzero__(self):
282 282 return bool(self._sequences)
283 283
284 284 __bool__ = __nonzero__
285 285
286 286 class bundleoperation(object):
287 287 """an object that represents a single bundling process
288 288
289 289 Its purpose is to carry unbundle-related objects and states.
290 290
291 291 A new object should be created at the beginning of each bundle processing.
292 292 The object is to be returned by the processing function.
293 293
294 294 The object has very little content now it will ultimately contain:
295 295 * an access to the repo the bundle is applied to,
296 296 * a ui object,
297 297 * a way to retrieve a transaction to add changes to the repo,
298 298 * a way to record the result of processing each part,
299 299 * a way to construct a bundle response when applicable.
300 300 """
301 301
302 302 def __init__(self, repo, transactiongetter, captureoutput=True, source=''):
303 303 self.repo = repo
304 304 self.ui = repo.ui
305 305 self.records = unbundlerecords()
306 306 self.reply = None
307 307 self.captureoutput = captureoutput
308 308 self.hookargs = {}
309 309 self._gettransaction = transactiongetter
310 310 # carries value that can modify part behavior
311 311 self.modes = {}
312 312 self.source = source
313 313
314 314 def gettransaction(self):
315 315 transaction = self._gettransaction()
316 316
317 317 if self.hookargs:
318 318 # the ones added to the transaction supercede those added
319 319 # to the operation.
320 320 self.hookargs.update(transaction.hookargs)
321 321 transaction.hookargs = self.hookargs
322 322
323 323 # mark the hookargs as flushed. further attempts to add to
324 324 # hookargs will result in an abort.
325 325 self.hookargs = None
326 326
327 327 return transaction
328 328
329 329 def addhookargs(self, hookargs):
330 330 if self.hookargs is None:
331 331 raise error.ProgrammingError('attempted to add hookargs to '
332 332 'operation after transaction started')
333 333 self.hookargs.update(hookargs)
334 334
335 335 class TransactionUnavailable(RuntimeError):
336 336 pass
337 337
338 338 def _notransaction():
339 339 """default method to get a transaction while processing a bundle
340 340
341 341 Raise an exception to highlight the fact that no transaction was expected
342 342 to be created"""
343 343 raise TransactionUnavailable()
344 344
345 345 def applybundle(repo, unbundler, tr, source, url=None, **kwargs):
346 346 # transform me into unbundler.apply() as soon as the freeze is lifted
347 347 if isinstance(unbundler, unbundle20):
348 348 tr.hookargs['bundle2'] = '1'
349 349 if source is not None and 'source' not in tr.hookargs:
350 350 tr.hookargs['source'] = source
351 351 if url is not None and 'url' not in tr.hookargs:
352 352 tr.hookargs['url'] = url
353 353 return processbundle(repo, unbundler, lambda: tr, source=source)
354 354 else:
355 355 # the transactiongetter won't be used, but we might as well set it
356 356 op = bundleoperation(repo, lambda: tr, source=source)
357 357 _processchangegroup(op, unbundler, tr, source, url, **kwargs)
358 358 return op
359 359
360 360 class partiterator(object):
361 361 def __init__(self, repo, op, unbundler):
362 362 self.repo = repo
363 363 self.op = op
364 364 self.unbundler = unbundler
365 365 self.iterator = None
366 366 self.count = 0
367 367 self.current = None
368 368
369 369 def __enter__(self):
370 370 def func():
371 371 itr = enumerate(self.unbundler.iterparts())
372 372 for count, p in itr:
373 373 self.count = count
374 374 self.current = p
375 375 yield p
376 376 p.consume()
377 377 self.current = None
378 378 self.iterator = func()
379 379 return self.iterator
380 380
381 381 def __exit__(self, type, exc, tb):
382 382 if not self.iterator:
383 383 return
384 384
385 385 # Only gracefully abort in a normal exception situation. User aborts
386 386 # like Ctrl+C throw a KeyboardInterrupt which is not a base Exception,
387 387 # and should not gracefully cleanup.
388 388 if isinstance(exc, Exception):
389 389 # Any exceptions seeking to the end of the bundle at this point are
390 390 # almost certainly related to the underlying stream being bad.
391 391 # And, chances are that the exception we're handling is related to
392 392 # getting in that bad state. So, we swallow the seeking error and
393 393 # re-raise the original error.
394 394 seekerror = False
395 395 try:
396 396 if self.current:
397 397 # consume the part content to not corrupt the stream.
398 398 self.current.consume()
399 399
400 400 for part in self.iterator:
401 401 # consume the bundle content
402 402 part.consume()
403 403 except Exception:
404 404 seekerror = True
405 405
406 406 # Small hack to let caller code distinguish exceptions from bundle2
407 407 # processing from processing the old format. This is mostly needed
408 408 # to handle different return codes to unbundle according to the type
409 409 # of bundle. We should probably clean up or drop this return code
410 410 # craziness in a future version.
411 411 exc.duringunbundle2 = True
412 412 salvaged = []
413 413 replycaps = None
414 414 if self.op.reply is not None:
415 415 salvaged = self.op.reply.salvageoutput()
416 416 replycaps = self.op.reply.capabilities
417 417 exc._replycaps = replycaps
418 418 exc._bundle2salvagedoutput = salvaged
419 419
420 420 # Re-raising from a variable loses the original stack. So only use
421 421 # that form if we need to.
422 422 if seekerror:
423 423 raise exc
424 424
425 425 self.repo.ui.debug('bundle2-input-bundle: %i parts total\n' %
426 426 self.count)
427 427
428 428 def processbundle(repo, unbundler, transactiongetter=None, op=None, source=''):
429 429 """This function process a bundle, apply effect to/from a repo
430 430
431 431 It iterates over each part then searches for and uses the proper handling
432 432 code to process the part. Parts are processed in order.
433 433
434 434 Unknown Mandatory part will abort the process.
435 435
436 436 It is temporarily possible to provide a prebuilt bundleoperation to the
437 437 function. This is used to ensure output is properly propagated in case of
438 438 an error during the unbundling. This output capturing part will likely be
439 439 reworked and this ability will probably go away in the process.
440 440 """
441 441 if op is None:
442 442 if transactiongetter is None:
443 443 transactiongetter = _notransaction
444 444 op = bundleoperation(repo, transactiongetter, source=source)
445 445 # todo:
446 446 # - replace this is a init function soon.
447 447 # - exception catching
448 448 unbundler.params
449 449 if repo.ui.debugflag:
450 450 msg = ['bundle2-input-bundle:']
451 451 if unbundler.params:
452 452 msg.append(' %i params' % len(unbundler.params))
453 453 if op._gettransaction is None or op._gettransaction is _notransaction:
454 454 msg.append(' no-transaction')
455 455 else:
456 456 msg.append(' with-transaction')
457 457 msg.append('\n')
458 458 repo.ui.debug(''.join(msg))
459 459
460 460 processparts(repo, op, unbundler)
461 461
462 462 return op
463 463
464 464 def processparts(repo, op, unbundler):
465 465 with partiterator(repo, op, unbundler) as parts:
466 466 for part in parts:
467 467 _processpart(op, part)
468 468
469 469 def _processchangegroup(op, cg, tr, source, url, **kwargs):
470 470 ret = cg.apply(op.repo, tr, source, url, **kwargs)
471 471 op.records.add('changegroup', {
472 472 'return': ret,
473 473 })
474 474 return ret
475 475
476 476 def _gethandler(op, part):
477 477 status = 'unknown' # used by debug output
478 478 try:
479 479 handler = parthandlermapping.get(part.type)
480 480 if handler is None:
481 481 status = 'unsupported-type'
482 482 raise error.BundleUnknownFeatureError(parttype=part.type)
483 483 indebug(op.ui, 'found a handler for part %s' % part.type)
484 484 unknownparams = part.mandatorykeys - handler.params
485 485 if unknownparams:
486 486 unknownparams = list(unknownparams)
487 487 unknownparams.sort()
488 488 status = 'unsupported-params (%s)' % ', '.join(unknownparams)
489 489 raise error.BundleUnknownFeatureError(parttype=part.type,
490 490 params=unknownparams)
491 491 status = 'supported'
492 492 except error.BundleUnknownFeatureError as exc:
493 493 if part.mandatory: # mandatory parts
494 494 raise
495 495 indebug(op.ui, 'ignoring unsupported advisory part %s' % exc)
496 496 return # skip to part processing
497 497 finally:
498 498 if op.ui.debugflag:
499 499 msg = ['bundle2-input-part: "%s"' % part.type]
500 500 if not part.mandatory:
501 501 msg.append(' (advisory)')
502 502 nbmp = len(part.mandatorykeys)
503 503 nbap = len(part.params) - nbmp
504 504 if nbmp or nbap:
505 505 msg.append(' (params:')
506 506 if nbmp:
507 507 msg.append(' %i mandatory' % nbmp)
508 508 if nbap:
509 509 msg.append(' %i advisory' % nbmp)
510 510 msg.append(')')
511 511 msg.append(' %s\n' % status)
512 512 op.ui.debug(''.join(msg))
513 513
514 514 return handler
515 515
516 516 def _processpart(op, part):
517 517 """process a single part from a bundle
518 518
519 519 The part is guaranteed to have been fully consumed when the function exits
520 520 (even if an exception is raised)."""
521 521 handler = _gethandler(op, part)
522 522 if handler is None:
523 523 return
524 524
525 525 # handler is called outside the above try block so that we don't
526 526 # risk catching KeyErrors from anything other than the
527 527 # parthandlermapping lookup (any KeyError raised by handler()
528 528 # itself represents a defect of a different variety).
529 529 output = None
530 530 if op.captureoutput and op.reply is not None:
531 531 op.ui.pushbuffer(error=True, subproc=True)
532 532 output = ''
533 533 try:
534 534 handler(op, part)
535 535 finally:
536 536 if output is not None:
537 537 output = op.ui.popbuffer()
538 538 if output:
539 539 outpart = op.reply.newpart('output', data=output,
540 540 mandatory=False)
541 541 outpart.addparam(
542 542 'in-reply-to', pycompat.bytestr(part.id), mandatory=False)
543 543
544 544 def decodecaps(blob):
545 545 """decode a bundle2 caps bytes blob into a dictionary
546 546
547 547 The blob is a list of capabilities (one per line)
548 548 Capabilities may have values using a line of the form::
549 549
550 550 capability=value1,value2,value3
551 551
552 552 The values are always a list."""
553 553 caps = {}
554 554 for line in blob.splitlines():
555 555 if not line:
556 556 continue
557 557 if '=' not in line:
558 558 key, vals = line, ()
559 559 else:
560 560 key, vals = line.split('=', 1)
561 561 vals = vals.split(',')
562 562 key = urlreq.unquote(key)
563 563 vals = [urlreq.unquote(v) for v in vals]
564 564 caps[key] = vals
565 565 return caps
566 566
567 567 def encodecaps(caps):
568 568 """encode a bundle2 caps dictionary into a bytes blob"""
569 569 chunks = []
570 570 for ca in sorted(caps):
571 571 vals = caps[ca]
572 572 ca = urlreq.quote(ca)
573 573 vals = [urlreq.quote(v) for v in vals]
574 574 if vals:
575 575 ca = "%s=%s" % (ca, ','.join(vals))
576 576 chunks.append(ca)
577 577 return '\n'.join(chunks)
578 578
579 579 bundletypes = {
580 580 "": ("", 'UN'), # only when using unbundle on ssh and old http servers
581 581 # since the unification ssh accepts a header but there
582 582 # is no capability signaling it.
583 583 "HG20": (), # special-cased below
584 584 "HG10UN": ("HG10UN", 'UN'),
585 585 "HG10BZ": ("HG10", 'BZ'),
586 586 "HG10GZ": ("HG10GZ", 'GZ'),
587 587 }
588 588
589 589 # hgweb uses this list to communicate its preferred type
590 590 bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
591 591
592 592 class bundle20(object):
593 593 """represent an outgoing bundle2 container
594 594
595 595 Use the `addparam` method to add stream level parameter. and `newpart` to
596 596 populate it. Then call `getchunks` to retrieve all the binary chunks of
597 597 data that compose the bundle2 container."""
598 598
599 599 _magicstring = 'HG20'
600 600
601 601 def __init__(self, ui, capabilities=()):
602 602 self.ui = ui
603 603 self._params = []
604 604 self._parts = []
605 605 self.capabilities = dict(capabilities)
606 606 self._compengine = util.compengines.forbundletype('UN')
607 607 self._compopts = None
608 608 # If compression is being handled by a consumer of the raw
609 609 # data (e.g. the wire protocol), unsetting this flag tells
610 610 # consumers that the bundle is best left uncompressed.
611 611 self.prefercompressed = True
612 612
613 613 def setcompression(self, alg, compopts=None):
614 614 """setup core part compression to <alg>"""
615 615 if alg in (None, 'UN'):
616 616 return
617 617 assert not any(n.lower() == 'compression' for n, v in self._params)
618 618 self.addparam('Compression', alg)
619 619 self._compengine = util.compengines.forbundletype(alg)
620 620 self._compopts = compopts
621 621
622 622 @property
623 623 def nbparts(self):
624 624 """total number of parts added to the bundler"""
625 625 return len(self._parts)
626 626
627 627 # methods used to defines the bundle2 content
628 628 def addparam(self, name, value=None):
629 629 """add a stream level parameter"""
630 630 if not name:
631 631 raise error.ProgrammingError(b'empty parameter name')
632 632 if name[0:1] not in pycompat.bytestr(string.ascii_letters):
633 633 raise error.ProgrammingError(b'non letter first character: %s'
634 634 % name)
635 635 self._params.append((name, value))
636 636
637 637 def addpart(self, part):
638 638 """add a new part to the bundle2 container
639 639
640 640 Parts contains the actual applicative payload."""
641 641 assert part.id is None
642 642 part.id = len(self._parts) # very cheap counter
643 643 self._parts.append(part)
644 644
645 645 def newpart(self, typeid, *args, **kwargs):
646 646 """create a new part and add it to the containers
647 647
648 648 As the part is directly added to the containers. For now, this means
649 649 that any failure to properly initialize the part after calling
650 650 ``newpart`` should result in a failure of the whole bundling process.
651 651
652 652 You can still fall back to manually create and add if you need better
653 653 control."""
654 654 part = bundlepart(typeid, *args, **kwargs)
655 655 self.addpart(part)
656 656 return part
657 657
658 658 # methods used to generate the bundle2 stream
659 659 def getchunks(self):
660 660 if self.ui.debugflag:
661 661 msg = ['bundle2-output-bundle: "%s",' % self._magicstring]
662 662 if self._params:
663 663 msg.append(' (%i params)' % len(self._params))
664 664 msg.append(' %i parts total\n' % len(self._parts))
665 665 self.ui.debug(''.join(msg))
666 666 outdebug(self.ui, 'start emission of %s stream' % self._magicstring)
667 667 yield self._magicstring
668 668 param = self._paramchunk()
669 669 outdebug(self.ui, 'bundle parameter: %s' % param)
670 670 yield _pack(_fstreamparamsize, len(param))
671 671 if param:
672 672 yield param
673 673 for chunk in self._compengine.compressstream(self._getcorechunk(),
674 674 self._compopts):
675 675 yield chunk
676 676
677 677 def _paramchunk(self):
678 678 """return a encoded version of all stream parameters"""
679 679 blocks = []
680 680 for par, value in self._params:
681 681 par = urlreq.quote(par)
682 682 if value is not None:
683 683 value = urlreq.quote(value)
684 684 par = '%s=%s' % (par, value)
685 685 blocks.append(par)
686 686 return ' '.join(blocks)
687 687
688 688 def _getcorechunk(self):
689 689 """yield chunk for the core part of the bundle
690 690
691 691 (all but headers and parameters)"""
692 692 outdebug(self.ui, 'start of parts')
693 693 for part in self._parts:
694 694 outdebug(self.ui, 'bundle part: "%s"' % part.type)
695 695 for chunk in part.getchunks(ui=self.ui):
696 696 yield chunk
697 697 outdebug(self.ui, 'end of bundle')
698 698 yield _pack(_fpartheadersize, 0)
699 699
700 700
701 701 def salvageoutput(self):
702 702 """return a list with a copy of all output parts in the bundle
703 703
704 704 This is meant to be used during error handling to make sure we preserve
705 705 server output"""
706 706 salvaged = []
707 707 for part in self._parts:
708 708 if part.type.startswith('output'):
709 709 salvaged.append(part.copy())
710 710 return salvaged
711 711
712 712
713 713 class unpackermixin(object):
714 714 """A mixin to extract bytes and struct data from a stream"""
715 715
716 716 def __init__(self, fp):
717 717 self._fp = fp
718 718
719 719 def _unpack(self, format):
720 720 """unpack this struct format from the stream
721 721
722 722 This method is meant for internal usage by the bundle2 protocol only.
723 723 They directly manipulate the low level stream including bundle2 level
724 724 instruction.
725 725
726 726 Do not use it to implement higher-level logic or methods."""
727 727 data = self._readexact(struct.calcsize(format))
728 728 return _unpack(format, data)
729 729
730 730 def _readexact(self, size):
731 731 """read exactly <size> bytes from the stream
732 732
733 733 This method is meant for internal usage by the bundle2 protocol only.
734 734 They directly manipulate the low level stream including bundle2 level
735 735 instruction.
736 736
737 737 Do not use it to implement higher-level logic or methods."""
738 738 return changegroup.readexactly(self._fp, size)
739 739
740 740 def getunbundler(ui, fp, magicstring=None):
741 741 """return a valid unbundler object for a given magicstring"""
742 742 if magicstring is None:
743 743 magicstring = changegroup.readexactly(fp, 4)
744 744 magic, version = magicstring[0:2], magicstring[2:4]
745 745 if magic != 'HG':
746 746 ui.debug(
747 747 "error: invalid magic: %r (version %r), should be 'HG'\n"
748 748 % (magic, version))
749 749 raise error.Abort(_('not a Mercurial bundle'))
750 750 unbundlerclass = formatmap.get(version)
751 751 if unbundlerclass is None:
752 752 raise error.Abort(_('unknown bundle version %s') % version)
753 753 unbundler = unbundlerclass(ui, fp)
754 754 indebug(ui, 'start processing of %s stream' % magicstring)
755 755 return unbundler
756 756
757 757 class unbundle20(unpackermixin):
758 758 """interpret a bundle2 stream
759 759
760 760 This class is fed with a binary stream and yields parts through its
761 761 `iterparts` methods."""
762 762
763 763 _magicstring = 'HG20'
764 764
765 765 def __init__(self, ui, fp):
766 766 """If header is specified, we do not read it out of the stream."""
767 767 self.ui = ui
768 768 self._compengine = util.compengines.forbundletype('UN')
769 769 self._compressed = None
770 770 super(unbundle20, self).__init__(fp)
771 771
772 772 @util.propertycache
773 773 def params(self):
774 774 """dictionary of stream level parameters"""
775 775 indebug(self.ui, 'reading bundle2 stream parameters')
776 776 params = {}
777 777 paramssize = self._unpack(_fstreamparamsize)[0]
778 778 if paramssize < 0:
779 779 raise error.BundleValueError('negative bundle param size: %i'
780 780 % paramssize)
781 781 if paramssize:
782 782 params = self._readexact(paramssize)
783 783 params = self._processallparams(params)
784 784 return params
785 785
786 786 def _processallparams(self, paramsblock):
787 787 """"""
788 788 params = util.sortdict()
789 789 for p in paramsblock.split(' '):
790 790 p = p.split('=', 1)
791 791 p = [urlreq.unquote(i) for i in p]
792 792 if len(p) < 2:
793 793 p.append(None)
794 794 self._processparam(*p)
795 795 params[p[0]] = p[1]
796 796 return params
797 797
798 798
799 799 def _processparam(self, name, value):
800 800 """process a parameter, applying its effect if needed
801 801
802 802 Parameter starting with a lower case letter are advisory and will be
803 803 ignored when unknown. Those starting with an upper case letter are
804 804 mandatory and will this function will raise a KeyError when unknown.
805 805
806 806 Note: no option are currently supported. Any input will be either
807 807 ignored or failing.
808 808 """
809 809 if not name:
810 810 raise ValueError(r'empty parameter name')
811 811 if name[0:1] not in pycompat.bytestr(string.ascii_letters):
812 812 raise ValueError(r'non letter first character: %s' % name)
813 813 try:
814 814 handler = b2streamparamsmap[name.lower()]
815 815 except KeyError:
816 816 if name[0:1].islower():
817 817 indebug(self.ui, "ignoring unknown parameter %s" % name)
818 818 else:
819 819 raise error.BundleUnknownFeatureError(params=(name,))
820 820 else:
821 821 handler(self, name, value)
822 822
823 823 def _forwardchunks(self):
824 824 """utility to transfer a bundle2 as binary
825 825
826 826 This is made necessary by the fact the 'getbundle' command over 'ssh'
827 827 have no way to know then the reply end, relying on the bundle to be
828 828 interpreted to know its end. This is terrible and we are sorry, but we
829 829 needed to move forward to get general delta enabled.
830 830 """
831 831 yield self._magicstring
832 832 assert 'params' not in vars(self)
833 833 paramssize = self._unpack(_fstreamparamsize)[0]
834 834 if paramssize < 0:
835 835 raise error.BundleValueError('negative bundle param size: %i'
836 836 % paramssize)
837 837 yield _pack(_fstreamparamsize, paramssize)
838 838 if paramssize:
839 839 params = self._readexact(paramssize)
840 840 self._processallparams(params)
841 841 yield params
842 842 assert self._compengine.bundletype == 'UN'
843 843 # From there, payload might need to be decompressed
844 844 self._fp = self._compengine.decompressorreader(self._fp)
845 845 emptycount = 0
846 846 while emptycount < 2:
847 847 # so we can brainlessly loop
848 848 assert _fpartheadersize == _fpayloadsize
849 849 size = self._unpack(_fpartheadersize)[0]
850 850 yield _pack(_fpartheadersize, size)
851 851 if size:
852 852 emptycount = 0
853 853 else:
854 854 emptycount += 1
855 855 continue
856 856 if size == flaginterrupt:
857 857 continue
858 858 elif size < 0:
859 859 raise error.BundleValueError('negative chunk size: %i')
860 860 yield self._readexact(size)
861 861
862 862
863 863 def iterparts(self, seekable=False):
864 864 """yield all parts contained in the stream"""
865 865 cls = seekableunbundlepart if seekable else unbundlepart
866 866 # make sure param have been loaded
867 867 self.params
868 868 # From there, payload need to be decompressed
869 869 self._fp = self._compengine.decompressorreader(self._fp)
870 870 indebug(self.ui, 'start extraction of bundle2 parts')
871 871 headerblock = self._readpartheader()
872 872 while headerblock is not None:
873 873 part = cls(self.ui, headerblock, self._fp)
874 874 yield part
875 875 # Ensure part is fully consumed so we can start reading the next
876 876 # part.
877 877 part.consume()
878 878
879 879 headerblock = self._readpartheader()
880 880 indebug(self.ui, 'end of bundle2 stream')
881 881
882 882 def _readpartheader(self):
883 883 """reads a part header size and return the bytes blob
884 884
885 885 returns None if empty"""
886 886 headersize = self._unpack(_fpartheadersize)[0]
887 887 if headersize < 0:
888 888 raise error.BundleValueError('negative part header size: %i'
889 889 % headersize)
890 890 indebug(self.ui, 'part header size: %i' % headersize)
891 891 if headersize:
892 892 return self._readexact(headersize)
893 893 return None
894 894
895 895 def compressed(self):
896 896 self.params # load params
897 897 return self._compressed
898 898
899 899 def close(self):
900 900 """close underlying file"""
901 901 if util.safehasattr(self._fp, 'close'):
902 902 return self._fp.close()
903 903
904 904 formatmap = {'20': unbundle20}
905 905
906 906 b2streamparamsmap = {}
907 907
908 908 def b2streamparamhandler(name):
909 909 """register a handler for a stream level parameter"""
910 910 def decorator(func):
911 911 assert name not in formatmap
912 912 b2streamparamsmap[name] = func
913 913 return func
914 914 return decorator
915 915
916 916 @b2streamparamhandler('compression')
917 917 def processcompression(unbundler, param, value):
918 918 """read compression parameter and install payload decompression"""
919 919 if value not in util.compengines.supportedbundletypes:
920 920 raise error.BundleUnknownFeatureError(params=(param,),
921 921 values=(value,))
922 922 unbundler._compengine = util.compengines.forbundletype(value)
923 923 if value is not None:
924 924 unbundler._compressed = True
925 925
926 926 class bundlepart(object):
927 927 """A bundle2 part contains application level payload
928 928
929 929 The part `type` is used to route the part to the application level
930 930 handler.
931 931
932 932 The part payload is contained in ``part.data``. It could be raw bytes or a
933 933 generator of byte chunks.
934 934
935 935 You can add parameters to the part using the ``addparam`` method.
936 936 Parameters can be either mandatory (default) or advisory. Remote side
937 937 should be able to safely ignore the advisory ones.
938 938
939 939 Both data and parameters cannot be modified after the generation has begun.
940 940 """
941 941
942 942 def __init__(self, parttype, mandatoryparams=(), advisoryparams=(),
943 943 data='', mandatory=True):
944 944 validateparttype(parttype)
945 945 self.id = None
946 946 self.type = parttype
947 947 self._data = data
948 948 self._mandatoryparams = list(mandatoryparams)
949 949 self._advisoryparams = list(advisoryparams)
950 950 # checking for duplicated entries
951 951 self._seenparams = set()
952 952 for pname, __ in self._mandatoryparams + self._advisoryparams:
953 953 if pname in self._seenparams:
954 954 raise error.ProgrammingError('duplicated params: %s' % pname)
955 955 self._seenparams.add(pname)
956 956 # status of the part's generation:
957 957 # - None: not started,
958 958 # - False: currently generated,
959 959 # - True: generation done.
960 960 self._generated = None
961 961 self.mandatory = mandatory
962 962
963 963 def __repr__(self):
964 964 cls = "%s.%s" % (self.__class__.__module__, self.__class__.__name__)
965 965 return ('<%s object at %x; id: %s; type: %s; mandatory: %s>'
966 966 % (cls, id(self), self.id, self.type, self.mandatory))
967 967
968 968 def copy(self):
969 969 """return a copy of the part
970 970
971 971 The new part have the very same content but no partid assigned yet.
972 972 Parts with generated data cannot be copied."""
973 973 assert not util.safehasattr(self.data, 'next')
974 974 return self.__class__(self.type, self._mandatoryparams,
975 975 self._advisoryparams, self._data, self.mandatory)
976 976
977 977 # methods used to defines the part content
978 978 @property
979 979 def data(self):
980 980 return self._data
981 981
982 982 @data.setter
983 983 def data(self, data):
984 984 if self._generated is not None:
985 985 raise error.ReadOnlyPartError('part is being generated')
986 986 self._data = data
987 987
988 988 @property
989 989 def mandatoryparams(self):
990 990 # make it an immutable tuple to force people through ``addparam``
991 991 return tuple(self._mandatoryparams)
992 992
993 993 @property
994 994 def advisoryparams(self):
995 995 # make it an immutable tuple to force people through ``addparam``
996 996 return tuple(self._advisoryparams)
997 997
998 998 def addparam(self, name, value='', mandatory=True):
999 999 """add a parameter to the part
1000 1000
1001 1001 If 'mandatory' is set to True, the remote handler must claim support
1002 1002 for this parameter or the unbundling will be aborted.
1003 1003
1004 1004 The 'name' and 'value' cannot exceed 255 bytes each.
1005 1005 """
1006 1006 if self._generated is not None:
1007 1007 raise error.ReadOnlyPartError('part is being generated')
1008 1008 if name in self._seenparams:
1009 1009 raise ValueError('duplicated params: %s' % name)
1010 1010 self._seenparams.add(name)
1011 1011 params = self._advisoryparams
1012 1012 if mandatory:
1013 1013 params = self._mandatoryparams
1014 1014 params.append((name, value))
1015 1015
1016 1016 # methods used to generates the bundle2 stream
1017 1017 def getchunks(self, ui):
1018 1018 if self._generated is not None:
1019 1019 raise error.ProgrammingError('part can only be consumed once')
1020 1020 self._generated = False
1021 1021
1022 1022 if ui.debugflag:
1023 1023 msg = ['bundle2-output-part: "%s"' % self.type]
1024 1024 if not self.mandatory:
1025 1025 msg.append(' (advisory)')
1026 1026 nbmp = len(self.mandatoryparams)
1027 1027 nbap = len(self.advisoryparams)
1028 1028 if nbmp or nbap:
1029 1029 msg.append(' (params:')
1030 1030 if nbmp:
1031 1031 msg.append(' %i mandatory' % nbmp)
1032 1032 if nbap:
1033 1033 msg.append(' %i advisory' % nbmp)
1034 1034 msg.append(')')
1035 1035 if not self.data:
1036 1036 msg.append(' empty payload')
1037 1037 elif (util.safehasattr(self.data, 'next')
1038 1038 or util.safehasattr(self.data, '__next__')):
1039 1039 msg.append(' streamed payload')
1040 1040 else:
1041 1041 msg.append(' %i bytes payload' % len(self.data))
1042 1042 msg.append('\n')
1043 1043 ui.debug(''.join(msg))
1044 1044
1045 1045 #### header
1046 1046 if self.mandatory:
1047 1047 parttype = self.type.upper()
1048 1048 else:
1049 1049 parttype = self.type.lower()
1050 1050 outdebug(ui, 'part %s: "%s"' % (pycompat.bytestr(self.id), parttype))
1051 1051 ## parttype
1052 1052 header = [_pack(_fparttypesize, len(parttype)),
1053 1053 parttype, _pack(_fpartid, self.id),
1054 1054 ]
1055 1055 ## parameters
1056 1056 # count
1057 1057 manpar = self.mandatoryparams
1058 1058 advpar = self.advisoryparams
1059 1059 header.append(_pack(_fpartparamcount, len(manpar), len(advpar)))
1060 1060 # size
1061 1061 parsizes = []
1062 1062 for key, value in manpar:
1063 1063 parsizes.append(len(key))
1064 1064 parsizes.append(len(value))
1065 1065 for key, value in advpar:
1066 1066 parsizes.append(len(key))
1067 1067 parsizes.append(len(value))
1068 1068 paramsizes = _pack(_makefpartparamsizes(len(parsizes) // 2), *parsizes)
1069 1069 header.append(paramsizes)
1070 1070 # key, value
1071 1071 for key, value in manpar:
1072 1072 header.append(key)
1073 1073 header.append(value)
1074 1074 for key, value in advpar:
1075 1075 header.append(key)
1076 1076 header.append(value)
1077 1077 ## finalize header
1078 1078 try:
1079 1079 headerchunk = ''.join(header)
1080 1080 except TypeError:
1081 1081 raise TypeError(r'Found a non-bytes trying to '
1082 1082 r'build bundle part header: %r' % header)
1083 1083 outdebug(ui, 'header chunk size: %i' % len(headerchunk))
1084 1084 yield _pack(_fpartheadersize, len(headerchunk))
1085 1085 yield headerchunk
1086 1086 ## payload
1087 1087 try:
1088 1088 for chunk in self._payloadchunks():
1089 1089 outdebug(ui, 'payload chunk size: %i' % len(chunk))
1090 1090 yield _pack(_fpayloadsize, len(chunk))
1091 1091 yield chunk
1092 1092 except GeneratorExit:
1093 1093 # GeneratorExit means that nobody is listening for our
1094 1094 # results anyway, so just bail quickly rather than trying
1095 1095 # to produce an error part.
1096 1096 ui.debug('bundle2-generatorexit\n')
1097 1097 raise
1098 1098 except BaseException as exc:
1099 1099 bexc = stringutil.forcebytestr(exc)
1100 1100 # backup exception data for later
1101 1101 ui.debug('bundle2-input-stream-interrupt: encoding exception %s'
1102 1102 % bexc)
1103 1103 tb = sys.exc_info()[2]
1104 1104 msg = 'unexpected error: %s' % bexc
1105 1105 interpart = bundlepart('error:abort', [('message', msg)],
1106 1106 mandatory=False)
1107 1107 interpart.id = 0
1108 1108 yield _pack(_fpayloadsize, -1)
1109 1109 for chunk in interpart.getchunks(ui=ui):
1110 1110 yield chunk
1111 1111 outdebug(ui, 'closing payload chunk')
1112 1112 # abort current part payload
1113 1113 yield _pack(_fpayloadsize, 0)
1114 1114 pycompat.raisewithtb(exc, tb)
1115 1115 # end of payload
1116 1116 outdebug(ui, 'closing payload chunk')
1117 1117 yield _pack(_fpayloadsize, 0)
1118 1118 self._generated = True
1119 1119
1120 1120 def _payloadchunks(self):
1121 1121 """yield chunks of a the part payload
1122 1122
1123 1123 Exists to handle the different methods to provide data to a part."""
1124 1124 # we only support fixed size data now.
1125 1125 # This will be improved in the future.
1126 1126 if (util.safehasattr(self.data, 'next')
1127 1127 or util.safehasattr(self.data, '__next__')):
1128 1128 buff = util.chunkbuffer(self.data)
1129 1129 chunk = buff.read(preferedchunksize)
1130 1130 while chunk:
1131 1131 yield chunk
1132 1132 chunk = buff.read(preferedchunksize)
1133 1133 elif len(self.data):
1134 1134 yield self.data
1135 1135
1136 1136
1137 1137 flaginterrupt = -1
1138 1138
1139 1139 class interrupthandler(unpackermixin):
1140 1140 """read one part and process it with restricted capability
1141 1141
1142 1142 This allows to transmit exception raised on the producer size during part
1143 1143 iteration while the consumer is reading a part.
1144 1144
1145 1145 Part processed in this manner only have access to a ui object,"""
1146 1146
1147 1147 def __init__(self, ui, fp):
1148 1148 super(interrupthandler, self).__init__(fp)
1149 1149 self.ui = ui
1150 1150
1151 1151 def _readpartheader(self):
1152 1152 """reads a part header size and return the bytes blob
1153 1153
1154 1154 returns None if empty"""
1155 1155 headersize = self._unpack(_fpartheadersize)[0]
1156 1156 if headersize < 0:
1157 1157 raise error.BundleValueError('negative part header size: %i'
1158 1158 % headersize)
1159 1159 indebug(self.ui, 'part header size: %i\n' % headersize)
1160 1160 if headersize:
1161 1161 return self._readexact(headersize)
1162 1162 return None
1163 1163
1164 1164 def __call__(self):
1165 1165
1166 1166 self.ui.debug('bundle2-input-stream-interrupt:'
1167 1167 ' opening out of band context\n')
1168 1168 indebug(self.ui, 'bundle2 stream interruption, looking for a part.')
1169 1169 headerblock = self._readpartheader()
1170 1170 if headerblock is None:
1171 1171 indebug(self.ui, 'no part found during interruption.')
1172 1172 return
1173 1173 part = unbundlepart(self.ui, headerblock, self._fp)
1174 1174 op = interruptoperation(self.ui)
1175 1175 hardabort = False
1176 1176 try:
1177 1177 _processpart(op, part)
1178 1178 except (SystemExit, KeyboardInterrupt):
1179 1179 hardabort = True
1180 1180 raise
1181 1181 finally:
1182 1182 if not hardabort:
1183 1183 part.consume()
1184 1184 self.ui.debug('bundle2-input-stream-interrupt:'
1185 1185 ' closing out of band context\n')
1186 1186
1187 1187 class interruptoperation(object):
1188 1188 """A limited operation to be use by part handler during interruption
1189 1189
1190 1190 It only have access to an ui object.
1191 1191 """
1192 1192
1193 1193 def __init__(self, ui):
1194 1194 self.ui = ui
1195 1195 self.reply = None
1196 1196 self.captureoutput = False
1197 1197
1198 1198 @property
1199 1199 def repo(self):
1200 1200 raise error.ProgrammingError('no repo access from stream interruption')
1201 1201
1202 1202 def gettransaction(self):
1203 1203 raise TransactionUnavailable('no repo access from stream interruption')
1204 1204
1205 1205 def decodepayloadchunks(ui, fh):
1206 1206 """Reads bundle2 part payload data into chunks.
1207 1207
1208 1208 Part payload data consists of framed chunks. This function takes
1209 1209 a file handle and emits those chunks.
1210 1210 """
1211 1211 dolog = ui.configbool('devel', 'bundle2.debug')
1212 1212 debug = ui.debug
1213 1213
1214 1214 headerstruct = struct.Struct(_fpayloadsize)
1215 1215 headersize = headerstruct.size
1216 1216 unpack = headerstruct.unpack
1217 1217
1218 1218 readexactly = changegroup.readexactly
1219 1219 read = fh.read
1220 1220
1221 1221 chunksize = unpack(readexactly(fh, headersize))[0]
1222 1222 indebug(ui, 'payload chunk size: %i' % chunksize)
1223 1223
1224 1224 # changegroup.readexactly() is inlined below for performance.
1225 1225 while chunksize:
1226 1226 if chunksize >= 0:
1227 1227 s = read(chunksize)
1228 1228 if len(s) < chunksize:
1229 1229 raise error.Abort(_('stream ended unexpectedly '
1230 1230 ' (got %d bytes, expected %d)') %
1231 1231 (len(s), chunksize))
1232 1232
1233 1233 yield s
1234 1234 elif chunksize == flaginterrupt:
1235 1235 # Interrupt "signal" detected. The regular stream is interrupted
1236 1236 # and a bundle2 part follows. Consume it.
1237 1237 interrupthandler(ui, fh)()
1238 1238 else:
1239 1239 raise error.BundleValueError(
1240 1240 'negative payload chunk size: %s' % chunksize)
1241 1241
1242 1242 s = read(headersize)
1243 1243 if len(s) < headersize:
1244 1244 raise error.Abort(_('stream ended unexpectedly '
1245 1245 ' (got %d bytes, expected %d)') %
1246 1246 (len(s), chunksize))
1247 1247
1248 1248 chunksize = unpack(s)[0]
1249 1249
1250 1250 # indebug() inlined for performance.
1251 1251 if dolog:
1252 1252 debug('bundle2-input: payload chunk size: %i\n' % chunksize)
1253 1253
1254 1254 class unbundlepart(unpackermixin):
1255 1255 """a bundle part read from a bundle"""
1256 1256
1257 1257 def __init__(self, ui, header, fp):
1258 1258 super(unbundlepart, self).__init__(fp)
1259 1259 self._seekable = (util.safehasattr(fp, 'seek') and
1260 1260 util.safehasattr(fp, 'tell'))
1261 1261 self.ui = ui
1262 1262 # unbundle state attr
1263 1263 self._headerdata = header
1264 1264 self._headeroffset = 0
1265 1265 self._initialized = False
1266 1266 self.consumed = False
1267 1267 # part data
1268 1268 self.id = None
1269 1269 self.type = None
1270 1270 self.mandatoryparams = None
1271 1271 self.advisoryparams = None
1272 1272 self.params = None
1273 1273 self.mandatorykeys = ()
1274 1274 self._readheader()
1275 1275 self._mandatory = None
1276 1276 self._pos = 0
1277 1277
1278 1278 def _fromheader(self, size):
1279 1279 """return the next <size> byte from the header"""
1280 1280 offset = self._headeroffset
1281 1281 data = self._headerdata[offset:(offset + size)]
1282 1282 self._headeroffset = offset + size
1283 1283 return data
1284 1284
1285 1285 def _unpackheader(self, format):
1286 1286 """read given format from header
1287 1287
1288 1288 This automatically compute the size of the format to read."""
1289 1289 data = self._fromheader(struct.calcsize(format))
1290 1290 return _unpack(format, data)
1291 1291
1292 1292 def _initparams(self, mandatoryparams, advisoryparams):
1293 1293 """internal function to setup all logic related parameters"""
1294 1294 # make it read only to prevent people touching it by mistake.
1295 1295 self.mandatoryparams = tuple(mandatoryparams)
1296 1296 self.advisoryparams = tuple(advisoryparams)
1297 1297 # user friendly UI
1298 1298 self.params = util.sortdict(self.mandatoryparams)
1299 1299 self.params.update(self.advisoryparams)
1300 1300 self.mandatorykeys = frozenset(p[0] for p in mandatoryparams)
1301 1301
1302 1302 def _readheader(self):
1303 1303 """read the header and setup the object"""
1304 1304 typesize = self._unpackheader(_fparttypesize)[0]
1305 1305 self.type = self._fromheader(typesize)
1306 1306 indebug(self.ui, 'part type: "%s"' % self.type)
1307 1307 self.id = self._unpackheader(_fpartid)[0]
1308 1308 indebug(self.ui, 'part id: "%s"' % pycompat.bytestr(self.id))
1309 1309 # extract mandatory bit from type
1310 1310 self.mandatory = (self.type != self.type.lower())
1311 1311 self.type = self.type.lower()
1312 1312 ## reading parameters
1313 1313 # param count
1314 1314 mancount, advcount = self._unpackheader(_fpartparamcount)
1315 1315 indebug(self.ui, 'part parameters: %i' % (mancount + advcount))
1316 1316 # param size
1317 1317 fparamsizes = _makefpartparamsizes(mancount + advcount)
1318 1318 paramsizes = self._unpackheader(fparamsizes)
1319 1319 # make it a list of couple again
1320 1320 paramsizes = list(zip(paramsizes[::2], paramsizes[1::2]))
1321 1321 # split mandatory from advisory
1322 1322 mansizes = paramsizes[:mancount]
1323 1323 advsizes = paramsizes[mancount:]
1324 1324 # retrieve param value
1325 1325 manparams = []
1326 1326 for key, value in mansizes:
1327 1327 manparams.append((self._fromheader(key), self._fromheader(value)))
1328 1328 advparams = []
1329 1329 for key, value in advsizes:
1330 1330 advparams.append((self._fromheader(key), self._fromheader(value)))
1331 1331 self._initparams(manparams, advparams)
1332 1332 ## part payload
1333 1333 self._payloadstream = util.chunkbuffer(self._payloadchunks())
1334 1334 # we read the data, tell it
1335 1335 self._initialized = True
1336 1336
1337 1337 def _payloadchunks(self):
1338 1338 """Generator of decoded chunks in the payload."""
1339 1339 return decodepayloadchunks(self.ui, self._fp)
1340 1340
1341 1341 def consume(self):
1342 1342 """Read the part payload until completion.
1343 1343
1344 1344 By consuming the part data, the underlying stream read offset will
1345 1345 be advanced to the next part (or end of stream).
1346 1346 """
1347 1347 if self.consumed:
1348 1348 return
1349 1349
1350 1350 chunk = self.read(32768)
1351 1351 while chunk:
1352 1352 self._pos += len(chunk)
1353 1353 chunk = self.read(32768)
1354 1354
1355 1355 def read(self, size=None):
1356 1356 """read payload data"""
1357 1357 if not self._initialized:
1358 1358 self._readheader()
1359 1359 if size is None:
1360 1360 data = self._payloadstream.read()
1361 1361 else:
1362 1362 data = self._payloadstream.read(size)
1363 1363 self._pos += len(data)
1364 1364 if size is None or len(data) < size:
1365 1365 if not self.consumed and self._pos:
1366 1366 self.ui.debug('bundle2-input-part: total payload size %i\n'
1367 1367 % self._pos)
1368 1368 self.consumed = True
1369 1369 return data
1370 1370
1371 1371 class seekableunbundlepart(unbundlepart):
1372 1372 """A bundle2 part in a bundle that is seekable.
1373 1373
1374 1374 Regular ``unbundlepart`` instances can only be read once. This class
1375 1375 extends ``unbundlepart`` to enable bi-directional seeking within the
1376 1376 part.
1377 1377
1378 1378 Bundle2 part data consists of framed chunks. Offsets when seeking
1379 1379 refer to the decoded data, not the offsets in the underlying bundle2
1380 1380 stream.
1381 1381
1382 1382 To facilitate quickly seeking within the decoded data, instances of this
1383 1383 class maintain a mapping between offsets in the underlying stream and
1384 1384 the decoded payload. This mapping will consume memory in proportion
1385 1385 to the number of chunks within the payload (which almost certainly
1386 1386 increases in proportion with the size of the part).
1387 1387 """
1388 1388 def __init__(self, ui, header, fp):
1389 1389 # (payload, file) offsets for chunk starts.
1390 1390 self._chunkindex = []
1391 1391
1392 1392 super(seekableunbundlepart, self).__init__(ui, header, fp)
1393 1393
1394 1394 def _payloadchunks(self, chunknum=0):
1395 1395 '''seek to specified chunk and start yielding data'''
1396 1396 if len(self._chunkindex) == 0:
1397 1397 assert chunknum == 0, 'Must start with chunk 0'
1398 1398 self._chunkindex.append((0, self._tellfp()))
1399 1399 else:
1400 1400 assert chunknum < len(self._chunkindex), \
1401 1401 'Unknown chunk %d' % chunknum
1402 1402 self._seekfp(self._chunkindex[chunknum][1])
1403 1403
1404 1404 pos = self._chunkindex[chunknum][0]
1405 1405
1406 1406 for chunk in decodepayloadchunks(self.ui, self._fp):
1407 1407 chunknum += 1
1408 1408 pos += len(chunk)
1409 1409 if chunknum == len(self._chunkindex):
1410 1410 self._chunkindex.append((pos, self._tellfp()))
1411 1411
1412 1412 yield chunk
1413 1413
1414 1414 def _findchunk(self, pos):
1415 1415 '''for a given payload position, return a chunk number and offset'''
1416 1416 for chunk, (ppos, fpos) in enumerate(self._chunkindex):
1417 1417 if ppos == pos:
1418 1418 return chunk, 0
1419 1419 elif ppos > pos:
1420 1420 return chunk - 1, pos - self._chunkindex[chunk - 1][0]
1421 1421 raise ValueError('Unknown chunk')
1422 1422
1423 1423 def tell(self):
1424 1424 return self._pos
1425 1425
1426 1426 def seek(self, offset, whence=os.SEEK_SET):
1427 1427 if whence == os.SEEK_SET:
1428 1428 newpos = offset
1429 1429 elif whence == os.SEEK_CUR:
1430 1430 newpos = self._pos + offset
1431 1431 elif whence == os.SEEK_END:
1432 1432 if not self.consumed:
1433 1433 # Can't use self.consume() here because it advances self._pos.
1434 1434 chunk = self.read(32768)
1435 1435 while chunk:
1436 1436 chunk = self.read(32768)
1437 1437 newpos = self._chunkindex[-1][0] - offset
1438 1438 else:
1439 1439 raise ValueError('Unknown whence value: %r' % (whence,))
1440 1440
1441 1441 if newpos > self._chunkindex[-1][0] and not self.consumed:
1442 1442 # Can't use self.consume() here because it advances self._pos.
1443 1443 chunk = self.read(32768)
1444 1444 while chunk:
1445 1445 chunk = self.read(32668)
1446 1446
1447 1447 if not 0 <= newpos <= self._chunkindex[-1][0]:
1448 1448 raise ValueError('Offset out of range')
1449 1449
1450 1450 if self._pos != newpos:
1451 1451 chunk, internaloffset = self._findchunk(newpos)
1452 1452 self._payloadstream = util.chunkbuffer(self._payloadchunks(chunk))
1453 1453 adjust = self.read(internaloffset)
1454 1454 if len(adjust) != internaloffset:
1455 1455 raise error.Abort(_('Seek failed\n'))
1456 1456 self._pos = newpos
1457 1457
1458 1458 def _seekfp(self, offset, whence=0):
1459 1459 """move the underlying file pointer
1460 1460
1461 1461 This method is meant for internal usage by the bundle2 protocol only.
1462 1462 They directly manipulate the low level stream including bundle2 level
1463 1463 instruction.
1464 1464
1465 1465 Do not use it to implement higher-level logic or methods."""
1466 1466 if self._seekable:
1467 1467 return self._fp.seek(offset, whence)
1468 1468 else:
1469 1469 raise NotImplementedError(_('File pointer is not seekable'))
1470 1470
1471 1471 def _tellfp(self):
1472 1472 """return the file offset, or None if file is not seekable
1473 1473
1474 1474 This method is meant for internal usage by the bundle2 protocol only.
1475 1475 They directly manipulate the low level stream including bundle2 level
1476 1476 instruction.
1477 1477
1478 1478 Do not use it to implement higher-level logic or methods."""
1479 1479 if self._seekable:
1480 1480 try:
1481 1481 return self._fp.tell()
1482 1482 except IOError as e:
1483 1483 if e.errno == errno.ESPIPE:
1484 1484 self._seekable = False
1485 1485 else:
1486 1486 raise
1487 1487 return None
1488 1488
1489 1489 # These are only the static capabilities.
1490 1490 # Check the 'getrepocaps' function for the rest.
1491 1491 capabilities = {'HG20': (),
1492 1492 'bookmarks': (),
1493 1493 'error': ('abort', 'unsupportedcontent', 'pushraced',
1494 1494 'pushkey'),
1495 1495 'listkeys': (),
1496 1496 'pushkey': (),
1497 1497 'digests': tuple(sorted(util.DIGESTS.keys())),
1498 1498 'remote-changegroup': ('http', 'https'),
1499 1499 'hgtagsfnodes': (),
1500 1500 'rev-branch-cache': (),
1501 1501 'phases': ('heads',),
1502 1502 'stream': ('v2',),
1503 1503 }
1504 1504
1505 1505 def getrepocaps(repo, allowpushback=False, role=None):
1506 1506 """return the bundle2 capabilities for a given repo
1507 1507
1508 1508 Exists to allow extensions (like evolution) to mutate the capabilities.
1509 1509
1510 1510 The returned value is used for servers advertising their capabilities as
1511 1511 well as clients advertising their capabilities to servers as part of
1512 1512 bundle2 requests. The ``role`` argument specifies which is which.
1513 1513 """
1514 1514 if role not in ('client', 'server'):
1515 1515 raise error.ProgrammingError('role argument must be client or server')
1516 1516
1517 1517 caps = capabilities.copy()
1518 1518 caps['changegroup'] = tuple(sorted(
1519 1519 changegroup.supportedincomingversions(repo)))
1520 1520 if obsolete.isenabled(repo, obsolete.exchangeopt):
1521 1521 supportedformat = tuple('V%i' % v for v in obsolete.formats)
1522 1522 caps['obsmarkers'] = supportedformat
1523 1523 if allowpushback:
1524 1524 caps['pushback'] = ()
1525 1525 cpmode = repo.ui.config('server', 'concurrent-push-mode')
1526 1526 if cpmode == 'check-related':
1527 1527 caps['checkheads'] = ('related',)
1528 1528 if 'phases' in repo.ui.configlist('devel', 'legacy.exchange'):
1529 1529 caps.pop('phases')
1530 1530
1531 1531 # Don't advertise stream clone support in server mode if not configured.
1532 1532 if role == 'server':
1533 1533 streamsupported = repo.ui.configbool('server', 'uncompressed',
1534 1534 untrusted=True)
1535 featuresupported = repo.ui.configbool('experimental', 'bundle2.stream')
1535 featuresupported = repo.ui.configbool('server', 'bundle2.stream')
1536 1536
1537 1537 if not streamsupported or not featuresupported:
1538 1538 caps.pop('stream')
1539 1539 # Else always advertise support on client, because payload support
1540 1540 # should always be advertised.
1541 1541
1542 1542 return caps
1543 1543
1544 1544 def bundle2caps(remote):
1545 1545 """return the bundle capabilities of a peer as dict"""
1546 1546 raw = remote.capable('bundle2')
1547 1547 if not raw and raw != '':
1548 1548 return {}
1549 1549 capsblob = urlreq.unquote(remote.capable('bundle2'))
1550 1550 return decodecaps(capsblob)
1551 1551
1552 1552 def obsmarkersversion(caps):
1553 1553 """extract the list of supported obsmarkers versions from a bundle2caps dict
1554 1554 """
1555 1555 obscaps = caps.get('obsmarkers', ())
1556 1556 return [int(c[1:]) for c in obscaps if c.startswith('V')]
1557 1557
1558 1558 def writenewbundle(ui, repo, source, filename, bundletype, outgoing, opts,
1559 1559 vfs=None, compression=None, compopts=None):
1560 1560 if bundletype.startswith('HG10'):
1561 1561 cg = changegroup.makechangegroup(repo, outgoing, '01', source)
1562 1562 return writebundle(ui, cg, filename, bundletype, vfs=vfs,
1563 1563 compression=compression, compopts=compopts)
1564 1564 elif not bundletype.startswith('HG20'):
1565 1565 raise error.ProgrammingError('unknown bundle type: %s' % bundletype)
1566 1566
1567 1567 caps = {}
1568 1568 if 'obsolescence' in opts:
1569 1569 caps['obsmarkers'] = ('V1',)
1570 1570 bundle = bundle20(ui, caps)
1571 1571 bundle.setcompression(compression, compopts)
1572 1572 _addpartsfromopts(ui, repo, bundle, source, outgoing, opts)
1573 1573 chunkiter = bundle.getchunks()
1574 1574
1575 1575 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
1576 1576
1577 1577 def _addpartsfromopts(ui, repo, bundler, source, outgoing, opts):
1578 1578 # We should eventually reconcile this logic with the one behind
1579 1579 # 'exchange.getbundle2partsgenerator'.
1580 1580 #
1581 1581 # The type of input from 'getbundle' and 'writenewbundle' are a bit
1582 1582 # different right now. So we keep them separated for now for the sake of
1583 1583 # simplicity.
1584 1584
1585 1585 # we might not always want a changegroup in such bundle, for example in
1586 1586 # stream bundles
1587 1587 if opts.get('changegroup', True):
1588 1588 cgversion = opts.get('cg.version')
1589 1589 if cgversion is None:
1590 1590 cgversion = changegroup.safeversion(repo)
1591 1591 cg = changegroup.makechangegroup(repo, outgoing, cgversion, source)
1592 1592 part = bundler.newpart('changegroup', data=cg.getchunks())
1593 1593 part.addparam('version', cg.version)
1594 1594 if 'clcount' in cg.extras:
1595 1595 part.addparam('nbchanges', '%d' % cg.extras['clcount'],
1596 1596 mandatory=False)
1597 1597 if opts.get('phases') and repo.revs('%ln and secret()',
1598 1598 outgoing.missingheads):
1599 1599 part.addparam('targetphase', '%d' % phases.secret, mandatory=False)
1600 1600
1601 1601 if opts.get('streamv2', False):
1602 1602 addpartbundlestream2(bundler, repo, stream=True)
1603 1603
1604 1604 if opts.get('tagsfnodescache', True):
1605 1605 addparttagsfnodescache(repo, bundler, outgoing)
1606 1606
1607 1607 if opts.get('revbranchcache', True):
1608 1608 addpartrevbranchcache(repo, bundler, outgoing)
1609 1609
1610 1610 if opts.get('obsolescence', False):
1611 1611 obsmarkers = repo.obsstore.relevantmarkers(outgoing.missing)
1612 1612 buildobsmarkerspart(bundler, obsmarkers)
1613 1613
1614 1614 if opts.get('phases', False):
1615 1615 headsbyphase = phases.subsetphaseheads(repo, outgoing.missing)
1616 1616 phasedata = phases.binaryencode(headsbyphase)
1617 1617 bundler.newpart('phase-heads', data=phasedata)
1618 1618
1619 1619 def addparttagsfnodescache(repo, bundler, outgoing):
1620 1620 # we include the tags fnode cache for the bundle changeset
1621 1621 # (as an optional parts)
1622 1622 cache = tags.hgtagsfnodescache(repo.unfiltered())
1623 1623 chunks = []
1624 1624
1625 1625 # .hgtags fnodes are only relevant for head changesets. While we could
1626 1626 # transfer values for all known nodes, there will likely be little to
1627 1627 # no benefit.
1628 1628 #
1629 1629 # We don't bother using a generator to produce output data because
1630 1630 # a) we only have 40 bytes per head and even esoteric numbers of heads
1631 1631 # consume little memory (1M heads is 40MB) b) we don't want to send the
1632 1632 # part if we don't have entries and knowing if we have entries requires
1633 1633 # cache lookups.
1634 1634 for node in outgoing.missingheads:
1635 1635 # Don't compute missing, as this may slow down serving.
1636 1636 fnode = cache.getfnode(node, computemissing=False)
1637 1637 if fnode is not None:
1638 1638 chunks.extend([node, fnode])
1639 1639
1640 1640 if chunks:
1641 1641 bundler.newpart('hgtagsfnodes', data=''.join(chunks))
1642 1642
1643 1643 def addpartrevbranchcache(repo, bundler, outgoing):
1644 1644 # we include the rev branch cache for the bundle changeset
1645 1645 # (as an optional parts)
1646 1646 cache = repo.revbranchcache()
1647 1647 cl = repo.unfiltered().changelog
1648 1648 branchesdata = collections.defaultdict(lambda: (set(), set()))
1649 1649 for node in outgoing.missing:
1650 1650 branch, close = cache.branchinfo(cl.rev(node))
1651 1651 branchesdata[branch][close].add(node)
1652 1652
1653 1653 def generate():
1654 1654 for branch, (nodes, closed) in sorted(branchesdata.items()):
1655 1655 utf8branch = encoding.fromlocal(branch)
1656 1656 yield rbcstruct.pack(len(utf8branch), len(nodes), len(closed))
1657 1657 yield utf8branch
1658 1658 for n in sorted(nodes):
1659 1659 yield n
1660 1660 for n in sorted(closed):
1661 1661 yield n
1662 1662
1663 1663 bundler.newpart('cache:rev-branch-cache', data=generate(),
1664 1664 mandatory=False)
1665 1665
1666 1666 def _formatrequirementsspec(requirements):
1667 1667 return urlreq.quote(','.join(sorted(requirements)))
1668 1668
1669 1669 def _formatrequirementsparams(requirements):
1670 1670 requirements = _formatrequirementsspec(requirements)
1671 1671 params = "%s%s" % (urlreq.quote("requirements="), requirements)
1672 1672 return params
1673 1673
1674 1674 def addpartbundlestream2(bundler, repo, **kwargs):
1675 1675 if not kwargs.get('stream', False):
1676 1676 return
1677 1677
1678 1678 if not streamclone.allowservergeneration(repo):
1679 1679 raise error.Abort(_('stream data requested but server does not allow '
1680 1680 'this feature'),
1681 1681 hint=_('well-behaved clients should not be '
1682 1682 'requesting stream data from servers not '
1683 1683 'advertising it; the client may be buggy'))
1684 1684
1685 1685 # Stream clones don't compress well. And compression undermines a
1686 1686 # goal of stream clones, which is to be fast. Communicate the desire
1687 1687 # to avoid compression to consumers of the bundle.
1688 1688 bundler.prefercompressed = False
1689 1689
1690 1690 filecount, bytecount, it = streamclone.generatev2(repo)
1691 1691 requirements = _formatrequirementsspec(repo.requirements)
1692 1692 part = bundler.newpart('stream2', data=it)
1693 1693 part.addparam('bytecount', '%d' % bytecount, mandatory=True)
1694 1694 part.addparam('filecount', '%d' % filecount, mandatory=True)
1695 1695 part.addparam('requirements', requirements, mandatory=True)
1696 1696
1697 1697 def buildobsmarkerspart(bundler, markers):
1698 1698 """add an obsmarker part to the bundler with <markers>
1699 1699
1700 1700 No part is created if markers is empty.
1701 1701 Raises ValueError if the bundler doesn't support any known obsmarker format.
1702 1702 """
1703 1703 if not markers:
1704 1704 return None
1705 1705
1706 1706 remoteversions = obsmarkersversion(bundler.capabilities)
1707 1707 version = obsolete.commonversion(remoteversions)
1708 1708 if version is None:
1709 1709 raise ValueError('bundler does not support common obsmarker format')
1710 1710 stream = obsolete.encodemarkers(markers, True, version=version)
1711 1711 return bundler.newpart('obsmarkers', data=stream)
1712 1712
1713 1713 def writebundle(ui, cg, filename, bundletype, vfs=None, compression=None,
1714 1714 compopts=None):
1715 1715 """Write a bundle file and return its filename.
1716 1716
1717 1717 Existing files will not be overwritten.
1718 1718 If no filename is specified, a temporary file is created.
1719 1719 bz2 compression can be turned off.
1720 1720 The bundle file will be deleted in case of errors.
1721 1721 """
1722 1722
1723 1723 if bundletype == "HG20":
1724 1724 bundle = bundle20(ui)
1725 1725 bundle.setcompression(compression, compopts)
1726 1726 part = bundle.newpart('changegroup', data=cg.getchunks())
1727 1727 part.addparam('version', cg.version)
1728 1728 if 'clcount' in cg.extras:
1729 1729 part.addparam('nbchanges', '%d' % cg.extras['clcount'],
1730 1730 mandatory=False)
1731 1731 chunkiter = bundle.getchunks()
1732 1732 else:
1733 1733 # compression argument is only for the bundle2 case
1734 1734 assert compression is None
1735 1735 if cg.version != '01':
1736 1736 raise error.Abort(_('old bundle types only supports v1 '
1737 1737 'changegroups'))
1738 1738 header, comp = bundletypes[bundletype]
1739 1739 if comp not in util.compengines.supportedbundletypes:
1740 1740 raise error.Abort(_('unknown stream compression type: %s')
1741 1741 % comp)
1742 1742 compengine = util.compengines.forbundletype(comp)
1743 1743 def chunkiter():
1744 1744 yield header
1745 1745 for chunk in compengine.compressstream(cg.getchunks(), compopts):
1746 1746 yield chunk
1747 1747 chunkiter = chunkiter()
1748 1748
1749 1749 # parse the changegroup data, otherwise we will block
1750 1750 # in case of sshrepo because we don't know the end of the stream
1751 1751 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
1752 1752
1753 1753 def combinechangegroupresults(op):
1754 1754 """logic to combine 0 or more addchangegroup results into one"""
1755 1755 results = [r.get('return', 0)
1756 1756 for r in op.records['changegroup']]
1757 1757 changedheads = 0
1758 1758 result = 1
1759 1759 for ret in results:
1760 1760 # If any changegroup result is 0, return 0
1761 1761 if ret == 0:
1762 1762 result = 0
1763 1763 break
1764 1764 if ret < -1:
1765 1765 changedheads += ret + 1
1766 1766 elif ret > 1:
1767 1767 changedheads += ret - 1
1768 1768 if changedheads > 0:
1769 1769 result = 1 + changedheads
1770 1770 elif changedheads < 0:
1771 1771 result = -1 + changedheads
1772 1772 return result
1773 1773
1774 1774 @parthandler('changegroup', ('version', 'nbchanges', 'treemanifest',
1775 1775 'targetphase'))
1776 1776 def handlechangegroup(op, inpart):
1777 1777 """apply a changegroup part on the repo
1778 1778
1779 1779 This is a very early implementation that will massive rework before being
1780 1780 inflicted to any end-user.
1781 1781 """
1782 1782 from . import localrepo
1783 1783
1784 1784 tr = op.gettransaction()
1785 1785 unpackerversion = inpart.params.get('version', '01')
1786 1786 # We should raise an appropriate exception here
1787 1787 cg = changegroup.getunbundler(unpackerversion, inpart, None)
1788 1788 # the source and url passed here are overwritten by the one contained in
1789 1789 # the transaction.hookargs argument. So 'bundle2' is a placeholder
1790 1790 nbchangesets = None
1791 1791 if 'nbchanges' in inpart.params:
1792 1792 nbchangesets = int(inpart.params.get('nbchanges'))
1793 1793 if ('treemanifest' in inpart.params and
1794 1794 'treemanifest' not in op.repo.requirements):
1795 1795 if len(op.repo.changelog) != 0:
1796 1796 raise error.Abort(_(
1797 1797 "bundle contains tree manifests, but local repo is "
1798 1798 "non-empty and does not use tree manifests"))
1799 1799 op.repo.requirements.add('treemanifest')
1800 1800 op.repo.svfs.options = localrepo.resolvestorevfsoptions(
1801 1801 op.repo.ui, op.repo.requirements)
1802 1802 op.repo._writerequirements()
1803 1803 extrakwargs = {}
1804 1804 targetphase = inpart.params.get('targetphase')
1805 1805 if targetphase is not None:
1806 1806 extrakwargs[r'targetphase'] = int(targetphase)
1807 1807 ret = _processchangegroup(op, cg, tr, 'bundle2', 'bundle2',
1808 1808 expectedtotal=nbchangesets, **extrakwargs)
1809 1809 if op.reply is not None:
1810 1810 # This is definitely not the final form of this
1811 1811 # return. But one need to start somewhere.
1812 1812 part = op.reply.newpart('reply:changegroup', mandatory=False)
1813 1813 part.addparam(
1814 1814 'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False)
1815 1815 part.addparam('return', '%i' % ret, mandatory=False)
1816 1816 assert not inpart.read()
1817 1817
1818 1818 _remotechangegroupparams = tuple(['url', 'size', 'digests'] +
1819 1819 ['digest:%s' % k for k in util.DIGESTS.keys()])
1820 1820 @parthandler('remote-changegroup', _remotechangegroupparams)
1821 1821 def handleremotechangegroup(op, inpart):
1822 1822 """apply a bundle10 on the repo, given an url and validation information
1823 1823
1824 1824 All the information about the remote bundle to import are given as
1825 1825 parameters. The parameters include:
1826 1826 - url: the url to the bundle10.
1827 1827 - size: the bundle10 file size. It is used to validate what was
1828 1828 retrieved by the client matches the server knowledge about the bundle.
1829 1829 - digests: a space separated list of the digest types provided as
1830 1830 parameters.
1831 1831 - digest:<digest-type>: the hexadecimal representation of the digest with
1832 1832 that name. Like the size, it is used to validate what was retrieved by
1833 1833 the client matches what the server knows about the bundle.
1834 1834
1835 1835 When multiple digest types are given, all of them are checked.
1836 1836 """
1837 1837 try:
1838 1838 raw_url = inpart.params['url']
1839 1839 except KeyError:
1840 1840 raise error.Abort(_('remote-changegroup: missing "%s" param') % 'url')
1841 1841 parsed_url = util.url(raw_url)
1842 1842 if parsed_url.scheme not in capabilities['remote-changegroup']:
1843 1843 raise error.Abort(_('remote-changegroup does not support %s urls') %
1844 1844 parsed_url.scheme)
1845 1845
1846 1846 try:
1847 1847 size = int(inpart.params['size'])
1848 1848 except ValueError:
1849 1849 raise error.Abort(_('remote-changegroup: invalid value for param "%s"')
1850 1850 % 'size')
1851 1851 except KeyError:
1852 1852 raise error.Abort(_('remote-changegroup: missing "%s" param') % 'size')
1853 1853
1854 1854 digests = {}
1855 1855 for typ in inpart.params.get('digests', '').split():
1856 1856 param = 'digest:%s' % typ
1857 1857 try:
1858 1858 value = inpart.params[param]
1859 1859 except KeyError:
1860 1860 raise error.Abort(_('remote-changegroup: missing "%s" param') %
1861 1861 param)
1862 1862 digests[typ] = value
1863 1863
1864 1864 real_part = util.digestchecker(url.open(op.ui, raw_url), size, digests)
1865 1865
1866 1866 tr = op.gettransaction()
1867 1867 from . import exchange
1868 1868 cg = exchange.readbundle(op.repo.ui, real_part, raw_url)
1869 1869 if not isinstance(cg, changegroup.cg1unpacker):
1870 1870 raise error.Abort(_('%s: not a bundle version 1.0') %
1871 1871 util.hidepassword(raw_url))
1872 1872 ret = _processchangegroup(op, cg, tr, 'bundle2', 'bundle2')
1873 1873 if op.reply is not None:
1874 1874 # This is definitely not the final form of this
1875 1875 # return. But one need to start somewhere.
1876 1876 part = op.reply.newpart('reply:changegroup')
1877 1877 part.addparam(
1878 1878 'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False)
1879 1879 part.addparam('return', '%i' % ret, mandatory=False)
1880 1880 try:
1881 1881 real_part.validate()
1882 1882 except error.Abort as e:
1883 1883 raise error.Abort(_('bundle at %s is corrupted:\n%s') %
1884 1884 (util.hidepassword(raw_url), bytes(e)))
1885 1885 assert not inpart.read()
1886 1886
1887 1887 @parthandler('reply:changegroup', ('return', 'in-reply-to'))
1888 1888 def handlereplychangegroup(op, inpart):
1889 1889 ret = int(inpart.params['return'])
1890 1890 replyto = int(inpart.params['in-reply-to'])
1891 1891 op.records.add('changegroup', {'return': ret}, replyto)
1892 1892
1893 1893 @parthandler('check:bookmarks')
1894 1894 def handlecheckbookmarks(op, inpart):
1895 1895 """check location of bookmarks
1896 1896
1897 1897 This part is to be used to detect push race regarding bookmark, it
1898 1898 contains binary encoded (bookmark, node) tuple. If the local state does
1899 1899 not marks the one in the part, a PushRaced exception is raised
1900 1900 """
1901 1901 bookdata = bookmarks.binarydecode(inpart)
1902 1902
1903 1903 msgstandard = ('repository changed while pushing - please try again '
1904 1904 '(bookmark "%s" move from %s to %s)')
1905 1905 msgmissing = ('repository changed while pushing - please try again '
1906 1906 '(bookmark "%s" is missing, expected %s)')
1907 1907 msgexist = ('repository changed while pushing - please try again '
1908 1908 '(bookmark "%s" set on %s, expected missing)')
1909 1909 for book, node in bookdata:
1910 1910 currentnode = op.repo._bookmarks.get(book)
1911 1911 if currentnode != node:
1912 1912 if node is None:
1913 1913 finalmsg = msgexist % (book, nodemod.short(currentnode))
1914 1914 elif currentnode is None:
1915 1915 finalmsg = msgmissing % (book, nodemod.short(node))
1916 1916 else:
1917 1917 finalmsg = msgstandard % (book, nodemod.short(node),
1918 1918 nodemod.short(currentnode))
1919 1919 raise error.PushRaced(finalmsg)
1920 1920
1921 1921 @parthandler('check:heads')
1922 1922 def handlecheckheads(op, inpart):
1923 1923 """check that head of the repo did not change
1924 1924
1925 1925 This is used to detect a push race when using unbundle.
1926 1926 This replaces the "heads" argument of unbundle."""
1927 1927 h = inpart.read(20)
1928 1928 heads = []
1929 1929 while len(h) == 20:
1930 1930 heads.append(h)
1931 1931 h = inpart.read(20)
1932 1932 assert not h
1933 1933 # Trigger a transaction so that we are guaranteed to have the lock now.
1934 1934 if op.ui.configbool('experimental', 'bundle2lazylocking'):
1935 1935 op.gettransaction()
1936 1936 if sorted(heads) != sorted(op.repo.heads()):
1937 1937 raise error.PushRaced('repository changed while pushing - '
1938 1938 'please try again')
1939 1939
1940 1940 @parthandler('check:updated-heads')
1941 1941 def handlecheckupdatedheads(op, inpart):
1942 1942 """check for race on the heads touched by a push
1943 1943
1944 1944 This is similar to 'check:heads' but focus on the heads actually updated
1945 1945 during the push. If other activities happen on unrelated heads, it is
1946 1946 ignored.
1947 1947
1948 1948 This allow server with high traffic to avoid push contention as long as
1949 1949 unrelated parts of the graph are involved."""
1950 1950 h = inpart.read(20)
1951 1951 heads = []
1952 1952 while len(h) == 20:
1953 1953 heads.append(h)
1954 1954 h = inpart.read(20)
1955 1955 assert not h
1956 1956 # trigger a transaction so that we are guaranteed to have the lock now.
1957 1957 if op.ui.configbool('experimental', 'bundle2lazylocking'):
1958 1958 op.gettransaction()
1959 1959
1960 1960 currentheads = set()
1961 1961 for ls in op.repo.branchmap().itervalues():
1962 1962 currentheads.update(ls)
1963 1963
1964 1964 for h in heads:
1965 1965 if h not in currentheads:
1966 1966 raise error.PushRaced('repository changed while pushing - '
1967 1967 'please try again')
1968 1968
1969 1969 @parthandler('check:phases')
1970 1970 def handlecheckphases(op, inpart):
1971 1971 """check that phase boundaries of the repository did not change
1972 1972
1973 1973 This is used to detect a push race.
1974 1974 """
1975 1975 phasetonodes = phases.binarydecode(inpart)
1976 1976 unfi = op.repo.unfiltered()
1977 1977 cl = unfi.changelog
1978 1978 phasecache = unfi._phasecache
1979 1979 msg = ('repository changed while pushing - please try again '
1980 1980 '(%s is %s expected %s)')
1981 1981 for expectedphase, nodes in enumerate(phasetonodes):
1982 1982 for n in nodes:
1983 1983 actualphase = phasecache.phase(unfi, cl.rev(n))
1984 1984 if actualphase != expectedphase:
1985 1985 finalmsg = msg % (nodemod.short(n),
1986 1986 phases.phasenames[actualphase],
1987 1987 phases.phasenames[expectedphase])
1988 1988 raise error.PushRaced(finalmsg)
1989 1989
1990 1990 @parthandler('output')
1991 1991 def handleoutput(op, inpart):
1992 1992 """forward output captured on the server to the client"""
1993 1993 for line in inpart.read().splitlines():
1994 1994 op.ui.status(_('remote: %s\n') % line)
1995 1995
1996 1996 @parthandler('replycaps')
1997 1997 def handlereplycaps(op, inpart):
1998 1998 """Notify that a reply bundle should be created
1999 1999
2000 2000 The payload contains the capabilities information for the reply"""
2001 2001 caps = decodecaps(inpart.read())
2002 2002 if op.reply is None:
2003 2003 op.reply = bundle20(op.ui, caps)
2004 2004
2005 2005 class AbortFromPart(error.Abort):
2006 2006 """Sub-class of Abort that denotes an error from a bundle2 part."""
2007 2007
2008 2008 @parthandler('error:abort', ('message', 'hint'))
2009 2009 def handleerrorabort(op, inpart):
2010 2010 """Used to transmit abort error over the wire"""
2011 2011 raise AbortFromPart(inpart.params['message'],
2012 2012 hint=inpart.params.get('hint'))
2013 2013
2014 2014 @parthandler('error:pushkey', ('namespace', 'key', 'new', 'old', 'ret',
2015 2015 'in-reply-to'))
2016 2016 def handleerrorpushkey(op, inpart):
2017 2017 """Used to transmit failure of a mandatory pushkey over the wire"""
2018 2018 kwargs = {}
2019 2019 for name in ('namespace', 'key', 'new', 'old', 'ret'):
2020 2020 value = inpart.params.get(name)
2021 2021 if value is not None:
2022 2022 kwargs[name] = value
2023 2023 raise error.PushkeyFailed(inpart.params['in-reply-to'],
2024 2024 **pycompat.strkwargs(kwargs))
2025 2025
2026 2026 @parthandler('error:unsupportedcontent', ('parttype', 'params'))
2027 2027 def handleerrorunsupportedcontent(op, inpart):
2028 2028 """Used to transmit unknown content error over the wire"""
2029 2029 kwargs = {}
2030 2030 parttype = inpart.params.get('parttype')
2031 2031 if parttype is not None:
2032 2032 kwargs['parttype'] = parttype
2033 2033 params = inpart.params.get('params')
2034 2034 if params is not None:
2035 2035 kwargs['params'] = params.split('\0')
2036 2036
2037 2037 raise error.BundleUnknownFeatureError(**pycompat.strkwargs(kwargs))
2038 2038
2039 2039 @parthandler('error:pushraced', ('message',))
2040 2040 def handleerrorpushraced(op, inpart):
2041 2041 """Used to transmit push race error over the wire"""
2042 2042 raise error.ResponseError(_('push failed:'), inpart.params['message'])
2043 2043
2044 2044 @parthandler('listkeys', ('namespace',))
2045 2045 def handlelistkeys(op, inpart):
2046 2046 """retrieve pushkey namespace content stored in a bundle2"""
2047 2047 namespace = inpart.params['namespace']
2048 2048 r = pushkey.decodekeys(inpart.read())
2049 2049 op.records.add('listkeys', (namespace, r))
2050 2050
2051 2051 @parthandler('pushkey', ('namespace', 'key', 'old', 'new'))
2052 2052 def handlepushkey(op, inpart):
2053 2053 """process a pushkey request"""
2054 2054 dec = pushkey.decode
2055 2055 namespace = dec(inpart.params['namespace'])
2056 2056 key = dec(inpart.params['key'])
2057 2057 old = dec(inpart.params['old'])
2058 2058 new = dec(inpart.params['new'])
2059 2059 # Grab the transaction to ensure that we have the lock before performing the
2060 2060 # pushkey.
2061 2061 if op.ui.configbool('experimental', 'bundle2lazylocking'):
2062 2062 op.gettransaction()
2063 2063 ret = op.repo.pushkey(namespace, key, old, new)
2064 2064 record = {'namespace': namespace,
2065 2065 'key': key,
2066 2066 'old': old,
2067 2067 'new': new}
2068 2068 op.records.add('pushkey', record)
2069 2069 if op.reply is not None:
2070 2070 rpart = op.reply.newpart('reply:pushkey')
2071 2071 rpart.addparam(
2072 2072 'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False)
2073 2073 rpart.addparam('return', '%i' % ret, mandatory=False)
2074 2074 if inpart.mandatory and not ret:
2075 2075 kwargs = {}
2076 2076 for key in ('namespace', 'key', 'new', 'old', 'ret'):
2077 2077 if key in inpart.params:
2078 2078 kwargs[key] = inpart.params[key]
2079 2079 raise error.PushkeyFailed(partid='%d' % inpart.id,
2080 2080 **pycompat.strkwargs(kwargs))
2081 2081
2082 2082 @parthandler('bookmarks')
2083 2083 def handlebookmark(op, inpart):
2084 2084 """transmit bookmark information
2085 2085
2086 2086 The part contains binary encoded bookmark information.
2087 2087
2088 2088 The exact behavior of this part can be controlled by the 'bookmarks' mode
2089 2089 on the bundle operation.
2090 2090
2091 2091 When mode is 'apply' (the default) the bookmark information is applied as
2092 2092 is to the unbundling repository. Make sure a 'check:bookmarks' part is
2093 2093 issued earlier to check for push races in such update. This behavior is
2094 2094 suitable for pushing.
2095 2095
2096 2096 When mode is 'records', the information is recorded into the 'bookmarks'
2097 2097 records of the bundle operation. This behavior is suitable for pulling.
2098 2098 """
2099 2099 changes = bookmarks.binarydecode(inpart)
2100 2100
2101 2101 pushkeycompat = op.repo.ui.configbool('server', 'bookmarks-pushkey-compat')
2102 2102 bookmarksmode = op.modes.get('bookmarks', 'apply')
2103 2103
2104 2104 if bookmarksmode == 'apply':
2105 2105 tr = op.gettransaction()
2106 2106 bookstore = op.repo._bookmarks
2107 2107 if pushkeycompat:
2108 2108 allhooks = []
2109 2109 for book, node in changes:
2110 2110 hookargs = tr.hookargs.copy()
2111 2111 hookargs['pushkeycompat'] = '1'
2112 2112 hookargs['namespace'] = 'bookmarks'
2113 2113 hookargs['key'] = book
2114 2114 hookargs['old'] = nodemod.hex(bookstore.get(book, ''))
2115 2115 hookargs['new'] = nodemod.hex(node if node is not None else '')
2116 2116 allhooks.append(hookargs)
2117 2117
2118 2118 for hookargs in allhooks:
2119 2119 op.repo.hook('prepushkey', throw=True,
2120 2120 **pycompat.strkwargs(hookargs))
2121 2121
2122 2122 bookstore.applychanges(op.repo, op.gettransaction(), changes)
2123 2123
2124 2124 if pushkeycompat:
2125 2125 def runhook():
2126 2126 for hookargs in allhooks:
2127 2127 op.repo.hook('pushkey', **pycompat.strkwargs(hookargs))
2128 2128 op.repo._afterlock(runhook)
2129 2129
2130 2130 elif bookmarksmode == 'records':
2131 2131 for book, node in changes:
2132 2132 record = {'bookmark': book, 'node': node}
2133 2133 op.records.add('bookmarks', record)
2134 2134 else:
2135 2135 raise error.ProgrammingError('unkown bookmark mode: %s' % bookmarksmode)
2136 2136
2137 2137 @parthandler('phase-heads')
2138 2138 def handlephases(op, inpart):
2139 2139 """apply phases from bundle part to repo"""
2140 2140 headsbyphase = phases.binarydecode(inpart)
2141 2141 phases.updatephases(op.repo.unfiltered(), op.gettransaction, headsbyphase)
2142 2142
2143 2143 @parthandler('reply:pushkey', ('return', 'in-reply-to'))
2144 2144 def handlepushkeyreply(op, inpart):
2145 2145 """retrieve the result of a pushkey request"""
2146 2146 ret = int(inpart.params['return'])
2147 2147 partid = int(inpart.params['in-reply-to'])
2148 2148 op.records.add('pushkey', {'return': ret}, partid)
2149 2149
2150 2150 @parthandler('obsmarkers')
2151 2151 def handleobsmarker(op, inpart):
2152 2152 """add a stream of obsmarkers to the repo"""
2153 2153 tr = op.gettransaction()
2154 2154 markerdata = inpart.read()
2155 2155 if op.ui.config('experimental', 'obsmarkers-exchange-debug'):
2156 2156 op.ui.write(('obsmarker-exchange: %i bytes received\n')
2157 2157 % len(markerdata))
2158 2158 # The mergemarkers call will crash if marker creation is not enabled.
2159 2159 # we want to avoid this if the part is advisory.
2160 2160 if not inpart.mandatory and op.repo.obsstore.readonly:
2161 2161 op.repo.ui.debug('ignoring obsolescence markers, feature not enabled\n')
2162 2162 return
2163 2163 new = op.repo.obsstore.mergemarkers(tr, markerdata)
2164 2164 op.repo.invalidatevolatilesets()
2165 2165 if new:
2166 2166 op.repo.ui.status(_('%i new obsolescence markers\n') % new)
2167 2167 op.records.add('obsmarkers', {'new': new})
2168 2168 if op.reply is not None:
2169 2169 rpart = op.reply.newpart('reply:obsmarkers')
2170 2170 rpart.addparam(
2171 2171 'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False)
2172 2172 rpart.addparam('new', '%i' % new, mandatory=False)
2173 2173
2174 2174
2175 2175 @parthandler('reply:obsmarkers', ('new', 'in-reply-to'))
2176 2176 def handleobsmarkerreply(op, inpart):
2177 2177 """retrieve the result of a pushkey request"""
2178 2178 ret = int(inpart.params['new'])
2179 2179 partid = int(inpart.params['in-reply-to'])
2180 2180 op.records.add('obsmarkers', {'new': ret}, partid)
2181 2181
2182 2182 @parthandler('hgtagsfnodes')
2183 2183 def handlehgtagsfnodes(op, inpart):
2184 2184 """Applies .hgtags fnodes cache entries to the local repo.
2185 2185
2186 2186 Payload is pairs of 20 byte changeset nodes and filenodes.
2187 2187 """
2188 2188 # Grab the transaction so we ensure that we have the lock at this point.
2189 2189 if op.ui.configbool('experimental', 'bundle2lazylocking'):
2190 2190 op.gettransaction()
2191 2191 cache = tags.hgtagsfnodescache(op.repo.unfiltered())
2192 2192
2193 2193 count = 0
2194 2194 while True:
2195 2195 node = inpart.read(20)
2196 2196 fnode = inpart.read(20)
2197 2197 if len(node) < 20 or len(fnode) < 20:
2198 2198 op.ui.debug('ignoring incomplete received .hgtags fnodes data\n')
2199 2199 break
2200 2200 cache.setfnode(node, fnode)
2201 2201 count += 1
2202 2202
2203 2203 cache.write()
2204 2204 op.ui.debug('applied %i hgtags fnodes cache entries\n' % count)
2205 2205
2206 2206 rbcstruct = struct.Struct('>III')
2207 2207
2208 2208 @parthandler('cache:rev-branch-cache')
2209 2209 def handlerbc(op, inpart):
2210 2210 """receive a rev-branch-cache payload and update the local cache
2211 2211
2212 2212 The payload is a series of data related to each branch
2213 2213
2214 2214 1) branch name length
2215 2215 2) number of open heads
2216 2216 3) number of closed heads
2217 2217 4) open heads nodes
2218 2218 5) closed heads nodes
2219 2219 """
2220 2220 total = 0
2221 2221 rawheader = inpart.read(rbcstruct.size)
2222 2222 cache = op.repo.revbranchcache()
2223 2223 cl = op.repo.unfiltered().changelog
2224 2224 while rawheader:
2225 2225 header = rbcstruct.unpack(rawheader)
2226 2226 total += header[1] + header[2]
2227 2227 utf8branch = inpart.read(header[0])
2228 2228 branch = encoding.tolocal(utf8branch)
2229 2229 for x in pycompat.xrange(header[1]):
2230 2230 node = inpart.read(20)
2231 2231 rev = cl.rev(node)
2232 2232 cache.setdata(branch, rev, node, False)
2233 2233 for x in pycompat.xrange(header[2]):
2234 2234 node = inpart.read(20)
2235 2235 rev = cl.rev(node)
2236 2236 cache.setdata(branch, rev, node, True)
2237 2237 rawheader = inpart.read(rbcstruct.size)
2238 2238 cache.write()
2239 2239
2240 2240 @parthandler('pushvars')
2241 2241 def bundle2getvars(op, part):
2242 2242 '''unbundle a bundle2 containing shellvars on the server'''
2243 2243 # An option to disable unbundling on server-side for security reasons
2244 2244 if op.ui.configbool('push', 'pushvars.server'):
2245 2245 hookargs = {}
2246 2246 for key, value in part.advisoryparams:
2247 2247 key = key.upper()
2248 2248 # We want pushed variables to have USERVAR_ prepended so we know
2249 2249 # they came from the --pushvar flag.
2250 2250 key = "USERVAR_" + key
2251 2251 hookargs[key] = value
2252 2252 op.addhookargs(hookargs)
2253 2253
2254 2254 @parthandler('stream2', ('requirements', 'filecount', 'bytecount'))
2255 2255 def handlestreamv2bundle(op, part):
2256 2256
2257 2257 requirements = urlreq.unquote(part.params['requirements']).split(',')
2258 2258 filecount = int(part.params['filecount'])
2259 2259 bytecount = int(part.params['bytecount'])
2260 2260
2261 2261 repo = op.repo
2262 2262 if len(repo):
2263 2263 msg = _('cannot apply stream clone to non empty repository')
2264 2264 raise error.Abort(msg)
2265 2265
2266 2266 repo.ui.debug('applying stream bundle\n')
2267 2267 streamclone.applybundlev2(repo, part, filecount, bytecount,
2268 2268 requirements)
@@ -1,1404 +1,1405 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 def loadconfigtable(ui, extname, configtable):
19 19 """update config item known to the ui with the extension ones"""
20 20 for section, items in sorted(configtable.items()):
21 21 knownitems = ui._knownconfig.setdefault(section, itemregister())
22 22 knownkeys = set(knownitems)
23 23 newkeys = set(items)
24 24 for key in sorted(knownkeys & newkeys):
25 25 msg = "extension '%s' overwrite config item '%s.%s'"
26 26 msg %= (extname, section, key)
27 27 ui.develwarn(msg, config='warn-config')
28 28
29 29 knownitems.update(items)
30 30
31 31 class configitem(object):
32 32 """represent a known config item
33 33
34 34 :section: the official config section where to find this item,
35 35 :name: the official name within the section,
36 36 :default: default value for this item,
37 37 :alias: optional list of tuples as alternatives,
38 38 :generic: this is a generic definition, match name using regular expression.
39 39 """
40 40
41 41 def __init__(self, section, name, default=None, alias=(),
42 42 generic=False, priority=0):
43 43 self.section = section
44 44 self.name = name
45 45 self.default = default
46 46 self.alias = list(alias)
47 47 self.generic = generic
48 48 self.priority = priority
49 49 self._re = None
50 50 if generic:
51 51 self._re = re.compile(self.name)
52 52
53 53 class itemregister(dict):
54 54 """A specialized dictionary that can handle wild-card selection"""
55 55
56 56 def __init__(self):
57 57 super(itemregister, self).__init__()
58 58 self._generics = set()
59 59
60 60 def update(self, other):
61 61 super(itemregister, self).update(other)
62 62 self._generics.update(other._generics)
63 63
64 64 def __setitem__(self, key, item):
65 65 super(itemregister, self).__setitem__(key, item)
66 66 if item.generic:
67 67 self._generics.add(item)
68 68
69 69 def get(self, key):
70 70 baseitem = super(itemregister, self).get(key)
71 71 if baseitem is not None and not baseitem.generic:
72 72 return baseitem
73 73
74 74 # search for a matching generic item
75 75 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
76 76 for item in generics:
77 77 # we use 'match' instead of 'search' to make the matching simpler
78 78 # for people unfamiliar with regular expression. Having the match
79 79 # rooted to the start of the string will produce less surprising
80 80 # result for user writing simple regex for sub-attribute.
81 81 #
82 82 # For example using "color\..*" match produces an unsurprising
83 83 # result, while using search could suddenly match apparently
84 84 # unrelated configuration that happens to contains "color."
85 85 # anywhere. This is a tradeoff where we favor requiring ".*" on
86 86 # some match to avoid the need to prefix most pattern with "^".
87 87 # The "^" seems more error prone.
88 88 if item._re.match(key):
89 89 return item
90 90
91 91 return None
92 92
93 93 coreitems = {}
94 94
95 95 def _register(configtable, *args, **kwargs):
96 96 item = configitem(*args, **kwargs)
97 97 section = configtable.setdefault(item.section, itemregister())
98 98 if item.name in section:
99 99 msg = "duplicated config item registration for '%s.%s'"
100 100 raise error.ProgrammingError(msg % (item.section, item.name))
101 101 section[item.name] = item
102 102
103 103 # special value for case where the default is derived from other values
104 104 dynamicdefault = object()
105 105
106 106 # Registering actual config items
107 107
108 108 def getitemregister(configtable):
109 109 f = functools.partial(_register, configtable)
110 110 # export pseudo enum as configitem.*
111 111 f.dynamicdefault = dynamicdefault
112 112 return f
113 113
114 114 coreconfigitem = getitemregister(coreitems)
115 115
116 116 coreconfigitem('alias', '.*',
117 117 default=dynamicdefault,
118 118 generic=True,
119 119 )
120 120 coreconfigitem('annotate', 'nodates',
121 121 default=False,
122 122 )
123 123 coreconfigitem('annotate', 'showfunc',
124 124 default=False,
125 125 )
126 126 coreconfigitem('annotate', 'unified',
127 127 default=None,
128 128 )
129 129 coreconfigitem('annotate', 'git',
130 130 default=False,
131 131 )
132 132 coreconfigitem('annotate', 'ignorews',
133 133 default=False,
134 134 )
135 135 coreconfigitem('annotate', 'ignorewsamount',
136 136 default=False,
137 137 )
138 138 coreconfigitem('annotate', 'ignoreblanklines',
139 139 default=False,
140 140 )
141 141 coreconfigitem('annotate', 'ignorewseol',
142 142 default=False,
143 143 )
144 144 coreconfigitem('annotate', 'nobinary',
145 145 default=False,
146 146 )
147 147 coreconfigitem('annotate', 'noprefix',
148 148 default=False,
149 149 )
150 150 coreconfigitem('annotate', 'word-diff',
151 151 default=False,
152 152 )
153 153 coreconfigitem('auth', 'cookiefile',
154 154 default=None,
155 155 )
156 156 # bookmarks.pushing: internal hack for discovery
157 157 coreconfigitem('bookmarks', 'pushing',
158 158 default=list,
159 159 )
160 160 # bundle.mainreporoot: internal hack for bundlerepo
161 161 coreconfigitem('bundle', 'mainreporoot',
162 162 default='',
163 163 )
164 164 # bundle.reorder: experimental config
165 165 coreconfigitem('bundle', 'reorder',
166 166 default='auto',
167 167 )
168 168 coreconfigitem('censor', 'policy',
169 169 default='abort',
170 170 )
171 171 coreconfigitem('chgserver', 'idletimeout',
172 172 default=3600,
173 173 )
174 174 coreconfigitem('chgserver', 'skiphash',
175 175 default=False,
176 176 )
177 177 coreconfigitem('cmdserver', 'log',
178 178 default=None,
179 179 )
180 180 coreconfigitem('color', '.*',
181 181 default=None,
182 182 generic=True,
183 183 )
184 184 coreconfigitem('color', 'mode',
185 185 default='auto',
186 186 )
187 187 coreconfigitem('color', 'pagermode',
188 188 default=dynamicdefault,
189 189 )
190 190 coreconfigitem('commands', 'grep.all-files',
191 191 default=False,
192 192 )
193 193 coreconfigitem('commands', 'resolve.confirm',
194 194 default=False,
195 195 )
196 196 coreconfigitem('commands', 'resolve.explicit-re-merge',
197 197 default=False,
198 198 )
199 199 coreconfigitem('commands', 'resolve.mark-check',
200 200 default='none',
201 201 )
202 202 coreconfigitem('commands', 'show.aliasprefix',
203 203 default=list,
204 204 )
205 205 coreconfigitem('commands', 'status.relative',
206 206 default=False,
207 207 )
208 208 coreconfigitem('commands', 'status.skipstates',
209 209 default=[],
210 210 )
211 211 coreconfigitem('commands', 'status.terse',
212 212 default='',
213 213 )
214 214 coreconfigitem('commands', 'status.verbose',
215 215 default=False,
216 216 )
217 217 coreconfigitem('commands', 'update.check',
218 218 default=None,
219 219 )
220 220 coreconfigitem('commands', 'update.requiredest',
221 221 default=False,
222 222 )
223 223 coreconfigitem('committemplate', '.*',
224 224 default=None,
225 225 generic=True,
226 226 )
227 227 coreconfigitem('convert', 'bzr.saverev',
228 228 default=True,
229 229 )
230 230 coreconfigitem('convert', 'cvsps.cache',
231 231 default=True,
232 232 )
233 233 coreconfigitem('convert', 'cvsps.fuzz',
234 234 default=60,
235 235 )
236 236 coreconfigitem('convert', 'cvsps.logencoding',
237 237 default=None,
238 238 )
239 239 coreconfigitem('convert', 'cvsps.mergefrom',
240 240 default=None,
241 241 )
242 242 coreconfigitem('convert', 'cvsps.mergeto',
243 243 default=None,
244 244 )
245 245 coreconfigitem('convert', 'git.committeractions',
246 246 default=lambda: ['messagedifferent'],
247 247 )
248 248 coreconfigitem('convert', 'git.extrakeys',
249 249 default=list,
250 250 )
251 251 coreconfigitem('convert', 'git.findcopiesharder',
252 252 default=False,
253 253 )
254 254 coreconfigitem('convert', 'git.remoteprefix',
255 255 default='remote',
256 256 )
257 257 coreconfigitem('convert', 'git.renamelimit',
258 258 default=400,
259 259 )
260 260 coreconfigitem('convert', 'git.saverev',
261 261 default=True,
262 262 )
263 263 coreconfigitem('convert', 'git.similarity',
264 264 default=50,
265 265 )
266 266 coreconfigitem('convert', 'git.skipsubmodules',
267 267 default=False,
268 268 )
269 269 coreconfigitem('convert', 'hg.clonebranches',
270 270 default=False,
271 271 )
272 272 coreconfigitem('convert', 'hg.ignoreerrors',
273 273 default=False,
274 274 )
275 275 coreconfigitem('convert', 'hg.revs',
276 276 default=None,
277 277 )
278 278 coreconfigitem('convert', 'hg.saverev',
279 279 default=False,
280 280 )
281 281 coreconfigitem('convert', 'hg.sourcename',
282 282 default=None,
283 283 )
284 284 coreconfigitem('convert', 'hg.startrev',
285 285 default=None,
286 286 )
287 287 coreconfigitem('convert', 'hg.tagsbranch',
288 288 default='default',
289 289 )
290 290 coreconfigitem('convert', 'hg.usebranchnames',
291 291 default=True,
292 292 )
293 293 coreconfigitem('convert', 'ignoreancestorcheck',
294 294 default=False,
295 295 )
296 296 coreconfigitem('convert', 'localtimezone',
297 297 default=False,
298 298 )
299 299 coreconfigitem('convert', 'p4.encoding',
300 300 default=dynamicdefault,
301 301 )
302 302 coreconfigitem('convert', 'p4.startrev',
303 303 default=0,
304 304 )
305 305 coreconfigitem('convert', 'skiptags',
306 306 default=False,
307 307 )
308 308 coreconfigitem('convert', 'svn.debugsvnlog',
309 309 default=True,
310 310 )
311 311 coreconfigitem('convert', 'svn.trunk',
312 312 default=None,
313 313 )
314 314 coreconfigitem('convert', 'svn.tags',
315 315 default=None,
316 316 )
317 317 coreconfigitem('convert', 'svn.branches',
318 318 default=None,
319 319 )
320 320 coreconfigitem('convert', 'svn.startrev',
321 321 default=0,
322 322 )
323 323 coreconfigitem('debug', 'dirstate.delaywrite',
324 324 default=0,
325 325 )
326 326 coreconfigitem('defaults', '.*',
327 327 default=None,
328 328 generic=True,
329 329 )
330 330 coreconfigitem('devel', 'all-warnings',
331 331 default=False,
332 332 )
333 333 coreconfigitem('devel', 'bundle2.debug',
334 334 default=False,
335 335 )
336 336 coreconfigitem('devel', 'cache-vfs',
337 337 default=None,
338 338 )
339 339 coreconfigitem('devel', 'check-locks',
340 340 default=False,
341 341 )
342 342 coreconfigitem('devel', 'check-relroot',
343 343 default=False,
344 344 )
345 345 coreconfigitem('devel', 'default-date',
346 346 default=None,
347 347 )
348 348 coreconfigitem('devel', 'deprec-warn',
349 349 default=False,
350 350 )
351 351 coreconfigitem('devel', 'disableloaddefaultcerts',
352 352 default=False,
353 353 )
354 354 coreconfigitem('devel', 'warn-empty-changegroup',
355 355 default=False,
356 356 )
357 357 coreconfigitem('devel', 'legacy.exchange',
358 358 default=list,
359 359 )
360 360 coreconfigitem('devel', 'servercafile',
361 361 default='',
362 362 )
363 363 coreconfigitem('devel', 'serverexactprotocol',
364 364 default='',
365 365 )
366 366 coreconfigitem('devel', 'serverrequirecert',
367 367 default=False,
368 368 )
369 369 coreconfigitem('devel', 'strip-obsmarkers',
370 370 default=True,
371 371 )
372 372 coreconfigitem('devel', 'warn-config',
373 373 default=None,
374 374 )
375 375 coreconfigitem('devel', 'warn-config-default',
376 376 default=None,
377 377 )
378 378 coreconfigitem('devel', 'user.obsmarker',
379 379 default=None,
380 380 )
381 381 coreconfigitem('devel', 'warn-config-unknown',
382 382 default=None,
383 383 )
384 384 coreconfigitem('devel', 'debug.extensions',
385 385 default=False,
386 386 )
387 387 coreconfigitem('devel', 'debug.peer-request',
388 388 default=False,
389 389 )
390 390 coreconfigitem('diff', 'nodates',
391 391 default=False,
392 392 )
393 393 coreconfigitem('diff', 'showfunc',
394 394 default=False,
395 395 )
396 396 coreconfigitem('diff', 'unified',
397 397 default=None,
398 398 )
399 399 coreconfigitem('diff', 'git',
400 400 default=False,
401 401 )
402 402 coreconfigitem('diff', 'ignorews',
403 403 default=False,
404 404 )
405 405 coreconfigitem('diff', 'ignorewsamount',
406 406 default=False,
407 407 )
408 408 coreconfigitem('diff', 'ignoreblanklines',
409 409 default=False,
410 410 )
411 411 coreconfigitem('diff', 'ignorewseol',
412 412 default=False,
413 413 )
414 414 coreconfigitem('diff', 'nobinary',
415 415 default=False,
416 416 )
417 417 coreconfigitem('diff', 'noprefix',
418 418 default=False,
419 419 )
420 420 coreconfigitem('diff', 'word-diff',
421 421 default=False,
422 422 )
423 423 coreconfigitem('email', 'bcc',
424 424 default=None,
425 425 )
426 426 coreconfigitem('email', 'cc',
427 427 default=None,
428 428 )
429 429 coreconfigitem('email', 'charsets',
430 430 default=list,
431 431 )
432 432 coreconfigitem('email', 'from',
433 433 default=None,
434 434 )
435 435 coreconfigitem('email', 'method',
436 436 default='smtp',
437 437 )
438 438 coreconfigitem('email', 'reply-to',
439 439 default=None,
440 440 )
441 441 coreconfigitem('email', 'to',
442 442 default=None,
443 443 )
444 444 coreconfigitem('experimental', 'archivemetatemplate',
445 445 default=dynamicdefault,
446 446 )
447 447 coreconfigitem('experimental', 'bundle-phases',
448 448 default=False,
449 449 )
450 450 coreconfigitem('experimental', 'bundle2-advertise',
451 451 default=True,
452 452 )
453 453 coreconfigitem('experimental', 'bundle2-output-capture',
454 454 default=False,
455 455 )
456 456 coreconfigitem('experimental', 'bundle2.pushback',
457 457 default=False,
458 458 )
459 coreconfigitem('experimental', 'bundle2.stream',
460 default=False,
461 )
462 459 coreconfigitem('experimental', 'bundle2lazylocking',
463 460 default=False,
464 461 )
465 462 coreconfigitem('experimental', 'bundlecomplevel',
466 463 default=None,
467 464 )
468 465 coreconfigitem('experimental', 'bundlecomplevel.bzip2',
469 466 default=None,
470 467 )
471 468 coreconfigitem('experimental', 'bundlecomplevel.gzip',
472 469 default=None,
473 470 )
474 471 coreconfigitem('experimental', 'bundlecomplevel.none',
475 472 default=None,
476 473 )
477 474 coreconfigitem('experimental', 'bundlecomplevel.zstd',
478 475 default=None,
479 476 )
480 477 coreconfigitem('experimental', 'changegroup3',
481 478 default=False,
482 479 )
483 480 coreconfigitem('experimental', 'clientcompressionengines',
484 481 default=list,
485 482 )
486 483 coreconfigitem('experimental', 'copytrace',
487 484 default='on',
488 485 )
489 486 coreconfigitem('experimental', 'copytrace.movecandidateslimit',
490 487 default=100,
491 488 )
492 489 coreconfigitem('experimental', 'copytrace.sourcecommitlimit',
493 490 default=100,
494 491 )
495 492 coreconfigitem('experimental', 'crecordtest',
496 493 default=None,
497 494 )
498 495 coreconfigitem('experimental', 'directaccess',
499 496 default=False,
500 497 )
501 498 coreconfigitem('experimental', 'directaccess.revnums',
502 499 default=False,
503 500 )
504 501 coreconfigitem('experimental', 'editortmpinhg',
505 502 default=False,
506 503 )
507 504 coreconfigitem('experimental', 'evolution',
508 505 default=list,
509 506 )
510 507 coreconfigitem('experimental', 'evolution.allowdivergence',
511 508 default=False,
512 509 alias=[('experimental', 'allowdivergence')]
513 510 )
514 511 coreconfigitem('experimental', 'evolution.allowunstable',
515 512 default=None,
516 513 )
517 514 coreconfigitem('experimental', 'evolution.createmarkers',
518 515 default=None,
519 516 )
520 517 coreconfigitem('experimental', 'evolution.effect-flags',
521 518 default=True,
522 519 alias=[('experimental', 'effect-flags')]
523 520 )
524 521 coreconfigitem('experimental', 'evolution.exchange',
525 522 default=None,
526 523 )
527 524 coreconfigitem('experimental', 'evolution.bundle-obsmarker',
528 525 default=False,
529 526 )
530 527 coreconfigitem('experimental', 'evolution.report-instabilities',
531 528 default=True,
532 529 )
533 530 coreconfigitem('experimental', 'evolution.track-operation',
534 531 default=True,
535 532 )
536 533 coreconfigitem('experimental', 'maxdeltachainspan',
537 534 default=-1,
538 535 )
539 536 coreconfigitem('experimental', 'mergetempdirprefix',
540 537 default=None,
541 538 )
542 539 coreconfigitem('experimental', 'mmapindexthreshold',
543 540 default=None,
544 541 )
545 542 coreconfigitem('experimental', 'nonnormalparanoidcheck',
546 543 default=False,
547 544 )
548 545 coreconfigitem('experimental', 'exportableenviron',
549 546 default=list,
550 547 )
551 548 coreconfigitem('experimental', 'extendedheader.index',
552 549 default=None,
553 550 )
554 551 coreconfigitem('experimental', 'extendedheader.similarity',
555 552 default=False,
556 553 )
557 554 coreconfigitem('experimental', 'format.compression',
558 555 default='zlib',
559 556 )
560 557 coreconfigitem('experimental', 'graphshorten',
561 558 default=False,
562 559 )
563 560 coreconfigitem('experimental', 'graphstyle.parent',
564 561 default=dynamicdefault,
565 562 )
566 563 coreconfigitem('experimental', 'graphstyle.missing',
567 564 default=dynamicdefault,
568 565 )
569 566 coreconfigitem('experimental', 'graphstyle.grandparent',
570 567 default=dynamicdefault,
571 568 )
572 569 coreconfigitem('experimental', 'hook-track-tags',
573 570 default=False,
574 571 )
575 572 coreconfigitem('experimental', 'httppeer.advertise-v2',
576 573 default=False,
577 574 )
578 575 coreconfigitem('experimental', 'httppostargs',
579 576 default=False,
580 577 )
581 578 coreconfigitem('experimental', 'mergedriver',
582 579 default=None,
583 580 )
584 581 coreconfigitem('experimental', 'nointerrupt', default=False)
585 582 coreconfigitem('experimental', 'nointerrupt-interactiveonly', default=True)
586 583
587 584 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
588 585 default=False,
589 586 )
590 587 coreconfigitem('experimental', 'remotenames',
591 588 default=False,
592 589 )
593 590 coreconfigitem('experimental', 'removeemptydirs',
594 591 default=True,
595 592 )
596 593 coreconfigitem('experimental', 'revisions.prefixhexnode',
597 594 default=False,
598 595 )
599 596 coreconfigitem('experimental', 'revlogv2',
600 597 default=None,
601 598 )
602 599 coreconfigitem('experimental', 'revisions.disambiguatewithin',
603 600 default=None,
604 601 )
605 602 coreconfigitem('experimental', 'single-head-per-branch',
606 603 default=False,
607 604 )
608 605 coreconfigitem('experimental', 'sshserver.support-v2',
609 606 default=False,
610 607 )
611 608 coreconfigitem('experimental', 'spacemovesdown',
612 609 default=False,
613 610 )
614 611 coreconfigitem('experimental', 'sparse-read',
615 612 default=False,
616 613 )
617 614 coreconfigitem('experimental', 'sparse-read.density-threshold',
618 615 default=0.50,
619 616 )
620 617 coreconfigitem('experimental', 'sparse-read.min-gap-size',
621 618 default='65K',
622 619 )
623 620 coreconfigitem('experimental', 'treemanifest',
624 621 default=False,
625 622 )
626 623 coreconfigitem('experimental', 'update.atomic-file',
627 624 default=False,
628 625 )
629 626 coreconfigitem('experimental', 'sshpeer.advertise-v2',
630 627 default=False,
631 628 )
632 629 coreconfigitem('experimental', 'web.apiserver',
633 630 default=False,
634 631 )
635 632 coreconfigitem('experimental', 'web.api.http-v2',
636 633 default=False,
637 634 )
638 635 coreconfigitem('experimental', 'web.api.debugreflect',
639 636 default=False,
640 637 )
641 638 coreconfigitem('experimental', 'worker.wdir-get-thread-safe',
642 639 default=False,
643 640 )
644 641 coreconfigitem('experimental', 'xdiff',
645 642 default=False,
646 643 )
647 644 coreconfigitem('extensions', '.*',
648 645 default=None,
649 646 generic=True,
650 647 )
651 648 coreconfigitem('extdata', '.*',
652 649 default=None,
653 650 generic=True,
654 651 )
655 652 coreconfigitem('format', 'chunkcachesize',
656 653 default=None,
657 654 )
658 655 coreconfigitem('format', 'dotencode',
659 656 default=True,
660 657 )
661 658 coreconfigitem('format', 'generaldelta',
662 659 default=False,
663 660 )
664 661 coreconfigitem('format', 'manifestcachesize',
665 662 default=None,
666 663 )
667 664 coreconfigitem('format', 'maxchainlen',
668 665 default=dynamicdefault,
669 666 )
670 667 coreconfigitem('format', 'obsstore-version',
671 668 default=None,
672 669 )
673 670 coreconfigitem('format', 'sparse-revlog',
674 671 default=False,
675 672 )
676 673 coreconfigitem('format', 'usefncache',
677 674 default=True,
678 675 )
679 676 coreconfigitem('format', 'usegeneraldelta',
680 677 default=True,
681 678 )
682 679 coreconfigitem('format', 'usestore',
683 680 default=True,
684 681 )
685 682 coreconfigitem('format', 'internal-phase',
686 683 default=False,
687 684 )
688 685 coreconfigitem('fsmonitor', 'warn_when_unused',
689 686 default=True,
690 687 )
691 688 coreconfigitem('fsmonitor', 'warn_update_file_count',
692 689 default=50000,
693 690 )
694 691 coreconfigitem('hooks', '.*',
695 692 default=dynamicdefault,
696 693 generic=True,
697 694 )
698 695 coreconfigitem('hgweb-paths', '.*',
699 696 default=list,
700 697 generic=True,
701 698 )
702 699 coreconfigitem('hostfingerprints', '.*',
703 700 default=list,
704 701 generic=True,
705 702 )
706 703 coreconfigitem('hostsecurity', 'ciphers',
707 704 default=None,
708 705 )
709 706 coreconfigitem('hostsecurity', 'disabletls10warning',
710 707 default=False,
711 708 )
712 709 coreconfigitem('hostsecurity', 'minimumprotocol',
713 710 default=dynamicdefault,
714 711 )
715 712 coreconfigitem('hostsecurity', '.*:minimumprotocol$',
716 713 default=dynamicdefault,
717 714 generic=True,
718 715 )
719 716 coreconfigitem('hostsecurity', '.*:ciphers$',
720 717 default=dynamicdefault,
721 718 generic=True,
722 719 )
723 720 coreconfigitem('hostsecurity', '.*:fingerprints$',
724 721 default=list,
725 722 generic=True,
726 723 )
727 724 coreconfigitem('hostsecurity', '.*:verifycertsfile$',
728 725 default=None,
729 726 generic=True,
730 727 )
731 728
732 729 coreconfigitem('http_proxy', 'always',
733 730 default=False,
734 731 )
735 732 coreconfigitem('http_proxy', 'host',
736 733 default=None,
737 734 )
738 735 coreconfigitem('http_proxy', 'no',
739 736 default=list,
740 737 )
741 738 coreconfigitem('http_proxy', 'passwd',
742 739 default=None,
743 740 )
744 741 coreconfigitem('http_proxy', 'user',
745 742 default=None,
746 743 )
747 744 coreconfigitem('logtoprocess', 'commandexception',
748 745 default=None,
749 746 )
750 747 coreconfigitem('logtoprocess', 'commandfinish',
751 748 default=None,
752 749 )
753 750 coreconfigitem('logtoprocess', 'command',
754 751 default=None,
755 752 )
756 753 coreconfigitem('logtoprocess', 'develwarn',
757 754 default=None,
758 755 )
759 756 coreconfigitem('logtoprocess', 'uiblocked',
760 757 default=None,
761 758 )
762 759 coreconfigitem('merge', 'checkunknown',
763 760 default='abort',
764 761 )
765 762 coreconfigitem('merge', 'checkignored',
766 763 default='abort',
767 764 )
768 765 coreconfigitem('experimental', 'merge.checkpathconflicts',
769 766 default=False,
770 767 )
771 768 coreconfigitem('merge', 'followcopies',
772 769 default=True,
773 770 )
774 771 coreconfigitem('merge', 'on-failure',
775 772 default='continue',
776 773 )
777 774 coreconfigitem('merge', 'preferancestor',
778 775 default=lambda: ['*'],
779 776 )
780 777 coreconfigitem('merge', 'strict-capability-check',
781 778 default=False,
782 779 )
783 780 coreconfigitem('merge-tools', '.*',
784 781 default=None,
785 782 generic=True,
786 783 )
787 784 coreconfigitem('merge-tools', br'.*\.args$',
788 785 default="$local $base $other",
789 786 generic=True,
790 787 priority=-1,
791 788 )
792 789 coreconfigitem('merge-tools', br'.*\.binary$',
793 790 default=False,
794 791 generic=True,
795 792 priority=-1,
796 793 )
797 794 coreconfigitem('merge-tools', br'.*\.check$',
798 795 default=list,
799 796 generic=True,
800 797 priority=-1,
801 798 )
802 799 coreconfigitem('merge-tools', br'.*\.checkchanged$',
803 800 default=False,
804 801 generic=True,
805 802 priority=-1,
806 803 )
807 804 coreconfigitem('merge-tools', br'.*\.executable$',
808 805 default=dynamicdefault,
809 806 generic=True,
810 807 priority=-1,
811 808 )
812 809 coreconfigitem('merge-tools', br'.*\.fixeol$',
813 810 default=False,
814 811 generic=True,
815 812 priority=-1,
816 813 )
817 814 coreconfigitem('merge-tools', br'.*\.gui$',
818 815 default=False,
819 816 generic=True,
820 817 priority=-1,
821 818 )
822 819 coreconfigitem('merge-tools', br'.*\.mergemarkers$',
823 820 default='basic',
824 821 generic=True,
825 822 priority=-1,
826 823 )
827 824 coreconfigitem('merge-tools', br'.*\.mergemarkertemplate$',
828 825 default=dynamicdefault, # take from ui.mergemarkertemplate
829 826 generic=True,
830 827 priority=-1,
831 828 )
832 829 coreconfigitem('merge-tools', br'.*\.priority$',
833 830 default=0,
834 831 generic=True,
835 832 priority=-1,
836 833 )
837 834 coreconfigitem('merge-tools', br'.*\.premerge$',
838 835 default=dynamicdefault,
839 836 generic=True,
840 837 priority=-1,
841 838 )
842 839 coreconfigitem('merge-tools', br'.*\.symlink$',
843 840 default=False,
844 841 generic=True,
845 842 priority=-1,
846 843 )
847 844 coreconfigitem('pager', 'attend-.*',
848 845 default=dynamicdefault,
849 846 generic=True,
850 847 )
851 848 coreconfigitem('pager', 'ignore',
852 849 default=list,
853 850 )
854 851 coreconfigitem('pager', 'pager',
855 852 default=dynamicdefault,
856 853 )
857 854 coreconfigitem('patch', 'eol',
858 855 default='strict',
859 856 )
860 857 coreconfigitem('patch', 'fuzz',
861 858 default=2,
862 859 )
863 860 coreconfigitem('paths', 'default',
864 861 default=None,
865 862 )
866 863 coreconfigitem('paths', 'default-push',
867 864 default=None,
868 865 )
869 866 coreconfigitem('paths', '.*',
870 867 default=None,
871 868 generic=True,
872 869 )
873 870 coreconfigitem('phases', 'checksubrepos',
874 871 default='follow',
875 872 )
876 873 coreconfigitem('phases', 'new-commit',
877 874 default='draft',
878 875 )
879 876 coreconfigitem('phases', 'publish',
880 877 default=True,
881 878 )
882 879 coreconfigitem('profiling', 'enabled',
883 880 default=False,
884 881 )
885 882 coreconfigitem('profiling', 'format',
886 883 default='text',
887 884 )
888 885 coreconfigitem('profiling', 'freq',
889 886 default=1000,
890 887 )
891 888 coreconfigitem('profiling', 'limit',
892 889 default=30,
893 890 )
894 891 coreconfigitem('profiling', 'nested',
895 892 default=0,
896 893 )
897 894 coreconfigitem('profiling', 'output',
898 895 default=None,
899 896 )
900 897 coreconfigitem('profiling', 'showmax',
901 898 default=0.999,
902 899 )
903 900 coreconfigitem('profiling', 'showmin',
904 901 default=dynamicdefault,
905 902 )
906 903 coreconfigitem('profiling', 'sort',
907 904 default='inlinetime',
908 905 )
909 906 coreconfigitem('profiling', 'statformat',
910 907 default='hotpath',
911 908 )
912 909 coreconfigitem('profiling', 'time-track',
913 910 default='cpu',
914 911 )
915 912 coreconfigitem('profiling', 'type',
916 913 default='stat',
917 914 )
918 915 coreconfigitem('progress', 'assume-tty',
919 916 default=False,
920 917 )
921 918 coreconfigitem('progress', 'changedelay',
922 919 default=1,
923 920 )
924 921 coreconfigitem('progress', 'clear-complete',
925 922 default=True,
926 923 )
927 924 coreconfigitem('progress', 'debug',
928 925 default=False,
929 926 )
930 927 coreconfigitem('progress', 'delay',
931 928 default=3,
932 929 )
933 930 coreconfigitem('progress', 'disable',
934 931 default=False,
935 932 )
936 933 coreconfigitem('progress', 'estimateinterval',
937 934 default=60.0,
938 935 )
939 936 coreconfigitem('progress', 'format',
940 937 default=lambda: ['topic', 'bar', 'number', 'estimate'],
941 938 )
942 939 coreconfigitem('progress', 'refresh',
943 940 default=0.1,
944 941 )
945 942 coreconfigitem('progress', 'width',
946 943 default=dynamicdefault,
947 944 )
948 945 coreconfigitem('push', 'pushvars.server',
949 946 default=False,
950 947 )
951 948 coreconfigitem('storage', 'revlog.optimize-delta-parent-choice',
952 949 default=True,
953 950 alias=[('format', 'aggressivemergedeltas')],
954 951 )
955 952 coreconfigitem('server', 'bookmarks-pushkey-compat',
956 953 default=True,
957 954 )
958 955 coreconfigitem('server', 'bundle1',
959 956 default=True,
960 957 )
961 958 coreconfigitem('server', 'bundle1gd',
962 959 default=None,
963 960 )
964 961 coreconfigitem('server', 'bundle1.pull',
965 962 default=None,
966 963 )
967 964 coreconfigitem('server', 'bundle1gd.pull',
968 965 default=None,
969 966 )
970 967 coreconfigitem('server', 'bundle1.push',
971 968 default=None,
972 969 )
973 970 coreconfigitem('server', 'bundle1gd.push',
974 971 default=None,
975 972 )
973 coreconfigitem('server', 'bundle2.stream',
974 default=False,
975 alias=[('experimental', 'bundle2.stream')]
976 )
976 977 coreconfigitem('server', 'compressionengines',
977 978 default=list,
978 979 )
979 980 coreconfigitem('server', 'concurrent-push-mode',
980 981 default='strict',
981 982 )
982 983 coreconfigitem('server', 'disablefullbundle',
983 984 default=False,
984 985 )
985 986 coreconfigitem('server', 'maxhttpheaderlen',
986 987 default=1024,
987 988 )
988 989 coreconfigitem('server', 'pullbundle',
989 990 default=False,
990 991 )
991 992 coreconfigitem('server', 'preferuncompressed',
992 993 default=False,
993 994 )
994 995 coreconfigitem('server', 'streamunbundle',
995 996 default=False,
996 997 )
997 998 coreconfigitem('server', 'uncompressed',
998 999 default=True,
999 1000 )
1000 1001 coreconfigitem('server', 'uncompressedallowsecret',
1001 1002 default=False,
1002 1003 )
1003 1004 coreconfigitem('server', 'validate',
1004 1005 default=False,
1005 1006 )
1006 1007 coreconfigitem('server', 'zliblevel',
1007 1008 default=-1,
1008 1009 )
1009 1010 coreconfigitem('server', 'zstdlevel',
1010 1011 default=3,
1011 1012 )
1012 1013 coreconfigitem('share', 'pool',
1013 1014 default=None,
1014 1015 )
1015 1016 coreconfigitem('share', 'poolnaming',
1016 1017 default='identity',
1017 1018 )
1018 1019 coreconfigitem('smtp', 'host',
1019 1020 default=None,
1020 1021 )
1021 1022 coreconfigitem('smtp', 'local_hostname',
1022 1023 default=None,
1023 1024 )
1024 1025 coreconfigitem('smtp', 'password',
1025 1026 default=None,
1026 1027 )
1027 1028 coreconfigitem('smtp', 'port',
1028 1029 default=dynamicdefault,
1029 1030 )
1030 1031 coreconfigitem('smtp', 'tls',
1031 1032 default='none',
1032 1033 )
1033 1034 coreconfigitem('smtp', 'username',
1034 1035 default=None,
1035 1036 )
1036 1037 coreconfigitem('sparse', 'missingwarning',
1037 1038 default=True,
1038 1039 )
1039 1040 coreconfigitem('subrepos', 'allowed',
1040 1041 default=dynamicdefault, # to make backporting simpler
1041 1042 )
1042 1043 coreconfigitem('subrepos', 'hg:allowed',
1043 1044 default=dynamicdefault,
1044 1045 )
1045 1046 coreconfigitem('subrepos', 'git:allowed',
1046 1047 default=dynamicdefault,
1047 1048 )
1048 1049 coreconfigitem('subrepos', 'svn:allowed',
1049 1050 default=dynamicdefault,
1050 1051 )
1051 1052 coreconfigitem('templates', '.*',
1052 1053 default=None,
1053 1054 generic=True,
1054 1055 )
1055 1056 coreconfigitem('trusted', 'groups',
1056 1057 default=list,
1057 1058 )
1058 1059 coreconfigitem('trusted', 'users',
1059 1060 default=list,
1060 1061 )
1061 1062 coreconfigitem('ui', '_usedassubrepo',
1062 1063 default=False,
1063 1064 )
1064 1065 coreconfigitem('ui', 'allowemptycommit',
1065 1066 default=False,
1066 1067 )
1067 1068 coreconfigitem('ui', 'archivemeta',
1068 1069 default=True,
1069 1070 )
1070 1071 coreconfigitem('ui', 'askusername',
1071 1072 default=False,
1072 1073 )
1073 1074 coreconfigitem('ui', 'clonebundlefallback',
1074 1075 default=False,
1075 1076 )
1076 1077 coreconfigitem('ui', 'clonebundleprefers',
1077 1078 default=list,
1078 1079 )
1079 1080 coreconfigitem('ui', 'clonebundles',
1080 1081 default=True,
1081 1082 )
1082 1083 coreconfigitem('ui', 'color',
1083 1084 default='auto',
1084 1085 )
1085 1086 coreconfigitem('ui', 'commitsubrepos',
1086 1087 default=False,
1087 1088 )
1088 1089 coreconfigitem('ui', 'debug',
1089 1090 default=False,
1090 1091 )
1091 1092 coreconfigitem('ui', 'debugger',
1092 1093 default=None,
1093 1094 )
1094 1095 coreconfigitem('ui', 'editor',
1095 1096 default=dynamicdefault,
1096 1097 )
1097 1098 coreconfigitem('ui', 'fallbackencoding',
1098 1099 default=None,
1099 1100 )
1100 1101 coreconfigitem('ui', 'forcecwd',
1101 1102 default=None,
1102 1103 )
1103 1104 coreconfigitem('ui', 'forcemerge',
1104 1105 default=None,
1105 1106 )
1106 1107 coreconfigitem('ui', 'formatdebug',
1107 1108 default=False,
1108 1109 )
1109 1110 coreconfigitem('ui', 'formatjson',
1110 1111 default=False,
1111 1112 )
1112 1113 coreconfigitem('ui', 'formatted',
1113 1114 default=None,
1114 1115 )
1115 1116 coreconfigitem('ui', 'graphnodetemplate',
1116 1117 default=None,
1117 1118 )
1118 1119 coreconfigitem('ui', 'history-editing-backup',
1119 1120 default=True,
1120 1121 )
1121 1122 coreconfigitem('ui', 'interactive',
1122 1123 default=None,
1123 1124 )
1124 1125 coreconfigitem('ui', 'interface',
1125 1126 default=None,
1126 1127 )
1127 1128 coreconfigitem('ui', 'interface.chunkselector',
1128 1129 default=None,
1129 1130 )
1130 1131 coreconfigitem('ui', 'large-file-limit',
1131 1132 default=10000000,
1132 1133 )
1133 1134 coreconfigitem('ui', 'logblockedtimes',
1134 1135 default=False,
1135 1136 )
1136 1137 coreconfigitem('ui', 'logtemplate',
1137 1138 default=None,
1138 1139 )
1139 1140 coreconfigitem('ui', 'merge',
1140 1141 default=None,
1141 1142 )
1142 1143 coreconfigitem('ui', 'mergemarkers',
1143 1144 default='basic',
1144 1145 )
1145 1146 coreconfigitem('ui', 'mergemarkertemplate',
1146 1147 default=('{node|short} '
1147 1148 '{ifeq(tags, "tip", "", '
1148 1149 'ifeq(tags, "", "", "{tags} "))}'
1149 1150 '{if(bookmarks, "{bookmarks} ")}'
1150 1151 '{ifeq(branch, "default", "", "{branch} ")}'
1151 1152 '- {author|user}: {desc|firstline}')
1152 1153 )
1153 1154 coreconfigitem('ui', 'nontty',
1154 1155 default=False,
1155 1156 )
1156 1157 coreconfigitem('ui', 'origbackuppath',
1157 1158 default=None,
1158 1159 )
1159 1160 coreconfigitem('ui', 'paginate',
1160 1161 default=True,
1161 1162 )
1162 1163 coreconfigitem('ui', 'patch',
1163 1164 default=None,
1164 1165 )
1165 1166 coreconfigitem('ui', 'portablefilenames',
1166 1167 default='warn',
1167 1168 )
1168 1169 coreconfigitem('ui', 'promptecho',
1169 1170 default=False,
1170 1171 )
1171 1172 coreconfigitem('ui', 'quiet',
1172 1173 default=False,
1173 1174 )
1174 1175 coreconfigitem('ui', 'quietbookmarkmove',
1175 1176 default=False,
1176 1177 )
1177 1178 coreconfigitem('ui', 'remotecmd',
1178 1179 default='hg',
1179 1180 )
1180 1181 coreconfigitem('ui', 'report_untrusted',
1181 1182 default=True,
1182 1183 )
1183 1184 coreconfigitem('ui', 'rollback',
1184 1185 default=True,
1185 1186 )
1186 1187 coreconfigitem('ui', 'signal-safe-lock',
1187 1188 default=True,
1188 1189 )
1189 1190 coreconfigitem('ui', 'slash',
1190 1191 default=False,
1191 1192 )
1192 1193 coreconfigitem('ui', 'ssh',
1193 1194 default='ssh',
1194 1195 )
1195 1196 coreconfigitem('ui', 'ssherrorhint',
1196 1197 default=None,
1197 1198 )
1198 1199 coreconfigitem('ui', 'statuscopies',
1199 1200 default=False,
1200 1201 )
1201 1202 coreconfigitem('ui', 'strict',
1202 1203 default=False,
1203 1204 )
1204 1205 coreconfigitem('ui', 'style',
1205 1206 default='',
1206 1207 )
1207 1208 coreconfigitem('ui', 'supportcontact',
1208 1209 default=None,
1209 1210 )
1210 1211 coreconfigitem('ui', 'textwidth',
1211 1212 default=78,
1212 1213 )
1213 1214 coreconfigitem('ui', 'timeout',
1214 1215 default='600',
1215 1216 )
1216 1217 coreconfigitem('ui', 'timeout.warn',
1217 1218 default=0,
1218 1219 )
1219 1220 coreconfigitem('ui', 'traceback',
1220 1221 default=False,
1221 1222 )
1222 1223 coreconfigitem('ui', 'tweakdefaults',
1223 1224 default=False,
1224 1225 )
1225 1226 coreconfigitem('ui', 'username',
1226 1227 alias=[('ui', 'user')]
1227 1228 )
1228 1229 coreconfigitem('ui', 'verbose',
1229 1230 default=False,
1230 1231 )
1231 1232 coreconfigitem('verify', 'skipflags',
1232 1233 default=None,
1233 1234 )
1234 1235 coreconfigitem('web', 'allowbz2',
1235 1236 default=False,
1236 1237 )
1237 1238 coreconfigitem('web', 'allowgz',
1238 1239 default=False,
1239 1240 )
1240 1241 coreconfigitem('web', 'allow-pull',
1241 1242 alias=[('web', 'allowpull')],
1242 1243 default=True,
1243 1244 )
1244 1245 coreconfigitem('web', 'allow-push',
1245 1246 alias=[('web', 'allow_push')],
1246 1247 default=list,
1247 1248 )
1248 1249 coreconfigitem('web', 'allowzip',
1249 1250 default=False,
1250 1251 )
1251 1252 coreconfigitem('web', 'archivesubrepos',
1252 1253 default=False,
1253 1254 )
1254 1255 coreconfigitem('web', 'cache',
1255 1256 default=True,
1256 1257 )
1257 1258 coreconfigitem('web', 'contact',
1258 1259 default=None,
1259 1260 )
1260 1261 coreconfigitem('web', 'deny_push',
1261 1262 default=list,
1262 1263 )
1263 1264 coreconfigitem('web', 'guessmime',
1264 1265 default=False,
1265 1266 )
1266 1267 coreconfigitem('web', 'hidden',
1267 1268 default=False,
1268 1269 )
1269 1270 coreconfigitem('web', 'labels',
1270 1271 default=list,
1271 1272 )
1272 1273 coreconfigitem('web', 'logoimg',
1273 1274 default='hglogo.png',
1274 1275 )
1275 1276 coreconfigitem('web', 'logourl',
1276 1277 default='https://mercurial-scm.org/',
1277 1278 )
1278 1279 coreconfigitem('web', 'accesslog',
1279 1280 default='-',
1280 1281 )
1281 1282 coreconfigitem('web', 'address',
1282 1283 default='',
1283 1284 )
1284 1285 coreconfigitem('web', 'allow-archive',
1285 1286 alias=[('web', 'allow_archive')],
1286 1287 default=list,
1287 1288 )
1288 1289 coreconfigitem('web', 'allow_read',
1289 1290 default=list,
1290 1291 )
1291 1292 coreconfigitem('web', 'baseurl',
1292 1293 default=None,
1293 1294 )
1294 1295 coreconfigitem('web', 'cacerts',
1295 1296 default=None,
1296 1297 )
1297 1298 coreconfigitem('web', 'certificate',
1298 1299 default=None,
1299 1300 )
1300 1301 coreconfigitem('web', 'collapse',
1301 1302 default=False,
1302 1303 )
1303 1304 coreconfigitem('web', 'csp',
1304 1305 default=None,
1305 1306 )
1306 1307 coreconfigitem('web', 'deny_read',
1307 1308 default=list,
1308 1309 )
1309 1310 coreconfigitem('web', 'descend',
1310 1311 default=True,
1311 1312 )
1312 1313 coreconfigitem('web', 'description',
1313 1314 default="",
1314 1315 )
1315 1316 coreconfigitem('web', 'encoding',
1316 1317 default=lambda: encoding.encoding,
1317 1318 )
1318 1319 coreconfigitem('web', 'errorlog',
1319 1320 default='-',
1320 1321 )
1321 1322 coreconfigitem('web', 'ipv6',
1322 1323 default=False,
1323 1324 )
1324 1325 coreconfigitem('web', 'maxchanges',
1325 1326 default=10,
1326 1327 )
1327 1328 coreconfigitem('web', 'maxfiles',
1328 1329 default=10,
1329 1330 )
1330 1331 coreconfigitem('web', 'maxshortchanges',
1331 1332 default=60,
1332 1333 )
1333 1334 coreconfigitem('web', 'motd',
1334 1335 default='',
1335 1336 )
1336 1337 coreconfigitem('web', 'name',
1337 1338 default=dynamicdefault,
1338 1339 )
1339 1340 coreconfigitem('web', 'port',
1340 1341 default=8000,
1341 1342 )
1342 1343 coreconfigitem('web', 'prefix',
1343 1344 default='',
1344 1345 )
1345 1346 coreconfigitem('web', 'push_ssl',
1346 1347 default=True,
1347 1348 )
1348 1349 coreconfigitem('web', 'refreshinterval',
1349 1350 default=20,
1350 1351 )
1351 1352 coreconfigitem('web', 'server-header',
1352 1353 default=None,
1353 1354 )
1354 1355 coreconfigitem('web', 'staticurl',
1355 1356 default=None,
1356 1357 )
1357 1358 coreconfigitem('web', 'stripes',
1358 1359 default=1,
1359 1360 )
1360 1361 coreconfigitem('web', 'style',
1361 1362 default='paper',
1362 1363 )
1363 1364 coreconfigitem('web', 'templates',
1364 1365 default=None,
1365 1366 )
1366 1367 coreconfigitem('web', 'view',
1367 1368 default='served',
1368 1369 )
1369 1370 coreconfigitem('worker', 'backgroundclose',
1370 1371 default=dynamicdefault,
1371 1372 )
1372 1373 # Windows defaults to a limit of 512 open files. A buffer of 128
1373 1374 # should give us enough headway.
1374 1375 coreconfigitem('worker', 'backgroundclosemaxqueue',
1375 1376 default=384,
1376 1377 )
1377 1378 coreconfigitem('worker', 'backgroundcloseminfilecount',
1378 1379 default=2048,
1379 1380 )
1380 1381 coreconfigitem('worker', 'backgroundclosethreadcount',
1381 1382 default=4,
1382 1383 )
1383 1384 coreconfigitem('worker', 'enabled',
1384 1385 default=True,
1385 1386 )
1386 1387 coreconfigitem('worker', 'numcpus',
1387 1388 default=None,
1388 1389 )
1389 1390
1390 1391 # Rebase related configuration moved to core because other extension are doing
1391 1392 # strange things. For example, shelve import the extensions to reuse some bit
1392 1393 # without formally loading it.
1393 1394 coreconfigitem('commands', 'rebase.requiredest',
1394 1395 default=False,
1395 1396 )
1396 1397 coreconfigitem('experimental', 'rebaseskipobsolete',
1397 1398 default=True,
1398 1399 )
1399 1400 coreconfigitem('rebase', 'singletransaction',
1400 1401 default=False,
1401 1402 )
1402 1403 coreconfigitem('rebase', 'experimental.inmemory',
1403 1404 default=False,
1404 1405 )
@@ -1,2715 +1,2719 b''
1 1 The Mercurial system uses a set of configuration files to control
2 2 aspects of its behavior.
3 3
4 4 Troubleshooting
5 5 ===============
6 6
7 7 If you're having problems with your configuration,
8 8 :hg:`config --debug` can help you understand what is introducing
9 9 a setting into your environment.
10 10
11 11 See :hg:`help config.syntax` and :hg:`help config.files`
12 12 for information about how and where to override things.
13 13
14 14 Structure
15 15 =========
16 16
17 17 The configuration files use a simple ini-file format. A configuration
18 18 file consists of sections, led by a ``[section]`` header and followed
19 19 by ``name = value`` entries::
20 20
21 21 [ui]
22 22 username = Firstname Lastname <firstname.lastname@example.net>
23 23 verbose = True
24 24
25 25 The above entries will be referred to as ``ui.username`` and
26 26 ``ui.verbose``, respectively. See :hg:`help config.syntax`.
27 27
28 28 Files
29 29 =====
30 30
31 31 Mercurial reads configuration data from several files, if they exist.
32 32 These files do not exist by default and you will have to create the
33 33 appropriate configuration files yourself:
34 34
35 35 Local configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
36 36
37 37 Global configuration like the username setting is typically put into:
38 38
39 39 .. container:: windows
40 40
41 41 - ``%USERPROFILE%\mercurial.ini`` (on Windows)
42 42
43 43 .. container:: unix.plan9
44 44
45 45 - ``$HOME/.hgrc`` (on Unix, Plan9)
46 46
47 47 The names of these files depend on the system on which Mercurial is
48 48 installed. ``*.rc`` files from a single directory are read in
49 49 alphabetical order, later ones overriding earlier ones. Where multiple
50 50 paths are given below, settings from earlier paths override later
51 51 ones.
52 52
53 53 .. container:: verbose.unix
54 54
55 55 On Unix, the following files are consulted:
56 56
57 57 - ``<repo>/.hg/hgrc`` (per-repository)
58 58 - ``$HOME/.hgrc`` (per-user)
59 59 - ``${XDG_CONFIG_HOME:-$HOME/.config}/hg/hgrc`` (per-user)
60 60 - ``<install-root>/etc/mercurial/hgrc`` (per-installation)
61 61 - ``<install-root>/etc/mercurial/hgrc.d/*.rc`` (per-installation)
62 62 - ``/etc/mercurial/hgrc`` (per-system)
63 63 - ``/etc/mercurial/hgrc.d/*.rc`` (per-system)
64 64 - ``<internal>/default.d/*.rc`` (defaults)
65 65
66 66 .. container:: verbose.windows
67 67
68 68 On Windows, the following files are consulted:
69 69
70 70 - ``<repo>/.hg/hgrc`` (per-repository)
71 71 - ``%USERPROFILE%\.hgrc`` (per-user)
72 72 - ``%USERPROFILE%\Mercurial.ini`` (per-user)
73 73 - ``%HOME%\.hgrc`` (per-user)
74 74 - ``%HOME%\Mercurial.ini`` (per-user)
75 75 - ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` (per-installation)
76 76 - ``<install-dir>\hgrc.d\*.rc`` (per-installation)
77 77 - ``<install-dir>\Mercurial.ini`` (per-installation)
78 78 - ``<internal>/default.d/*.rc`` (defaults)
79 79
80 80 .. note::
81 81
82 82 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
83 83 is used when running 32-bit Python on 64-bit Windows.
84 84
85 85 .. container:: windows
86 86
87 87 On Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``.
88 88
89 89 .. container:: verbose.plan9
90 90
91 91 On Plan9, the following files are consulted:
92 92
93 93 - ``<repo>/.hg/hgrc`` (per-repository)
94 94 - ``$home/lib/hgrc`` (per-user)
95 95 - ``<install-root>/lib/mercurial/hgrc`` (per-installation)
96 96 - ``<install-root>/lib/mercurial/hgrc.d/*.rc`` (per-installation)
97 97 - ``/lib/mercurial/hgrc`` (per-system)
98 98 - ``/lib/mercurial/hgrc.d/*.rc`` (per-system)
99 99 - ``<internal>/default.d/*.rc`` (defaults)
100 100
101 101 Per-repository configuration options only apply in a
102 102 particular repository. This file is not version-controlled, and
103 103 will not get transferred during a "clone" operation. Options in
104 104 this file override options in all other configuration files.
105 105
106 106 .. container:: unix.plan9
107 107
108 108 On Plan 9 and Unix, most of this file will be ignored if it doesn't
109 109 belong to a trusted user or to a trusted group. See
110 110 :hg:`help config.trusted` for more details.
111 111
112 112 Per-user configuration file(s) are for the user running Mercurial. Options
113 113 in these files apply to all Mercurial commands executed by this user in any
114 114 directory. Options in these files override per-system and per-installation
115 115 options.
116 116
117 117 Per-installation configuration files are searched for in the
118 118 directory where Mercurial is installed. ``<install-root>`` is the
119 119 parent directory of the **hg** executable (or symlink) being run.
120 120
121 121 .. container:: unix.plan9
122 122
123 123 For example, if installed in ``/shared/tools/bin/hg``, Mercurial
124 124 will look in ``/shared/tools/etc/mercurial/hgrc``. Options in these
125 125 files apply to all Mercurial commands executed by any user in any
126 126 directory.
127 127
128 128 Per-installation configuration files are for the system on
129 129 which Mercurial is running. Options in these files apply to all
130 130 Mercurial commands executed by any user in any directory. Registry
131 131 keys contain PATH-like strings, every part of which must reference
132 132 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
133 133 be read. Mercurial checks each of these locations in the specified
134 134 order until one or more configuration files are detected.
135 135
136 136 Per-system configuration files are for the system on which Mercurial
137 137 is running. Options in these files apply to all Mercurial commands
138 138 executed by any user in any directory. Options in these files
139 139 override per-installation options.
140 140
141 141 Mercurial comes with some default configuration. The default configuration
142 142 files are installed with Mercurial and will be overwritten on upgrades. Default
143 143 configuration files should never be edited by users or administrators but can
144 144 be overridden in other configuration files. So far the directory only contains
145 145 merge tool configuration but packagers can also put other default configuration
146 146 there.
147 147
148 148 Syntax
149 149 ======
150 150
151 151 A configuration file consists of sections, led by a ``[section]`` header
152 152 and followed by ``name = value`` entries (sometimes called
153 153 ``configuration keys``)::
154 154
155 155 [spam]
156 156 eggs=ham
157 157 green=
158 158 eggs
159 159
160 160 Each line contains one entry. If the lines that follow are indented,
161 161 they are treated as continuations of that entry. Leading whitespace is
162 162 removed from values. Empty lines are skipped. Lines beginning with
163 163 ``#`` or ``;`` are ignored and may be used to provide comments.
164 164
165 165 Configuration keys can be set multiple times, in which case Mercurial
166 166 will use the value that was configured last. As an example::
167 167
168 168 [spam]
169 169 eggs=large
170 170 ham=serrano
171 171 eggs=small
172 172
173 173 This would set the configuration key named ``eggs`` to ``small``.
174 174
175 175 It is also possible to define a section multiple times. A section can
176 176 be redefined on the same and/or on different configuration files. For
177 177 example::
178 178
179 179 [foo]
180 180 eggs=large
181 181 ham=serrano
182 182 eggs=small
183 183
184 184 [bar]
185 185 eggs=ham
186 186 green=
187 187 eggs
188 188
189 189 [foo]
190 190 ham=prosciutto
191 191 eggs=medium
192 192 bread=toasted
193 193
194 194 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
195 195 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
196 196 respectively. As you can see there only thing that matters is the last
197 197 value that was set for each of the configuration keys.
198 198
199 199 If a configuration key is set multiple times in different
200 200 configuration files the final value will depend on the order in which
201 201 the different configuration files are read, with settings from earlier
202 202 paths overriding later ones as described on the ``Files`` section
203 203 above.
204 204
205 205 A line of the form ``%include file`` will include ``file`` into the
206 206 current configuration file. The inclusion is recursive, which means
207 207 that included files can include other files. Filenames are relative to
208 208 the configuration file in which the ``%include`` directive is found.
209 209 Environment variables and ``~user`` constructs are expanded in
210 210 ``file``. This lets you do something like::
211 211
212 212 %include ~/.hgrc.d/$HOST.rc
213 213
214 214 to include a different configuration file on each computer you use.
215 215
216 216 A line with ``%unset name`` will remove ``name`` from the current
217 217 section, if it has been set previously.
218 218
219 219 The values are either free-form text strings, lists of text strings,
220 220 or Boolean values. Boolean values can be set to true using any of "1",
221 221 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
222 222 (all case insensitive).
223 223
224 224 List values are separated by whitespace or comma, except when values are
225 225 placed in double quotation marks::
226 226
227 227 allow_read = "John Doe, PhD", brian, betty
228 228
229 229 Quotation marks can be escaped by prefixing them with a backslash. Only
230 230 quotation marks at the beginning of a word is counted as a quotation
231 231 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
232 232
233 233 Sections
234 234 ========
235 235
236 236 This section describes the different sections that may appear in a
237 237 Mercurial configuration file, the purpose of each section, its possible
238 238 keys, and their possible values.
239 239
240 240 ``alias``
241 241 ---------
242 242
243 243 Defines command aliases.
244 244
245 245 Aliases allow you to define your own commands in terms of other
246 246 commands (or aliases), optionally including arguments. Positional
247 247 arguments in the form of ``$1``, ``$2``, etc. in the alias definition
248 248 are expanded by Mercurial before execution. Positional arguments not
249 249 already used by ``$N`` in the definition are put at the end of the
250 250 command to be executed.
251 251
252 252 Alias definitions consist of lines of the form::
253 253
254 254 <alias> = <command> [<argument>]...
255 255
256 256 For example, this definition::
257 257
258 258 latest = log --limit 5
259 259
260 260 creates a new command ``latest`` that shows only the five most recent
261 261 changesets. You can define subsequent aliases using earlier ones::
262 262
263 263 stable5 = latest -b stable
264 264
265 265 .. note::
266 266
267 267 It is possible to create aliases with the same names as
268 268 existing commands, which will then override the original
269 269 definitions. This is almost always a bad idea!
270 270
271 271 An alias can start with an exclamation point (``!``) to make it a
272 272 shell alias. A shell alias is executed with the shell and will let you
273 273 run arbitrary commands. As an example, ::
274 274
275 275 echo = !echo $@
276 276
277 277 will let you do ``hg echo foo`` to have ``foo`` printed in your
278 278 terminal. A better example might be::
279 279
280 280 purge = !$HG status --no-status --unknown -0 re: | xargs -0 rm -f
281 281
282 282 which will make ``hg purge`` delete all unknown files in the
283 283 repository in the same manner as the purge extension.
284 284
285 285 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
286 286 expand to the command arguments. Unmatched arguments are
287 287 removed. ``$0`` expands to the alias name and ``$@`` expands to all
288 288 arguments separated by a space. ``"$@"`` (with quotes) expands to all
289 289 arguments quoted individually and separated by a space. These expansions
290 290 happen before the command is passed to the shell.
291 291
292 292 Shell aliases are executed in an environment where ``$HG`` expands to
293 293 the path of the Mercurial that was used to execute the alias. This is
294 294 useful when you want to call further Mercurial commands in a shell
295 295 alias, as was done above for the purge alias. In addition,
296 296 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
297 297 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
298 298
299 299 .. note::
300 300
301 301 Some global configuration options such as ``-R`` are
302 302 processed before shell aliases and will thus not be passed to
303 303 aliases.
304 304
305 305
306 306 ``annotate``
307 307 ------------
308 308
309 309 Settings used when displaying file annotations. All values are
310 310 Booleans and default to False. See :hg:`help config.diff` for
311 311 related options for the diff command.
312 312
313 313 ``ignorews``
314 314 Ignore white space when comparing lines.
315 315
316 316 ``ignorewseol``
317 317 Ignore white space at the end of a line when comparing lines.
318 318
319 319 ``ignorewsamount``
320 320 Ignore changes in the amount of white space.
321 321
322 322 ``ignoreblanklines``
323 323 Ignore changes whose lines are all blank.
324 324
325 325
326 326 ``auth``
327 327 --------
328 328
329 329 Authentication credentials and other authentication-like configuration
330 330 for HTTP connections. This section allows you to store usernames and
331 331 passwords for use when logging *into* HTTP servers. See
332 332 :hg:`help config.web` if you want to configure *who* can login to
333 333 your HTTP server.
334 334
335 335 The following options apply to all hosts.
336 336
337 337 ``cookiefile``
338 338 Path to a file containing HTTP cookie lines. Cookies matching a
339 339 host will be sent automatically.
340 340
341 341 The file format uses the Mozilla cookies.txt format, which defines cookies
342 342 on their own lines. Each line contains 7 fields delimited by the tab
343 343 character (domain, is_domain_cookie, path, is_secure, expires, name,
344 344 value). For more info, do an Internet search for "Netscape cookies.txt
345 345 format."
346 346
347 347 Note: the cookies parser does not handle port numbers on domains. You
348 348 will need to remove ports from the domain for the cookie to be recognized.
349 349 This could result in a cookie being disclosed to an unwanted server.
350 350
351 351 The cookies file is read-only.
352 352
353 353 Other options in this section are grouped by name and have the following
354 354 format::
355 355
356 356 <name>.<argument> = <value>
357 357
358 358 where ``<name>`` is used to group arguments into authentication
359 359 entries. Example::
360 360
361 361 foo.prefix = hg.intevation.de/mercurial
362 362 foo.username = foo
363 363 foo.password = bar
364 364 foo.schemes = http https
365 365
366 366 bar.prefix = secure.example.org
367 367 bar.key = path/to/file.key
368 368 bar.cert = path/to/file.cert
369 369 bar.schemes = https
370 370
371 371 Supported arguments:
372 372
373 373 ``prefix``
374 374 Either ``*`` or a URI prefix with or without the scheme part.
375 375 The authentication entry with the longest matching prefix is used
376 376 (where ``*`` matches everything and counts as a match of length
377 377 1). If the prefix doesn't include a scheme, the match is performed
378 378 against the URI with its scheme stripped as well, and the schemes
379 379 argument, q.v., is then subsequently consulted.
380 380
381 381 ``username``
382 382 Optional. Username to authenticate with. If not given, and the
383 383 remote site requires basic or digest authentication, the user will
384 384 be prompted for it. Environment variables are expanded in the
385 385 username letting you do ``foo.username = $USER``. If the URI
386 386 includes a username, only ``[auth]`` entries with a matching
387 387 username or without a username will be considered.
388 388
389 389 ``password``
390 390 Optional. Password to authenticate with. If not given, and the
391 391 remote site requires basic or digest authentication, the user
392 392 will be prompted for it.
393 393
394 394 ``key``
395 395 Optional. PEM encoded client certificate key file. Environment
396 396 variables are expanded in the filename.
397 397
398 398 ``cert``
399 399 Optional. PEM encoded client certificate chain file. Environment
400 400 variables are expanded in the filename.
401 401
402 402 ``schemes``
403 403 Optional. Space separated list of URI schemes to use this
404 404 authentication entry with. Only used if the prefix doesn't include
405 405 a scheme. Supported schemes are http and https. They will match
406 406 static-http and static-https respectively, as well.
407 407 (default: https)
408 408
409 409 If no suitable authentication entry is found, the user is prompted
410 410 for credentials as usual if required by the remote.
411 411
412 412 ``color``
413 413 ---------
414 414
415 415 Configure the Mercurial color mode. For details about how to define your custom
416 416 effect and style see :hg:`help color`.
417 417
418 418 ``mode``
419 419 String: control the method used to output color. One of ``auto``, ``ansi``,
420 420 ``win32``, ``terminfo`` or ``debug``. In auto mode, Mercurial will
421 421 use ANSI mode by default (or win32 mode prior to Windows 10) if it detects a
422 422 terminal. Any invalid value will disable color.
423 423
424 424 ``pagermode``
425 425 String: optional override of ``color.mode`` used with pager.
426 426
427 427 On some systems, terminfo mode may cause problems when using
428 428 color with ``less -R`` as a pager program. less with the -R option
429 429 will only display ECMA-48 color codes, and terminfo mode may sometimes
430 430 emit codes that less doesn't understand. You can work around this by
431 431 either using ansi mode (or auto mode), or by using less -r (which will
432 432 pass through all terminal control codes, not just color control
433 433 codes).
434 434
435 435 On some systems (such as MSYS in Windows), the terminal may support
436 436 a different color mode than the pager program.
437 437
438 438 ``commands``
439 439 ------------
440 440
441 441 ``resolve.confirm``
442 442 Confirm before performing action if no filename is passed.
443 443 (default: False)
444 444
445 445 ``resolve.explicit-re-merge``
446 446 Require uses of ``hg resolve`` to specify which action it should perform,
447 447 instead of re-merging files by default.
448 448 (default: False)
449 449
450 450 ``resolve.mark-check``
451 451 Determines what level of checking :hg:`resolve --mark` will perform before
452 452 marking files as resolved. Valid values are ``none`, ``warn``, and
453 453 ``abort``. ``warn`` will output a warning listing the file(s) that still
454 454 have conflict markers in them, but will still mark everything resolved.
455 455 ``abort`` will output the same warning but will not mark things as resolved.
456 456 If --all is passed and this is set to ``abort``, only a warning will be
457 457 shown (an error will not be raised).
458 458 (default: ``none``)
459 459
460 460 ``status.relative``
461 461 Make paths in :hg:`status` output relative to the current directory.
462 462 (default: False)
463 463
464 464 ``status.terse``
465 465 Default value for the --terse flag, which condenes status output.
466 466 (default: empty)
467 467
468 468 ``update.check``
469 469 Determines what level of checking :hg:`update` will perform before moving
470 470 to a destination revision. Valid values are ``abort``, ``none``,
471 471 ``linear``, and ``noconflict``. ``abort`` always fails if the working
472 472 directory has uncommitted changes. ``none`` performs no checking, and may
473 473 result in a merge with uncommitted changes. ``linear`` allows any update
474 474 as long as it follows a straight line in the revision history, and may
475 475 trigger a merge with uncommitted changes. ``noconflict`` will allow any
476 476 update which would not trigger a merge with uncommitted changes, if any
477 477 are present.
478 478 (default: ``linear``)
479 479
480 480 ``update.requiredest``
481 481 Require that the user pass a destination when running :hg:`update`.
482 482 For example, :hg:`update .::` will be allowed, but a plain :hg:`update`
483 483 will be disallowed.
484 484 (default: False)
485 485
486 486 ``committemplate``
487 487 ------------------
488 488
489 489 ``changeset``
490 490 String: configuration in this section is used as the template to
491 491 customize the text shown in the editor when committing.
492 492
493 493 In addition to pre-defined template keywords, commit log specific one
494 494 below can be used for customization:
495 495
496 496 ``extramsg``
497 497 String: Extra message (typically 'Leave message empty to abort
498 498 commit.'). This may be changed by some commands or extensions.
499 499
500 500 For example, the template configuration below shows as same text as
501 501 one shown by default::
502 502
503 503 [committemplate]
504 504 changeset = {desc}\n\n
505 505 HG: Enter commit message. Lines beginning with 'HG:' are removed.
506 506 HG: {extramsg}
507 507 HG: --
508 508 HG: user: {author}\n{ifeq(p2rev, "-1", "",
509 509 "HG: branch merge\n")
510 510 }HG: branch '{branch}'\n{if(activebookmark,
511 511 "HG: bookmark '{activebookmark}'\n") }{subrepos %
512 512 "HG: subrepo {subrepo}\n" }{file_adds %
513 513 "HG: added {file}\n" }{file_mods %
514 514 "HG: changed {file}\n" }{file_dels %
515 515 "HG: removed {file}\n" }{if(files, "",
516 516 "HG: no files changed\n")}
517 517
518 518 ``diff()``
519 519 String: show the diff (see :hg:`help templates` for detail)
520 520
521 521 Sometimes it is helpful to show the diff of the changeset in the editor without
522 522 having to prefix 'HG: ' to each line so that highlighting works correctly. For
523 523 this, Mercurial provides a special string which will ignore everything below
524 524 it::
525 525
526 526 HG: ------------------------ >8 ------------------------
527 527
528 528 For example, the template configuration below will show the diff below the
529 529 extra message::
530 530
531 531 [committemplate]
532 532 changeset = {desc}\n\n
533 533 HG: Enter commit message. Lines beginning with 'HG:' are removed.
534 534 HG: {extramsg}
535 535 HG: ------------------------ >8 ------------------------
536 536 HG: Do not touch the line above.
537 537 HG: Everything below will be removed.
538 538 {diff()}
539 539
540 540 .. note::
541 541
542 542 For some problematic encodings (see :hg:`help win32mbcs` for
543 543 detail), this customization should be configured carefully, to
544 544 avoid showing broken characters.
545 545
546 546 For example, if a multibyte character ending with backslash (0x5c) is
547 547 followed by the ASCII character 'n' in the customized template,
548 548 the sequence of backslash and 'n' is treated as line-feed unexpectedly
549 549 (and the multibyte character is broken, too).
550 550
551 551 Customized template is used for commands below (``--edit`` may be
552 552 required):
553 553
554 554 - :hg:`backout`
555 555 - :hg:`commit`
556 556 - :hg:`fetch` (for merge commit only)
557 557 - :hg:`graft`
558 558 - :hg:`histedit`
559 559 - :hg:`import`
560 560 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
561 561 - :hg:`rebase`
562 562 - :hg:`shelve`
563 563 - :hg:`sign`
564 564 - :hg:`tag`
565 565 - :hg:`transplant`
566 566
567 567 Configuring items below instead of ``changeset`` allows showing
568 568 customized message only for specific actions, or showing different
569 569 messages for each action.
570 570
571 571 - ``changeset.backout`` for :hg:`backout`
572 572 - ``changeset.commit.amend.merge`` for :hg:`commit --amend` on merges
573 573 - ``changeset.commit.amend.normal`` for :hg:`commit --amend` on other
574 574 - ``changeset.commit.normal.merge`` for :hg:`commit` on merges
575 575 - ``changeset.commit.normal.normal`` for :hg:`commit` on other
576 576 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
577 577 - ``changeset.gpg.sign`` for :hg:`sign`
578 578 - ``changeset.graft`` for :hg:`graft`
579 579 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
580 580 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
581 581 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
582 582 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
583 583 - ``changeset.import.bypass`` for :hg:`import --bypass`
584 584 - ``changeset.import.normal.merge`` for :hg:`import` on merges
585 585 - ``changeset.import.normal.normal`` for :hg:`import` on other
586 586 - ``changeset.mq.qnew`` for :hg:`qnew`
587 587 - ``changeset.mq.qfold`` for :hg:`qfold`
588 588 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
589 589 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
590 590 - ``changeset.rebase.merge`` for :hg:`rebase` on merges
591 591 - ``changeset.rebase.normal`` for :hg:`rebase` on other
592 592 - ``changeset.shelve.shelve`` for :hg:`shelve`
593 593 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
594 594 - ``changeset.tag.remove`` for :hg:`tag --remove`
595 595 - ``changeset.transplant.merge`` for :hg:`transplant` on merges
596 596 - ``changeset.transplant.normal`` for :hg:`transplant` on other
597 597
598 598 These dot-separated lists of names are treated as hierarchical ones.
599 599 For example, ``changeset.tag.remove`` customizes the commit message
600 600 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
601 601 commit message for :hg:`tag` regardless of ``--remove`` option.
602 602
603 603 When the external editor is invoked for a commit, the corresponding
604 604 dot-separated list of names without the ``changeset.`` prefix
605 605 (e.g. ``commit.normal.normal``) is in the ``HGEDITFORM`` environment
606 606 variable.
607 607
608 608 In this section, items other than ``changeset`` can be referred from
609 609 others. For example, the configuration to list committed files up
610 610 below can be referred as ``{listupfiles}``::
611 611
612 612 [committemplate]
613 613 listupfiles = {file_adds %
614 614 "HG: added {file}\n" }{file_mods %
615 615 "HG: changed {file}\n" }{file_dels %
616 616 "HG: removed {file}\n" }{if(files, "",
617 617 "HG: no files changed\n")}
618 618
619 619 ``decode/encode``
620 620 -----------------
621 621
622 622 Filters for transforming files on checkout/checkin. This would
623 623 typically be used for newline processing or other
624 624 localization/canonicalization of files.
625 625
626 626 Filters consist of a filter pattern followed by a filter command.
627 627 Filter patterns are globs by default, rooted at the repository root.
628 628 For example, to match any file ending in ``.txt`` in the root
629 629 directory only, use the pattern ``*.txt``. To match any file ending
630 630 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
631 631 For each file only the first matching filter applies.
632 632
633 633 The filter command can start with a specifier, either ``pipe:`` or
634 634 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
635 635
636 636 A ``pipe:`` command must accept data on stdin and return the transformed
637 637 data on stdout.
638 638
639 639 Pipe example::
640 640
641 641 [encode]
642 642 # uncompress gzip files on checkin to improve delta compression
643 643 # note: not necessarily a good idea, just an example
644 644 *.gz = pipe: gunzip
645 645
646 646 [decode]
647 647 # recompress gzip files when writing them to the working dir (we
648 648 # can safely omit "pipe:", because it's the default)
649 649 *.gz = gzip
650 650
651 651 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
652 652 with the name of a temporary file that contains the data to be
653 653 filtered by the command. The string ``OUTFILE`` is replaced with the name
654 654 of an empty temporary file, where the filtered data must be written by
655 655 the command.
656 656
657 657 .. container:: windows
658 658
659 659 .. note::
660 660
661 661 The tempfile mechanism is recommended for Windows systems,
662 662 where the standard shell I/O redirection operators often have
663 663 strange effects and may corrupt the contents of your files.
664 664
665 665 This filter mechanism is used internally by the ``eol`` extension to
666 666 translate line ending characters between Windows (CRLF) and Unix (LF)
667 667 format. We suggest you use the ``eol`` extension for convenience.
668 668
669 669
670 670 ``defaults``
671 671 ------------
672 672
673 673 (defaults are deprecated. Don't use them. Use aliases instead.)
674 674
675 675 Use the ``[defaults]`` section to define command defaults, i.e. the
676 676 default options/arguments to pass to the specified commands.
677 677
678 678 The following example makes :hg:`log` run in verbose mode, and
679 679 :hg:`status` show only the modified files, by default::
680 680
681 681 [defaults]
682 682 log = -v
683 683 status = -m
684 684
685 685 The actual commands, instead of their aliases, must be used when
686 686 defining command defaults. The command defaults will also be applied
687 687 to the aliases of the commands defined.
688 688
689 689
690 690 ``diff``
691 691 --------
692 692
693 693 Settings used when displaying diffs. Everything except for ``unified``
694 694 is a Boolean and defaults to False. See :hg:`help config.annotate`
695 695 for related options for the annotate command.
696 696
697 697 ``git``
698 698 Use git extended diff format.
699 699
700 700 ``nobinary``
701 701 Omit git binary patches.
702 702
703 703 ``nodates``
704 704 Don't include dates in diff headers.
705 705
706 706 ``noprefix``
707 707 Omit 'a/' and 'b/' prefixes from filenames. Ignored in plain mode.
708 708
709 709 ``showfunc``
710 710 Show which function each change is in.
711 711
712 712 ``ignorews``
713 713 Ignore white space when comparing lines.
714 714
715 715 ``ignorewsamount``
716 716 Ignore changes in the amount of white space.
717 717
718 718 ``ignoreblanklines``
719 719 Ignore changes whose lines are all blank.
720 720
721 721 ``unified``
722 722 Number of lines of context to show.
723 723
724 724 ``word-diff``
725 725 Highlight changed words.
726 726
727 727 ``email``
728 728 ---------
729 729
730 730 Settings for extensions that send email messages.
731 731
732 732 ``from``
733 733 Optional. Email address to use in "From" header and SMTP envelope
734 734 of outgoing messages.
735 735
736 736 ``to``
737 737 Optional. Comma-separated list of recipients' email addresses.
738 738
739 739 ``cc``
740 740 Optional. Comma-separated list of carbon copy recipients'
741 741 email addresses.
742 742
743 743 ``bcc``
744 744 Optional. Comma-separated list of blind carbon copy recipients'
745 745 email addresses.
746 746
747 747 ``method``
748 748 Optional. Method to use to send email messages. If value is ``smtp``
749 749 (default), use SMTP (see the ``[smtp]`` section for configuration).
750 750 Otherwise, use as name of program to run that acts like sendmail
751 751 (takes ``-f`` option for sender, list of recipients on command line,
752 752 message on stdin). Normally, setting this to ``sendmail`` or
753 753 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
754 754
755 755 ``charsets``
756 756 Optional. Comma-separated list of character sets considered
757 757 convenient for recipients. Addresses, headers, and parts not
758 758 containing patches of outgoing messages will be encoded in the
759 759 first character set to which conversion from local encoding
760 760 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
761 761 conversion fails, the text in question is sent as is.
762 762 (default: '')
763 763
764 764 Order of outgoing email character sets:
765 765
766 766 1. ``us-ascii``: always first, regardless of settings
767 767 2. ``email.charsets``: in order given by user
768 768 3. ``ui.fallbackencoding``: if not in email.charsets
769 769 4. ``$HGENCODING``: if not in email.charsets
770 770 5. ``utf-8``: always last, regardless of settings
771 771
772 772 Email example::
773 773
774 774 [email]
775 775 from = Joseph User <joe.user@example.com>
776 776 method = /usr/sbin/sendmail
777 777 # charsets for western Europeans
778 778 # us-ascii, utf-8 omitted, as they are tried first and last
779 779 charsets = iso-8859-1, iso-8859-15, windows-1252
780 780
781 781
782 782 ``extensions``
783 783 --------------
784 784
785 785 Mercurial has an extension mechanism for adding new features. To
786 786 enable an extension, create an entry for it in this section.
787 787
788 788 If you know that the extension is already in Python's search path,
789 789 you can give the name of the module, followed by ``=``, with nothing
790 790 after the ``=``.
791 791
792 792 Otherwise, give a name that you choose, followed by ``=``, followed by
793 793 the path to the ``.py`` file (including the file name extension) that
794 794 defines the extension.
795 795
796 796 To explicitly disable an extension that is enabled in an hgrc of
797 797 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
798 798 or ``foo = !`` when path is not supplied.
799 799
800 800 Example for ``~/.hgrc``::
801 801
802 802 [extensions]
803 803 # (the churn extension will get loaded from Mercurial's path)
804 804 churn =
805 805 # (this extension will get loaded from the file specified)
806 806 myfeature = ~/.hgext/myfeature.py
807 807
808 808
809 809 ``format``
810 810 ----------
811 811
812 812 Configuration that controls the repository format. Newer format options are more
813 813 powerful but incompatible with some older versions of Mercurial. Format options
814 814 are considered at repository initialization only. You need to make a new clone
815 815 for config change to be taken into account.
816 816
817 817 For more details about repository format and version compatibility, see
818 818 https://www.mercurial-scm.org/wiki/MissingRequirement
819 819
820 820 ``usegeneraldelta``
821 821 Enable or disable the "generaldelta" repository format which improves
822 822 repository compression by allowing "revlog" to store delta against arbitrary
823 823 revision instead of the previous stored one. This provides significant
824 824 improvement for repositories with branches.
825 825
826 826 Repositories with this on-disk format require Mercurial version 1.9.
827 827
828 828 Enabled by default.
829 829
830 830 ``dotencode``
831 831 Enable or disable the "dotencode" repository format which enhances
832 832 the "fncache" repository format (which has to be enabled to use
833 833 dotencode) to avoid issues with filenames starting with ._ on
834 834 Mac OS X and spaces on Windows.
835 835
836 836 Repositories with this on-disk format require Mercurial version 1.7.
837 837
838 838 Enabled by default.
839 839
840 840 ``usefncache``
841 841 Enable or disable the "fncache" repository format which enhances
842 842 the "store" repository format (which has to be enabled to use
843 843 fncache) to allow longer filenames and avoids using Windows
844 844 reserved names, e.g. "nul".
845 845
846 846 Repositories with this on-disk format require Mercurial version 1.1.
847 847
848 848 Enabled by default.
849 849
850 850 ``usestore``
851 851 Enable or disable the "store" repository format which improves
852 852 compatibility with systems that fold case or otherwise mangle
853 853 filenames. Disabling this option will allow you to store longer filenames
854 854 in some situations at the expense of compatibility.
855 855
856 856 Repositories with this on-disk format require Mercurial version 0.9.4.
857 857
858 858 Enabled by default.
859 859
860 860 ``graph``
861 861 ---------
862 862
863 863 Web graph view configuration. This section let you change graph
864 864 elements display properties by branches, for instance to make the
865 865 ``default`` branch stand out.
866 866
867 867 Each line has the following format::
868 868
869 869 <branch>.<argument> = <value>
870 870
871 871 where ``<branch>`` is the name of the branch being
872 872 customized. Example::
873 873
874 874 [graph]
875 875 # 2px width
876 876 default.width = 2
877 877 # red color
878 878 default.color = FF0000
879 879
880 880 Supported arguments:
881 881
882 882 ``width``
883 883 Set branch edges width in pixels.
884 884
885 885 ``color``
886 886 Set branch edges color in hexadecimal RGB notation.
887 887
888 888 ``hooks``
889 889 ---------
890 890
891 891 Commands or Python functions that get automatically executed by
892 892 various actions such as starting or finishing a commit. Multiple
893 893 hooks can be run for the same action by appending a suffix to the
894 894 action. Overriding a site-wide hook can be done by changing its
895 895 value or setting it to an empty string. Hooks can be prioritized
896 896 by adding a prefix of ``priority.`` to the hook name on a new line
897 897 and setting the priority. The default priority is 0.
898 898
899 899 Example ``.hg/hgrc``::
900 900
901 901 [hooks]
902 902 # update working directory after adding changesets
903 903 changegroup.update = hg update
904 904 # do not use the site-wide hook
905 905 incoming =
906 906 incoming.email = /my/email/hook
907 907 incoming.autobuild = /my/build/hook
908 908 # force autobuild hook to run before other incoming hooks
909 909 priority.incoming.autobuild = 1
910 910
911 911 Most hooks are run with environment variables set that give useful
912 912 additional information. For each hook below, the environment variables
913 913 it is passed are listed with names in the form ``$HG_foo``. The
914 914 ``$HG_HOOKTYPE`` and ``$HG_HOOKNAME`` variables are set for all hooks.
915 915 They contain the type of hook which triggered the run and the full name
916 916 of the hook in the config, respectively. In the example above, this will
917 917 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
918 918
919 919 .. container:: windows
920 920
921 921 Some basic Unix syntax can be enabled for portability, including ``$VAR``
922 922 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
923 923 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
924 924 on Unix. To use a literal ``$`` or ``~``, it must be escaped with a back
925 925 slash or inside of a strong quote. Strong quotes will be replaced by
926 926 double quotes after processing.
927 927
928 928 This feature is enabled by adding a prefix of ``tonative.`` to the hook
929 929 name on a new line, and setting it to ``True``. For example::
930 930
931 931 [hooks]
932 932 incoming.autobuild = /my/build/hook
933 933 # enable translation to cmd.exe syntax for autobuild hook
934 934 tonative.incoming.autobuild = True
935 935
936 936 ``changegroup``
937 937 Run after a changegroup has been added via push, pull or unbundle. The ID of
938 938 the first new changeset is in ``$HG_NODE`` and last is in ``$HG_NODE_LAST``.
939 939 The URL from which changes came is in ``$HG_URL``.
940 940
941 941 ``commit``
942 942 Run after a changeset has been created in the local repository. The ID
943 943 of the newly created changeset is in ``$HG_NODE``. Parent changeset
944 944 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
945 945
946 946 ``incoming``
947 947 Run after a changeset has been pulled, pushed, or unbundled into
948 948 the local repository. The ID of the newly arrived changeset is in
949 949 ``$HG_NODE``. The URL that was source of the changes is in ``$HG_URL``.
950 950
951 951 ``outgoing``
952 952 Run after sending changes from the local repository to another. The ID of
953 953 first changeset sent is in ``$HG_NODE``. The source of operation is in
954 954 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
955 955
956 956 ``post-<command>``
957 957 Run after successful invocations of the associated command. The
958 958 contents of the command line are passed as ``$HG_ARGS`` and the result
959 959 code in ``$HG_RESULT``. Parsed command line arguments are passed as
960 960 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
961 961 the python data internally passed to <command>. ``$HG_OPTS`` is a
962 962 dictionary of options (with unspecified options set to their defaults).
963 963 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
964 964
965 965 ``fail-<command>``
966 966 Run after a failed invocation of an associated command. The contents
967 967 of the command line are passed as ``$HG_ARGS``. Parsed command line
968 968 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
969 969 string representations of the python data internally passed to
970 970 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
971 971 options set to their defaults). ``$HG_PATS`` is a list of arguments.
972 972 Hook failure is ignored.
973 973
974 974 ``pre-<command>``
975 975 Run before executing the associated command. The contents of the
976 976 command line are passed as ``$HG_ARGS``. Parsed command line arguments
977 977 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
978 978 representations of the data internally passed to <command>. ``$HG_OPTS``
979 979 is a dictionary of options (with unspecified options set to their
980 980 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
981 981 failure, the command doesn't execute and Mercurial returns the failure
982 982 code.
983 983
984 984 ``prechangegroup``
985 985 Run before a changegroup is added via push, pull or unbundle. Exit
986 986 status 0 allows the changegroup to proceed. A non-zero status will
987 987 cause the push, pull or unbundle to fail. The URL from which changes
988 988 will come is in ``$HG_URL``.
989 989
990 990 ``precommit``
991 991 Run before starting a local commit. Exit status 0 allows the
992 992 commit to proceed. A non-zero status will cause the commit to fail.
993 993 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
994 994
995 995 ``prelistkeys``
996 996 Run before listing pushkeys (like bookmarks) in the
997 997 repository. A non-zero status will cause failure. The key namespace is
998 998 in ``$HG_NAMESPACE``.
999 999
1000 1000 ``preoutgoing``
1001 1001 Run before collecting changes to send from the local repository to
1002 1002 another. A non-zero status will cause failure. This lets you prevent
1003 1003 pull over HTTP or SSH. It can also prevent propagating commits (via
1004 1004 local pull, push (outbound) or bundle commands), but not completely,
1005 1005 since you can just copy files instead. The source of operation is in
1006 1006 ``$HG_SOURCE``. If "serve", the operation is happening on behalf of a remote
1007 1007 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1008 1008 is happening on behalf of a repository on same system.
1009 1009
1010 1010 ``prepushkey``
1011 1011 Run before a pushkey (like a bookmark) is added to the
1012 1012 repository. A non-zero status will cause the key to be rejected. The
1013 1013 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
1014 1014 the old value (if any) is in ``$HG_OLD``, and the new value is in
1015 1015 ``$HG_NEW``.
1016 1016
1017 1017 ``pretag``
1018 1018 Run before creating a tag. Exit status 0 allows the tag to be
1019 1019 created. A non-zero status will cause the tag to fail. The ID of the
1020 1020 changeset to tag is in ``$HG_NODE``. The name of tag is in ``$HG_TAG``. The
1021 1021 tag is local if ``$HG_LOCAL=1``, or in the repository if ``$HG_LOCAL=0``.
1022 1022
1023 1023 ``pretxnopen``
1024 1024 Run before any new repository transaction is open. The reason for the
1025 1025 transaction will be in ``$HG_TXNNAME``, and a unique identifier for the
1026 1026 transaction will be in ``HG_TXNID``. A non-zero status will prevent the
1027 1027 transaction from being opened.
1028 1028
1029 1029 ``pretxnclose``
1030 1030 Run right before the transaction is actually finalized. Any repository change
1031 1031 will be visible to the hook program. This lets you validate the transaction
1032 1032 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1033 1033 status will cause the transaction to be rolled back. The reason for the
1034 1034 transaction opening will be in ``$HG_TXNNAME``, and a unique identifier for
1035 1035 the transaction will be in ``HG_TXNID``. The rest of the available data will
1036 1036 vary according the transaction type. New changesets will add ``$HG_NODE``
1037 1037 (the ID of the first added changeset), ``$HG_NODE_LAST`` (the ID of the last
1038 1038 added changeset), ``$HG_URL`` and ``$HG_SOURCE`` variables. Bookmark and
1039 1039 phase changes will set ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``
1040 1040 respectively, etc.
1041 1041
1042 1042 ``pretxnclose-bookmark``
1043 1043 Run right before a bookmark change is actually finalized. Any repository
1044 1044 change will be visible to the hook program. This lets you validate the
1045 1045 transaction content or change it. Exit status 0 allows the commit to
1046 1046 proceed. A non-zero status will cause the transaction to be rolled back.
1047 1047 The name of the bookmark will be available in ``$HG_BOOKMARK``, the new
1048 1048 bookmark location will be available in ``$HG_NODE`` while the previous
1049 1049 location will be available in ``$HG_OLDNODE``. In case of a bookmark
1050 1050 creation ``$HG_OLDNODE`` will be empty. In case of deletion ``$HG_NODE``
1051 1051 will be empty.
1052 1052 In addition, the reason for the transaction opening will be in
1053 1053 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1054 1054 ``HG_TXNID``.
1055 1055
1056 1056 ``pretxnclose-phase``
1057 1057 Run right before a phase change is actually finalized. Any repository change
1058 1058 will be visible to the hook program. This lets you validate the transaction
1059 1059 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1060 1060 status will cause the transaction to be rolled back. The hook is called
1061 1061 multiple times, once for each revision affected by a phase change.
1062 1062 The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``
1063 1063 while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``
1064 1064 will be empty. In addition, the reason for the transaction opening will be in
1065 1065 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1066 1066 ``HG_TXNID``. The hook is also run for newly added revisions. In this case
1067 1067 the ``$HG_OLDPHASE`` entry will be empty.
1068 1068
1069 1069 ``txnclose``
1070 1070 Run after any repository transaction has been committed. At this
1071 1071 point, the transaction can no longer be rolled back. The hook will run
1072 1072 after the lock is released. See :hg:`help config.hooks.pretxnclose` for
1073 1073 details about available variables.
1074 1074
1075 1075 ``txnclose-bookmark``
1076 1076 Run after any bookmark change has been committed. At this point, the
1077 1077 transaction can no longer be rolled back. The hook will run after the lock
1078 1078 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1079 1079 about available variables.
1080 1080
1081 1081 ``txnclose-phase``
1082 1082 Run after any phase change has been committed. At this point, the
1083 1083 transaction can no longer be rolled back. The hook will run after the lock
1084 1084 is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
1085 1085 available variables.
1086 1086
1087 1087 ``txnabort``
1088 1088 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
1089 1089 for details about available variables.
1090 1090
1091 1091 ``pretxnchangegroup``
1092 1092 Run after a changegroup has been added via push, pull or unbundle, but before
1093 1093 the transaction has been committed. The changegroup is visible to the hook
1094 1094 program. This allows validation of incoming changes before accepting them.
1095 1095 The ID of the first new changeset is in ``$HG_NODE`` and last is in
1096 1096 ``$HG_NODE_LAST``. Exit status 0 allows the transaction to commit. A non-zero
1097 1097 status will cause the transaction to be rolled back, and the push, pull or
1098 1098 unbundle will fail. The URL that was the source of changes is in ``$HG_URL``.
1099 1099
1100 1100 ``pretxncommit``
1101 1101 Run after a changeset has been created, but before the transaction is
1102 1102 committed. The changeset is visible to the hook program. This allows
1103 1103 validation of the commit message and changes. Exit status 0 allows the
1104 1104 commit to proceed. A non-zero status will cause the transaction to
1105 1105 be rolled back. The ID of the new changeset is in ``$HG_NODE``. The parent
1106 1106 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1107 1107
1108 1108 ``preupdate``
1109 1109 Run before updating the working directory. Exit status 0 allows
1110 1110 the update to proceed. A non-zero status will prevent the update.
1111 1111 The changeset ID of first new parent is in ``$HG_PARENT1``. If updating to a
1112 1112 merge, the ID of second new parent is in ``$HG_PARENT2``.
1113 1113
1114 1114 ``listkeys``
1115 1115 Run after listing pushkeys (like bookmarks) in the repository. The
1116 1116 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1117 1117 dictionary containing the keys and values.
1118 1118
1119 1119 ``pushkey``
1120 1120 Run after a pushkey (like a bookmark) is added to the
1121 1121 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
1122 1122 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
1123 1123 value is in ``$HG_NEW``.
1124 1124
1125 1125 ``tag``
1126 1126 Run after a tag is created. The ID of the tagged changeset is in ``$HG_NODE``.
1127 1127 The name of tag is in ``$HG_TAG``. The tag is local if ``$HG_LOCAL=1``, or in
1128 1128 the repository if ``$HG_LOCAL=0``.
1129 1129
1130 1130 ``update``
1131 1131 Run after updating the working directory. The changeset ID of first
1132 1132 new parent is in ``$HG_PARENT1``. If updating to a merge, the ID of second new
1133 1133 parent is in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
1134 1134 update failed (e.g. because conflicts were not resolved), ``$HG_ERROR=1``.
1135 1135
1136 1136 .. note::
1137 1137
1138 1138 It is generally better to use standard hooks rather than the
1139 1139 generic pre- and post- command hooks, as they are guaranteed to be
1140 1140 called in the appropriate contexts for influencing transactions.
1141 1141 Also, hooks like "commit" will be called in all contexts that
1142 1142 generate a commit (e.g. tag) and not just the commit command.
1143 1143
1144 1144 .. note::
1145 1145
1146 1146 Environment variables with empty values may not be passed to
1147 1147 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1148 1148 will have an empty value under Unix-like platforms for non-merge
1149 1149 changesets, while it will not be available at all under Windows.
1150 1150
1151 1151 The syntax for Python hooks is as follows::
1152 1152
1153 1153 hookname = python:modulename.submodule.callable
1154 1154 hookname = python:/path/to/python/module.py:callable
1155 1155
1156 1156 Python hooks are run within the Mercurial process. Each hook is
1157 1157 called with at least three keyword arguments: a ui object (keyword
1158 1158 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1159 1159 keyword that tells what kind of hook is used. Arguments listed as
1160 1160 environment variables above are passed as keyword arguments, with no
1161 1161 ``HG_`` prefix, and names in lower case.
1162 1162
1163 1163 If a Python hook returns a "true" value or raises an exception, this
1164 1164 is treated as a failure.
1165 1165
1166 1166
1167 1167 ``hostfingerprints``
1168 1168 --------------------
1169 1169
1170 1170 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1171 1171
1172 1172 Fingerprints of the certificates of known HTTPS servers.
1173 1173
1174 1174 A HTTPS connection to a server with a fingerprint configured here will
1175 1175 only succeed if the servers certificate matches the fingerprint.
1176 1176 This is very similar to how ssh known hosts works.
1177 1177
1178 1178 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
1179 1179 Multiple values can be specified (separated by spaces or commas). This can
1180 1180 be used to define both old and new fingerprints while a host transitions
1181 1181 to a new certificate.
1182 1182
1183 1183 The CA chain and web.cacerts is not used for servers with a fingerprint.
1184 1184
1185 1185 For example::
1186 1186
1187 1187 [hostfingerprints]
1188 1188 hg.intevation.de = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1189 1189 hg.intevation.org = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1190 1190
1191 1191 ``hostsecurity``
1192 1192 ----------------
1193 1193
1194 1194 Used to specify global and per-host security settings for connecting to
1195 1195 other machines.
1196 1196
1197 1197 The following options control default behavior for all hosts.
1198 1198
1199 1199 ``ciphers``
1200 1200 Defines the cryptographic ciphers to use for connections.
1201 1201
1202 1202 Value must be a valid OpenSSL Cipher List Format as documented at
1203 1203 https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
1204 1204
1205 1205 This setting is for advanced users only. Setting to incorrect values
1206 1206 can significantly lower connection security or decrease performance.
1207 1207 You have been warned.
1208 1208
1209 1209 This option requires Python 2.7.
1210 1210
1211 1211 ``minimumprotocol``
1212 1212 Defines the minimum channel encryption protocol to use.
1213 1213
1214 1214 By default, the highest version of TLS supported by both client and server
1215 1215 is used.
1216 1216
1217 1217 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1218 1218
1219 1219 When running on an old Python version, only ``tls1.0`` is allowed since
1220 1220 old versions of Python only support up to TLS 1.0.
1221 1221
1222 1222 When running a Python that supports modern TLS versions, the default is
1223 1223 ``tls1.1``. ``tls1.0`` can still be used to allow TLS 1.0. However, this
1224 1224 weakens security and should only be used as a feature of last resort if
1225 1225 a server does not support TLS 1.1+.
1226 1226
1227 1227 Options in the ``[hostsecurity]`` section can have the form
1228 1228 ``hostname``:``setting``. This allows multiple settings to be defined on a
1229 1229 per-host basis.
1230 1230
1231 1231 The following per-host settings can be defined.
1232 1232
1233 1233 ``ciphers``
1234 1234 This behaves like ``ciphers`` as described above except it only applies
1235 1235 to the host on which it is defined.
1236 1236
1237 1237 ``fingerprints``
1238 1238 A list of hashes of the DER encoded peer/remote certificate. Values have
1239 1239 the form ``algorithm``:``fingerprint``. e.g.
1240 1240 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1241 1241 In addition, colons (``:``) can appear in the fingerprint part.
1242 1242
1243 1243 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1244 1244 ``sha512``.
1245 1245
1246 1246 Use of ``sha256`` or ``sha512`` is preferred.
1247 1247
1248 1248 If a fingerprint is specified, the CA chain is not validated for this
1249 1249 host and Mercurial will require the remote certificate to match one
1250 1250 of the fingerprints specified. This means if the server updates its
1251 1251 certificate, Mercurial will abort until a new fingerprint is defined.
1252 1252 This can provide stronger security than traditional CA-based validation
1253 1253 at the expense of convenience.
1254 1254
1255 1255 This option takes precedence over ``verifycertsfile``.
1256 1256
1257 1257 ``minimumprotocol``
1258 1258 This behaves like ``minimumprotocol`` as described above except it
1259 1259 only applies to the host on which it is defined.
1260 1260
1261 1261 ``verifycertsfile``
1262 1262 Path to file a containing a list of PEM encoded certificates used to
1263 1263 verify the server certificate. Environment variables and ``~user``
1264 1264 constructs are expanded in the filename.
1265 1265
1266 1266 The server certificate or the certificate's certificate authority (CA)
1267 1267 must match a certificate from this file or certificate verification
1268 1268 will fail and connections to the server will be refused.
1269 1269
1270 1270 If defined, only certificates provided by this file will be used:
1271 1271 ``web.cacerts`` and any system/default certificates will not be
1272 1272 used.
1273 1273
1274 1274 This option has no effect if the per-host ``fingerprints`` option
1275 1275 is set.
1276 1276
1277 1277 The format of the file is as follows::
1278 1278
1279 1279 -----BEGIN CERTIFICATE-----
1280 1280 ... (certificate in base64 PEM encoding) ...
1281 1281 -----END CERTIFICATE-----
1282 1282 -----BEGIN CERTIFICATE-----
1283 1283 ... (certificate in base64 PEM encoding) ...
1284 1284 -----END CERTIFICATE-----
1285 1285
1286 1286 For example::
1287 1287
1288 1288 [hostsecurity]
1289 1289 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
1290 1290 hg2.example.com:fingerprints = sha1:914f1aff87249c09b6859b88b1906d30756491ca, sha1:fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1291 1291 hg3.example.com:fingerprints = sha256:9a:b0:dc:e2:75:ad:8a:b7:84:58:e5:1f:07:32:f1:87:e6:bd:24:22:af:b7:ce:8e:9c:b4:10:cf:b9:f4:0e:d2
1292 1292 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1293 1293
1294 1294 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1295 1295 when connecting to ``hg.example.com``::
1296 1296
1297 1297 [hostsecurity]
1298 1298 minimumprotocol = tls1.2
1299 1299 hg.example.com:minimumprotocol = tls1.1
1300 1300
1301 1301 ``http_proxy``
1302 1302 --------------
1303 1303
1304 1304 Used to access web-based Mercurial repositories through a HTTP
1305 1305 proxy.
1306 1306
1307 1307 ``host``
1308 1308 Host name and (optional) port of the proxy server, for example
1309 1309 "myproxy:8000".
1310 1310
1311 1311 ``no``
1312 1312 Optional. Comma-separated list of host names that should bypass
1313 1313 the proxy.
1314 1314
1315 1315 ``passwd``
1316 1316 Optional. Password to authenticate with at the proxy server.
1317 1317
1318 1318 ``user``
1319 1319 Optional. User name to authenticate with at the proxy server.
1320 1320
1321 1321 ``always``
1322 1322 Optional. Always use the proxy, even for localhost and any entries
1323 1323 in ``http_proxy.no``. (default: False)
1324 1324
1325 1325 ``merge``
1326 1326 ---------
1327 1327
1328 1328 This section specifies behavior during merges and updates.
1329 1329
1330 1330 ``checkignored``
1331 1331 Controls behavior when an ignored file on disk has the same name as a tracked
1332 1332 file in the changeset being merged or updated to, and has different
1333 1333 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1334 1334 abort on such files. With ``warn``, warn on such files and back them up as
1335 1335 ``.orig``. With ``ignore``, don't print a warning and back them up as
1336 1336 ``.orig``. (default: ``abort``)
1337 1337
1338 1338 ``checkunknown``
1339 1339 Controls behavior when an unknown file that isn't ignored has the same name
1340 1340 as a tracked file in the changeset being merged or updated to, and has
1341 1341 different contents. Similar to ``merge.checkignored``, except for files that
1342 1342 are not ignored. (default: ``abort``)
1343 1343
1344 1344 ``on-failure``
1345 1345 When set to ``continue`` (the default), the merge process attempts to
1346 1346 merge all unresolved files using the merge chosen tool, regardless of
1347 1347 whether previous file merge attempts during the process succeeded or not.
1348 1348 Setting this to ``prompt`` will prompt after any merge failure continue
1349 1349 or halt the merge process. Setting this to ``halt`` will automatically
1350 1350 halt the merge process on any merge tool failure. The merge process
1351 1351 can be restarted by using the ``resolve`` command. When a merge is
1352 1352 halted, the repository is left in a normal ``unresolved`` merge state.
1353 1353 (default: ``continue``)
1354 1354
1355 1355 ``strict-capability-check``
1356 1356 Whether capabilities of internal merge tools are checked strictly
1357 1357 or not, while examining rules to decide merge tool to be used.
1358 1358 (default: False)
1359 1359
1360 1360 ``merge-patterns``
1361 1361 ------------------
1362 1362
1363 1363 This section specifies merge tools to associate with particular file
1364 1364 patterns. Tools matched here will take precedence over the default
1365 1365 merge tool. Patterns are globs by default, rooted at the repository
1366 1366 root.
1367 1367
1368 1368 Example::
1369 1369
1370 1370 [merge-patterns]
1371 1371 **.c = kdiff3
1372 1372 **.jpg = myimgmerge
1373 1373
1374 1374 ``merge-tools``
1375 1375 ---------------
1376 1376
1377 1377 This section configures external merge tools to use for file-level
1378 1378 merges. This section has likely been preconfigured at install time.
1379 1379 Use :hg:`config merge-tools` to check the existing configuration.
1380 1380 Also see :hg:`help merge-tools` for more details.
1381 1381
1382 1382 Example ``~/.hgrc``::
1383 1383
1384 1384 [merge-tools]
1385 1385 # Override stock tool location
1386 1386 kdiff3.executable = ~/bin/kdiff3
1387 1387 # Specify command line
1388 1388 kdiff3.args = $base $local $other -o $output
1389 1389 # Give higher priority
1390 1390 kdiff3.priority = 1
1391 1391
1392 1392 # Changing the priority of preconfigured tool
1393 1393 meld.priority = 0
1394 1394
1395 1395 # Disable a preconfigured tool
1396 1396 vimdiff.disabled = yes
1397 1397
1398 1398 # Define new tool
1399 1399 myHtmlTool.args = -m $local $other $base $output
1400 1400 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1401 1401 myHtmlTool.priority = 1
1402 1402
1403 1403 Supported arguments:
1404 1404
1405 1405 ``priority``
1406 1406 The priority in which to evaluate this tool.
1407 1407 (default: 0)
1408 1408
1409 1409 ``executable``
1410 1410 Either just the name of the executable or its pathname.
1411 1411
1412 1412 .. container:: windows
1413 1413
1414 1414 On Windows, the path can use environment variables with ${ProgramFiles}
1415 1415 syntax.
1416 1416
1417 1417 (default: the tool name)
1418 1418
1419 1419 ``args``
1420 1420 The arguments to pass to the tool executable. You can refer to the
1421 1421 files being merged as well as the output file through these
1422 1422 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1423 1423
1424 1424 The meaning of ``$local`` and ``$other`` can vary depending on which action is
1425 1425 being performed. During an update or merge, ``$local`` represents the original
1426 1426 state of the file, while ``$other`` represents the commit you are updating to or
1427 1427 the commit you are merging with. During a rebase, ``$local`` represents the
1428 1428 destination of the rebase, and ``$other`` represents the commit being rebased.
1429 1429
1430 1430 Some operations define custom labels to assist with identifying the revisions,
1431 1431 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1432 1432 labels are not available, these will be ``local``, ``other``, and ``base``,
1433 1433 respectively.
1434 1434 (default: ``$local $base $other``)
1435 1435
1436 1436 ``premerge``
1437 1437 Attempt to run internal non-interactive 3-way merge tool before
1438 1438 launching external tool. Options are ``true``, ``false``, ``keep`` or
1439 1439 ``keep-merge3``. The ``keep`` option will leave markers in the file if the
1440 1440 premerge fails. The ``keep-merge3`` will do the same but include information
1441 1441 about the base of the merge in the marker (see internal :merge3 in
1442 1442 :hg:`help merge-tools`).
1443 1443 (default: True)
1444 1444
1445 1445 ``binary``
1446 1446 This tool can merge binary files. (default: False, unless tool
1447 1447 was selected by file pattern match)
1448 1448
1449 1449 ``symlink``
1450 1450 This tool can merge symlinks. (default: False)
1451 1451
1452 1452 ``check``
1453 1453 A list of merge success-checking options:
1454 1454
1455 1455 ``changed``
1456 1456 Ask whether merge was successful when the merged file shows no changes.
1457 1457 ``conflicts``
1458 1458 Check whether there are conflicts even though the tool reported success.
1459 1459 ``prompt``
1460 1460 Always prompt for merge success, regardless of success reported by tool.
1461 1461
1462 1462 ``fixeol``
1463 1463 Attempt to fix up EOL changes caused by the merge tool.
1464 1464 (default: False)
1465 1465
1466 1466 ``gui``
1467 1467 This tool requires a graphical interface to run. (default: False)
1468 1468
1469 1469 ``mergemarkers``
1470 1470 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1471 1471 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1472 1472 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1473 1473 markers generated during premerge will be ``detailed`` if either this option or
1474 1474 the corresponding option in the ``[ui]`` section is ``detailed``.
1475 1475 (default: ``basic``)
1476 1476
1477 1477 ``mergemarkertemplate``
1478 1478 This setting can be used to override ``mergemarkertemplate`` from the ``[ui]``
1479 1479 section on a per-tool basis; this applies to the ``$label``-prefixed variables
1480 1480 and to the conflict markers that are generated if ``premerge`` is ``keep` or
1481 1481 ``keep-merge3``. See the corresponding variable in ``[ui]`` for more
1482 1482 information.
1483 1483
1484 1484 .. container:: windows
1485 1485
1486 1486 ``regkey``
1487 1487 Windows registry key which describes install location of this
1488 1488 tool. Mercurial will search for this key first under
1489 1489 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1490 1490 (default: None)
1491 1491
1492 1492 ``regkeyalt``
1493 1493 An alternate Windows registry key to try if the first key is not
1494 1494 found. The alternate key uses the same ``regname`` and ``regappend``
1495 1495 semantics of the primary key. The most common use for this key
1496 1496 is to search for 32bit applications on 64bit operating systems.
1497 1497 (default: None)
1498 1498
1499 1499 ``regname``
1500 1500 Name of value to read from specified registry key.
1501 1501 (default: the unnamed (default) value)
1502 1502
1503 1503 ``regappend``
1504 1504 String to append to the value read from the registry, typically
1505 1505 the executable name of the tool.
1506 1506 (default: None)
1507 1507
1508 1508 ``pager``
1509 1509 ---------
1510 1510
1511 1511 Setting used to control when to paginate and with what external tool. See
1512 1512 :hg:`help pager` for details.
1513 1513
1514 1514 ``pager``
1515 1515 Define the external tool used as pager.
1516 1516
1517 1517 If no pager is set, Mercurial uses the environment variable $PAGER.
1518 1518 If neither pager.pager, nor $PAGER is set, a default pager will be
1519 1519 used, typically `less` on Unix and `more` on Windows. Example::
1520 1520
1521 1521 [pager]
1522 1522 pager = less -FRX
1523 1523
1524 1524 ``ignore``
1525 1525 List of commands to disable the pager for. Example::
1526 1526
1527 1527 [pager]
1528 1528 ignore = version, help, update
1529 1529
1530 1530 ``patch``
1531 1531 ---------
1532 1532
1533 1533 Settings used when applying patches, for instance through the 'import'
1534 1534 command or with Mercurial Queues extension.
1535 1535
1536 1536 ``eol``
1537 1537 When set to 'strict' patch content and patched files end of lines
1538 1538 are preserved. When set to ``lf`` or ``crlf``, both files end of
1539 1539 lines are ignored when patching and the result line endings are
1540 1540 normalized to either LF (Unix) or CRLF (Windows). When set to
1541 1541 ``auto``, end of lines are again ignored while patching but line
1542 1542 endings in patched files are normalized to their original setting
1543 1543 on a per-file basis. If target file does not exist or has no end
1544 1544 of line, patch line endings are preserved.
1545 1545 (default: strict)
1546 1546
1547 1547 ``fuzz``
1548 1548 The number of lines of 'fuzz' to allow when applying patches. This
1549 1549 controls how much context the patcher is allowed to ignore when
1550 1550 trying to apply a patch.
1551 1551 (default: 2)
1552 1552
1553 1553 ``paths``
1554 1554 ---------
1555 1555
1556 1556 Assigns symbolic names and behavior to repositories.
1557 1557
1558 1558 Options are symbolic names defining the URL or directory that is the
1559 1559 location of the repository. Example::
1560 1560
1561 1561 [paths]
1562 1562 my_server = https://example.com/my_repo
1563 1563 local_path = /home/me/repo
1564 1564
1565 1565 These symbolic names can be used from the command line. To pull
1566 1566 from ``my_server``: :hg:`pull my_server`. To push to ``local_path``:
1567 1567 :hg:`push local_path`.
1568 1568
1569 1569 Options containing colons (``:``) denote sub-options that can influence
1570 1570 behavior for that specific path. Example::
1571 1571
1572 1572 [paths]
1573 1573 my_server = https://example.com/my_path
1574 1574 my_server:pushurl = ssh://example.com/my_path
1575 1575
1576 1576 The following sub-options can be defined:
1577 1577
1578 1578 ``pushurl``
1579 1579 The URL to use for push operations. If not defined, the location
1580 1580 defined by the path's main entry is used.
1581 1581
1582 1582 ``pushrev``
1583 1583 A revset defining which revisions to push by default.
1584 1584
1585 1585 When :hg:`push` is executed without a ``-r`` argument, the revset
1586 1586 defined by this sub-option is evaluated to determine what to push.
1587 1587
1588 1588 For example, a value of ``.`` will push the working directory's
1589 1589 revision by default.
1590 1590
1591 1591 Revsets specifying bookmarks will not result in the bookmark being
1592 1592 pushed.
1593 1593
1594 1594 The following special named paths exist:
1595 1595
1596 1596 ``default``
1597 1597 The URL or directory to use when no source or remote is specified.
1598 1598
1599 1599 :hg:`clone` will automatically define this path to the location the
1600 1600 repository was cloned from.
1601 1601
1602 1602 ``default-push``
1603 1603 (deprecated) The URL or directory for the default :hg:`push` location.
1604 1604 ``default:pushurl`` should be used instead.
1605 1605
1606 1606 ``phases``
1607 1607 ----------
1608 1608
1609 1609 Specifies default handling of phases. See :hg:`help phases` for more
1610 1610 information about working with phases.
1611 1611
1612 1612 ``publish``
1613 1613 Controls draft phase behavior when working as a server. When true,
1614 1614 pushed changesets are set to public in both client and server and
1615 1615 pulled or cloned changesets are set to public in the client.
1616 1616 (default: True)
1617 1617
1618 1618 ``new-commit``
1619 1619 Phase of newly-created commits.
1620 1620 (default: draft)
1621 1621
1622 1622 ``checksubrepos``
1623 1623 Check the phase of the current revision of each subrepository. Allowed
1624 1624 values are "ignore", "follow" and "abort". For settings other than
1625 1625 "ignore", the phase of the current revision of each subrepository is
1626 1626 checked before committing the parent repository. If any of those phases is
1627 1627 greater than the phase of the parent repository (e.g. if a subrepo is in a
1628 1628 "secret" phase while the parent repo is in "draft" phase), the commit is
1629 1629 either aborted (if checksubrepos is set to "abort") or the higher phase is
1630 1630 used for the parent repository commit (if set to "follow").
1631 1631 (default: follow)
1632 1632
1633 1633
1634 1634 ``profiling``
1635 1635 -------------
1636 1636
1637 1637 Specifies profiling type, format, and file output. Two profilers are
1638 1638 supported: an instrumenting profiler (named ``ls``), and a sampling
1639 1639 profiler (named ``stat``).
1640 1640
1641 1641 In this section description, 'profiling data' stands for the raw data
1642 1642 collected during profiling, while 'profiling report' stands for a
1643 1643 statistical text report generated from the profiling data.
1644 1644
1645 1645 ``enabled``
1646 1646 Enable the profiler.
1647 1647 (default: false)
1648 1648
1649 1649 This is equivalent to passing ``--profile`` on the command line.
1650 1650
1651 1651 ``type``
1652 1652 The type of profiler to use.
1653 1653 (default: stat)
1654 1654
1655 1655 ``ls``
1656 1656 Use Python's built-in instrumenting profiler. This profiler
1657 1657 works on all platforms, but each line number it reports is the
1658 1658 first line of a function. This restriction makes it difficult to
1659 1659 identify the expensive parts of a non-trivial function.
1660 1660 ``stat``
1661 1661 Use a statistical profiler, statprof. This profiler is most
1662 1662 useful for profiling commands that run for longer than about 0.1
1663 1663 seconds.
1664 1664
1665 1665 ``format``
1666 1666 Profiling format. Specific to the ``ls`` instrumenting profiler.
1667 1667 (default: text)
1668 1668
1669 1669 ``text``
1670 1670 Generate a profiling report. When saving to a file, it should be
1671 1671 noted that only the report is saved, and the profiling data is
1672 1672 not kept.
1673 1673 ``kcachegrind``
1674 1674 Format profiling data for kcachegrind use: when saving to a
1675 1675 file, the generated file can directly be loaded into
1676 1676 kcachegrind.
1677 1677
1678 1678 ``statformat``
1679 1679 Profiling format for the ``stat`` profiler.
1680 1680 (default: hotpath)
1681 1681
1682 1682 ``hotpath``
1683 1683 Show a tree-based display containing the hot path of execution (where
1684 1684 most time was spent).
1685 1685 ``bymethod``
1686 1686 Show a table of methods ordered by how frequently they are active.
1687 1687 ``byline``
1688 1688 Show a table of lines in files ordered by how frequently they are active.
1689 1689 ``json``
1690 1690 Render profiling data as JSON.
1691 1691
1692 1692 ``frequency``
1693 1693 Sampling frequency. Specific to the ``stat`` sampling profiler.
1694 1694 (default: 1000)
1695 1695
1696 1696 ``output``
1697 1697 File path where profiling data or report should be saved. If the
1698 1698 file exists, it is replaced. (default: None, data is printed on
1699 1699 stderr)
1700 1700
1701 1701 ``sort``
1702 1702 Sort field. Specific to the ``ls`` instrumenting profiler.
1703 1703 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1704 1704 ``inlinetime``.
1705 1705 (default: inlinetime)
1706 1706
1707 1707 ``time-track``
1708 1708 Control if the stat profiler track ``cpu`` or ``real`` time.
1709 1709 (default: ``cpu``)
1710 1710
1711 1711 ``limit``
1712 1712 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1713 1713 (default: 30)
1714 1714
1715 1715 ``nested``
1716 1716 Show at most this number of lines of drill-down info after each main entry.
1717 1717 This can help explain the difference between Total and Inline.
1718 1718 Specific to the ``ls`` instrumenting profiler.
1719 1719 (default: 0)
1720 1720
1721 1721 ``showmin``
1722 1722 Minimum fraction of samples an entry must have for it to be displayed.
1723 1723 Can be specified as a float between ``0.0`` and ``1.0`` or can have a
1724 1724 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
1725 1725
1726 1726 Only used by the ``stat`` profiler.
1727 1727
1728 1728 For the ``hotpath`` format, default is ``0.05``.
1729 1729 For the ``chrome`` format, default is ``0.005``.
1730 1730
1731 1731 The option is unused on other formats.
1732 1732
1733 1733 ``showmax``
1734 1734 Maximum fraction of samples an entry can have before it is ignored in
1735 1735 display. Values format is the same as ``showmin``.
1736 1736
1737 1737 Only used by the ``stat`` profiler.
1738 1738
1739 1739 For the ``chrome`` format, default is ``0.999``.
1740 1740
1741 1741 The option is unused on other formats.
1742 1742
1743 1743 ``progress``
1744 1744 ------------
1745 1745
1746 1746 Mercurial commands can draw progress bars that are as informative as
1747 1747 possible. Some progress bars only offer indeterminate information, while others
1748 1748 have a definite end point.
1749 1749
1750 1750 ``delay``
1751 1751 Number of seconds (float) before showing the progress bar. (default: 3)
1752 1752
1753 1753 ``changedelay``
1754 1754 Minimum delay before showing a new topic. When set to less than 3 * refresh,
1755 1755 that value will be used instead. (default: 1)
1756 1756
1757 1757 ``estimateinterval``
1758 1758 Maximum sampling interval in seconds for speed and estimated time
1759 1759 calculation. (default: 60)
1760 1760
1761 1761 ``refresh``
1762 1762 Time in seconds between refreshes of the progress bar. (default: 0.1)
1763 1763
1764 1764 ``format``
1765 1765 Format of the progress bar.
1766 1766
1767 1767 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1768 1768 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1769 1769 last 20 characters of the item, but this can be changed by adding either
1770 1770 ``-<num>`` which would take the last num characters, or ``+<num>`` for the
1771 1771 first num characters.
1772 1772
1773 1773 (default: topic bar number estimate)
1774 1774
1775 1775 ``width``
1776 1776 If set, the maximum width of the progress information (that is, min(width,
1777 1777 term width) will be used).
1778 1778
1779 1779 ``clear-complete``
1780 1780 Clear the progress bar after it's done. (default: True)
1781 1781
1782 1782 ``disable``
1783 1783 If true, don't show a progress bar.
1784 1784
1785 1785 ``assume-tty``
1786 1786 If true, ALWAYS show a progress bar, unless disable is given.
1787 1787
1788 1788 ``rebase``
1789 1789 ----------
1790 1790
1791 1791 ``evolution.allowdivergence``
1792 1792 Default to False, when True allow creating divergence when performing
1793 1793 rebase of obsolete changesets.
1794 1794
1795 1795 ``revsetalias``
1796 1796 ---------------
1797 1797
1798 1798 Alias definitions for revsets. See :hg:`help revsets` for details.
1799 1799
1800 1800 ``storage``
1801 1801 -----------
1802 1802
1803 1803 Control the strategy Mercurial uses internally to store history. Options in this
1804 1804 category impact performance and repository size.
1805 1805
1806 1806 ``revlog.optimize-delta-parent-choice``
1807 1807 When storing a merge revision, both parents will be equally considered as
1808 1808 a possible delta base. This results in better delta selection and improved
1809 1809 revlog compression. This option is enabled by default.
1810 1810
1811 1811 Turning this option off can result in large increase of repository size for
1812 1812 repository with many merges.
1813 1813
1814 1814 ``server``
1815 1815 ----------
1816 1816
1817 1817 Controls generic server settings.
1818 1818
1819 1819 ``bookmarks-pushkey-compat``
1820 1820 Trigger pushkey hook when being pushed bookmark updates. This config exist
1821 1821 for compatibility purpose (default to True)
1822 1822
1823 1823 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
1824 1824 movement we recommend you migrate them to ``txnclose-bookmark`` and
1825 1825 ``pretxnclose-bookmark``.
1826 1826
1827 1827 ``compressionengines``
1828 1828 List of compression engines and their relative priority to advertise
1829 1829 to clients.
1830 1830
1831 1831 The order of compression engines determines their priority, the first
1832 1832 having the highest priority. If a compression engine is not listed
1833 1833 here, it won't be advertised to clients.
1834 1834
1835 1835 If not set (the default), built-in defaults are used. Run
1836 1836 :hg:`debuginstall` to list available compression engines and their
1837 1837 default wire protocol priority.
1838 1838
1839 1839 Older Mercurial clients only support zlib compression and this setting
1840 1840 has no effect for legacy clients.
1841 1841
1842 1842 ``uncompressed``
1843 1843 Whether to allow clients to clone a repository using the
1844 1844 uncompressed streaming protocol. This transfers about 40% more
1845 1845 data than a regular clone, but uses less memory and CPU on both
1846 1846 server and client. Over a LAN (100 Mbps or better) or a very fast
1847 1847 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
1848 1848 regular clone. Over most WAN connections (anything slower than
1849 1849 about 6 Mbps), uncompressed streaming is slower, because of the
1850 1850 extra data transfer overhead. This mode will also temporarily hold
1851 1851 the write lock while determining what data to transfer.
1852 1852 (default: True)
1853 1853
1854 1854 ``uncompressedallowsecret``
1855 1855 Whether to allow stream clones when the repository contains secret
1856 1856 changesets. (default: False)
1857 1857
1858 1858 ``preferuncompressed``
1859 1859 When set, clients will try to use the uncompressed streaming
1860 1860 protocol. (default: False)
1861 1861
1862 1862 ``disablefullbundle``
1863 1863 When set, servers will refuse attempts to do pull-based clones.
1864 1864 If this option is set, ``preferuncompressed`` and/or clone bundles
1865 1865 are highly recommended. Partial clones will still be allowed.
1866 1866 (default: False)
1867 1867
1868 1868 ``streamunbundle``
1869 1869 When set, servers will apply data sent from the client directly,
1870 1870 otherwise it will be written to a temporary file first. This option
1871 1871 effectively prevents concurrent pushes.
1872 1872
1873 1873 ``pullbundle``
1874 1874 When set, the server will check pullbundle.manifest for bundles
1875 1875 covering the requested heads and common nodes. The first matching
1876 1876 entry will be streamed to the client.
1877 1877
1878 1878 For HTTP transport, the stream will still use zlib compression
1879 1879 for older clients.
1880 1880
1881 1881 ``concurrent-push-mode``
1882 1882 Level of allowed race condition between two pushing clients.
1883 1883
1884 1884 - 'strict': push is abort if another client touched the repository
1885 1885 while the push was preparing. (default)
1886 1886 - 'check-related': push is only aborted if it affects head that got also
1887 1887 affected while the push was preparing.
1888 1888
1889 1889 This requires compatible client (version 4.3 and later). Old client will
1890 1890 use 'strict'.
1891 1891
1892 1892 ``validate``
1893 1893 Whether to validate the completeness of pushed changesets by
1894 1894 checking that all new file revisions specified in manifests are
1895 1895 present. (default: False)
1896 1896
1897 1897 ``maxhttpheaderlen``
1898 1898 Instruct HTTP clients not to send request headers longer than this
1899 1899 many bytes. (default: 1024)
1900 1900
1901 1901 ``bundle1``
1902 1902 Whether to allow clients to push and pull using the legacy bundle1
1903 1903 exchange format. (default: True)
1904 1904
1905 1905 ``bundle1gd``
1906 1906 Like ``bundle1`` but only used if the repository is using the
1907 1907 *generaldelta* storage format. (default: True)
1908 1908
1909 1909 ``bundle1.push``
1910 1910 Whether to allow clients to push using the legacy bundle1 exchange
1911 1911 format. (default: True)
1912 1912
1913 1913 ``bundle1gd.push``
1914 1914 Like ``bundle1.push`` but only used if the repository is using the
1915 1915 *generaldelta* storage format. (default: True)
1916 1916
1917 1917 ``bundle1.pull``
1918 1918 Whether to allow clients to pull using the legacy bundle1 exchange
1919 1919 format. (default: True)
1920 1920
1921 1921 ``bundle1gd.pull``
1922 1922 Like ``bundle1.pull`` but only used if the repository is using the
1923 1923 *generaldelta* storage format. (default: True)
1924 1924
1925 1925 Large repositories using the *generaldelta* storage format should
1926 1926 consider setting this option because converting *generaldelta*
1927 1927 repositories to the exchange format required by the bundle1 data
1928 1928 format can consume a lot of CPU.
1929 1929
1930 ``bundle2.stream``
1931 Whether to allow clients to pull using the bundle2 streaming protocol.
1932 (default: False)
1933
1930 1934 ``zliblevel``
1931 1935 Integer between ``-1`` and ``9`` that controls the zlib compression level
1932 1936 for wire protocol commands that send zlib compressed output (notably the
1933 1937 commands that send repository history data).
1934 1938
1935 1939 The default (``-1``) uses the default zlib compression level, which is
1936 1940 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
1937 1941 maximum compression.
1938 1942
1939 1943 Setting this option allows server operators to make trade-offs between
1940 1944 bandwidth and CPU used. Lowering the compression lowers CPU utilization
1941 1945 but sends more bytes to clients.
1942 1946
1943 1947 This option only impacts the HTTP server.
1944 1948
1945 1949 ``zstdlevel``
1946 1950 Integer between ``1`` and ``22`` that controls the zstd compression level
1947 1951 for wire protocol commands. ``1`` is the minimal amount of compression and
1948 1952 ``22`` is the highest amount of compression.
1949 1953
1950 1954 The default (``3``) should be significantly faster than zlib while likely
1951 1955 delivering better compression ratios.
1952 1956
1953 1957 This option only impacts the HTTP server.
1954 1958
1955 1959 See also ``server.zliblevel``.
1956 1960
1957 1961 ``smtp``
1958 1962 --------
1959 1963
1960 1964 Configuration for extensions that need to send email messages.
1961 1965
1962 1966 ``host``
1963 1967 Host name of mail server, e.g. "mail.example.com".
1964 1968
1965 1969 ``port``
1966 1970 Optional. Port to connect to on mail server. (default: 465 if
1967 1971 ``tls`` is smtps; 25 otherwise)
1968 1972
1969 1973 ``tls``
1970 1974 Optional. Method to enable TLS when connecting to mail server: starttls,
1971 1975 smtps or none. (default: none)
1972 1976
1973 1977 ``username``
1974 1978 Optional. User name for authenticating with the SMTP server.
1975 1979 (default: None)
1976 1980
1977 1981 ``password``
1978 1982 Optional. Password for authenticating with the SMTP server. If not
1979 1983 specified, interactive sessions will prompt the user for a
1980 1984 password; non-interactive sessions will fail. (default: None)
1981 1985
1982 1986 ``local_hostname``
1983 1987 Optional. The hostname that the sender can use to identify
1984 1988 itself to the MTA.
1985 1989
1986 1990
1987 1991 ``subpaths``
1988 1992 ------------
1989 1993
1990 1994 Subrepository source URLs can go stale if a remote server changes name
1991 1995 or becomes temporarily unavailable. This section lets you define
1992 1996 rewrite rules of the form::
1993 1997
1994 1998 <pattern> = <replacement>
1995 1999
1996 2000 where ``pattern`` is a regular expression matching a subrepository
1997 2001 source URL and ``replacement`` is the replacement string used to
1998 2002 rewrite it. Groups can be matched in ``pattern`` and referenced in
1999 2003 ``replacements``. For instance::
2000 2004
2001 2005 http://server/(.*)-hg/ = http://hg.server/\1/
2002 2006
2003 2007 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2004 2008
2005 2009 Relative subrepository paths are first made absolute, and the
2006 2010 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2007 2011 doesn't match the full path, an attempt is made to apply it on the
2008 2012 relative path alone. The rules are applied in definition order.
2009 2013
2010 2014 ``subrepos``
2011 2015 ------------
2012 2016
2013 2017 This section contains options that control the behavior of the
2014 2018 subrepositories feature. See also :hg:`help subrepos`.
2015 2019
2016 2020 Security note: auditing in Mercurial is known to be insufficient to
2017 2021 prevent clone-time code execution with carefully constructed Git
2018 2022 subrepos. It is unknown if a similar detect is present in Subversion
2019 2023 subrepos. Both Git and Subversion subrepos are disabled by default
2020 2024 out of security concerns. These subrepo types can be enabled using
2021 2025 the respective options below.
2022 2026
2023 2027 ``allowed``
2024 2028 Whether subrepositories are allowed in the working directory.
2025 2029
2026 2030 When false, commands involving subrepositories (like :hg:`update`)
2027 2031 will fail for all subrepository types.
2028 2032 (default: true)
2029 2033
2030 2034 ``hg:allowed``
2031 2035 Whether Mercurial subrepositories are allowed in the working
2032 2036 directory. This option only has an effect if ``subrepos.allowed``
2033 2037 is true.
2034 2038 (default: true)
2035 2039
2036 2040 ``git:allowed``
2037 2041 Whether Git subrepositories are allowed in the working directory.
2038 2042 This option only has an effect if ``subrepos.allowed`` is true.
2039 2043
2040 2044 See the security note above before enabling Git subrepos.
2041 2045 (default: false)
2042 2046
2043 2047 ``svn:allowed``
2044 2048 Whether Subversion subrepositories are allowed in the working
2045 2049 directory. This option only has an effect if ``subrepos.allowed``
2046 2050 is true.
2047 2051
2048 2052 See the security note above before enabling Subversion subrepos.
2049 2053 (default: false)
2050 2054
2051 2055 ``templatealias``
2052 2056 -----------------
2053 2057
2054 2058 Alias definitions for templates. See :hg:`help templates` for details.
2055 2059
2056 2060 ``templates``
2057 2061 -------------
2058 2062
2059 2063 Use the ``[templates]`` section to define template strings.
2060 2064 See :hg:`help templates` for details.
2061 2065
2062 2066 ``trusted``
2063 2067 -----------
2064 2068
2065 2069 Mercurial will not use the settings in the
2066 2070 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2067 2071 user or to a trusted group, as various hgrc features allow arbitrary
2068 2072 commands to be run. This issue is often encountered when configuring
2069 2073 hooks or extensions for shared repositories or servers. However,
2070 2074 the web interface will use some safe settings from the ``[web]``
2071 2075 section.
2072 2076
2073 2077 This section specifies what users and groups are trusted. The
2074 2078 current user is always trusted. To trust everybody, list a user or a
2075 2079 group with name ``*``. These settings must be placed in an
2076 2080 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2077 2081 user or service running Mercurial.
2078 2082
2079 2083 ``users``
2080 2084 Comma-separated list of trusted users.
2081 2085
2082 2086 ``groups``
2083 2087 Comma-separated list of trusted groups.
2084 2088
2085 2089
2086 2090 ``ui``
2087 2091 ------
2088 2092
2089 2093 User interface controls.
2090 2094
2091 2095 ``archivemeta``
2092 2096 Whether to include the .hg_archival.txt file containing meta data
2093 2097 (hashes for the repository base and for tip) in archives created
2094 2098 by the :hg:`archive` command or downloaded via hgweb.
2095 2099 (default: True)
2096 2100
2097 2101 ``askusername``
2098 2102 Whether to prompt for a username when committing. If True, and
2099 2103 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2100 2104 be prompted to enter a username. If no username is entered, the
2101 2105 default ``USER@HOST`` is used instead.
2102 2106 (default: False)
2103 2107
2104 2108 ``clonebundles``
2105 2109 Whether the "clone bundles" feature is enabled.
2106 2110
2107 2111 When enabled, :hg:`clone` may download and apply a server-advertised
2108 2112 bundle file from a URL instead of using the normal exchange mechanism.
2109 2113
2110 2114 This can likely result in faster and more reliable clones.
2111 2115
2112 2116 (default: True)
2113 2117
2114 2118 ``clonebundlefallback``
2115 2119 Whether failure to apply an advertised "clone bundle" from a server
2116 2120 should result in fallback to a regular clone.
2117 2121
2118 2122 This is disabled by default because servers advertising "clone
2119 2123 bundles" often do so to reduce server load. If advertised bundles
2120 2124 start mass failing and clients automatically fall back to a regular
2121 2125 clone, this would add significant and unexpected load to the server
2122 2126 since the server is expecting clone operations to be offloaded to
2123 2127 pre-generated bundles. Failing fast (the default behavior) ensures
2124 2128 clients don't overwhelm the server when "clone bundle" application
2125 2129 fails.
2126 2130
2127 2131 (default: False)
2128 2132
2129 2133 ``clonebundleprefers``
2130 2134 Defines preferences for which "clone bundles" to use.
2131 2135
2132 2136 Servers advertising "clone bundles" may advertise multiple available
2133 2137 bundles. Each bundle may have different attributes, such as the bundle
2134 2138 type and compression format. This option is used to prefer a particular
2135 2139 bundle over another.
2136 2140
2137 2141 The following keys are defined by Mercurial:
2138 2142
2139 2143 BUNDLESPEC
2140 2144 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2141 2145 e.g. ``gzip-v2`` or ``bzip2-v1``.
2142 2146
2143 2147 COMPRESSION
2144 2148 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2145 2149
2146 2150 Server operators may define custom keys.
2147 2151
2148 2152 Example values: ``COMPRESSION=bzip2``,
2149 2153 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2150 2154
2151 2155 By default, the first bundle advertised by the server is used.
2152 2156
2153 2157 ``color``
2154 2158 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2155 2159 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2156 2160 seems possible. See :hg:`help color` for details.
2157 2161
2158 2162 ``commitsubrepos``
2159 2163 Whether to commit modified subrepositories when committing the
2160 2164 parent repository. If False and one subrepository has uncommitted
2161 2165 changes, abort the commit.
2162 2166 (default: False)
2163 2167
2164 2168 ``debug``
2165 2169 Print debugging information. (default: False)
2166 2170
2167 2171 ``editor``
2168 2172 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2169 2173
2170 2174 ``fallbackencoding``
2171 2175 Encoding to try if it's not possible to decode the changelog using
2172 2176 UTF-8. (default: ISO-8859-1)
2173 2177
2174 2178 ``graphnodetemplate``
2175 2179 The template used to print changeset nodes in an ASCII revision graph.
2176 2180 (default: ``{graphnode}``)
2177 2181
2178 2182 ``ignore``
2179 2183 A file to read per-user ignore patterns from. This file should be
2180 2184 in the same format as a repository-wide .hgignore file. Filenames
2181 2185 are relative to the repository root. This option supports hook syntax,
2182 2186 so if you want to specify multiple ignore files, you can do so by
2183 2187 setting something like ``ignore.other = ~/.hgignore2``. For details
2184 2188 of the ignore file format, see the ``hgignore(5)`` man page.
2185 2189
2186 2190 ``interactive``
2187 2191 Allow to prompt the user. (default: True)
2188 2192
2189 2193 ``interface``
2190 2194 Select the default interface for interactive features (default: text).
2191 2195 Possible values are 'text' and 'curses'.
2192 2196
2193 2197 ``interface.chunkselector``
2194 2198 Select the interface for change recording (e.g. :hg:`commit -i`).
2195 2199 Possible values are 'text' and 'curses'.
2196 2200 This config overrides the interface specified by ui.interface.
2197 2201
2198 2202 ``large-file-limit``
2199 2203 Largest file size that gives no memory use warning.
2200 2204 Possible values are integers or 0 to disable the check.
2201 2205 (default: 10000000)
2202 2206
2203 2207 ``logtemplate``
2204 2208 Template string for commands that print changesets.
2205 2209
2206 2210 ``merge``
2207 2211 The conflict resolution program to use during a manual merge.
2208 2212 For more information on merge tools see :hg:`help merge-tools`.
2209 2213 For configuring merge tools see the ``[merge-tools]`` section.
2210 2214
2211 2215 ``mergemarkers``
2212 2216 Sets the merge conflict marker label styling. The ``detailed``
2213 2217 style uses the ``mergemarkertemplate`` setting to style the labels.
2214 2218 The ``basic`` style just uses 'local' and 'other' as the marker label.
2215 2219 One of ``basic`` or ``detailed``.
2216 2220 (default: ``basic``)
2217 2221
2218 2222 ``mergemarkertemplate``
2219 2223 The template used to print the commit description next to each conflict
2220 2224 marker during merge conflicts. See :hg:`help templates` for the template
2221 2225 format.
2222 2226
2223 2227 Defaults to showing the hash, tags, branches, bookmarks, author, and
2224 2228 the first line of the commit description.
2225 2229
2226 2230 If you use non-ASCII characters in names for tags, branches, bookmarks,
2227 2231 authors, and/or commit descriptions, you must pay attention to encodings of
2228 2232 managed files. At template expansion, non-ASCII characters use the encoding
2229 2233 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2230 2234 environment variables that govern your locale. If the encoding of the merge
2231 2235 markers is different from the encoding of the merged files,
2232 2236 serious problems may occur.
2233 2237
2234 2238 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2235 2239
2236 2240 ``origbackuppath``
2237 2241 The path to a directory used to store generated .orig files. If the path is
2238 2242 not a directory, one will be created. If set, files stored in this
2239 2243 directory have the same name as the original file and do not have a .orig
2240 2244 suffix.
2241 2245
2242 2246 ``paginate``
2243 2247 Control the pagination of command output (default: True). See :hg:`help pager`
2244 2248 for details.
2245 2249
2246 2250 ``patch``
2247 2251 An optional external tool that ``hg import`` and some extensions
2248 2252 will use for applying patches. By default Mercurial uses an
2249 2253 internal patch utility. The external tool must work as the common
2250 2254 Unix ``patch`` program. In particular, it must accept a ``-p``
2251 2255 argument to strip patch headers, a ``-d`` argument to specify the
2252 2256 current directory, a file name to patch, and a patch file to take
2253 2257 from stdin.
2254 2258
2255 2259 It is possible to specify a patch tool together with extra
2256 2260 arguments. For example, setting this option to ``patch --merge``
2257 2261 will use the ``patch`` program with its 2-way merge option.
2258 2262
2259 2263 ``portablefilenames``
2260 2264 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2261 2265 (default: ``warn``)
2262 2266
2263 2267 ``warn``
2264 2268 Print a warning message on POSIX platforms, if a file with a non-portable
2265 2269 filename is added (e.g. a file with a name that can't be created on
2266 2270 Windows because it contains reserved parts like ``AUX``, reserved
2267 2271 characters like ``:``, or would cause a case collision with an existing
2268 2272 file).
2269 2273
2270 2274 ``ignore``
2271 2275 Don't print a warning.
2272 2276
2273 2277 ``abort``
2274 2278 The command is aborted.
2275 2279
2276 2280 ``true``
2277 2281 Alias for ``warn``.
2278 2282
2279 2283 ``false``
2280 2284 Alias for ``ignore``.
2281 2285
2282 2286 .. container:: windows
2283 2287
2284 2288 On Windows, this configuration option is ignored and the command aborted.
2285 2289
2286 2290 ``quiet``
2287 2291 Reduce the amount of output printed.
2288 2292 (default: False)
2289 2293
2290 2294 ``remotecmd``
2291 2295 Remote command to use for clone/push/pull operations.
2292 2296 (default: ``hg``)
2293 2297
2294 2298 ``report_untrusted``
2295 2299 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2296 2300 trusted user or group.
2297 2301 (default: True)
2298 2302
2299 2303 ``slash``
2300 2304 (Deprecated. Use ``slashpath`` template filter instead.)
2301 2305
2302 2306 Display paths using a slash (``/``) as the path separator. This
2303 2307 only makes a difference on systems where the default path
2304 2308 separator is not the slash character (e.g. Windows uses the
2305 2309 backslash character (``\``)).
2306 2310 (default: False)
2307 2311
2308 2312 ``statuscopies``
2309 2313 Display copies in the status command.
2310 2314
2311 2315 ``ssh``
2312 2316 Command to use for SSH connections. (default: ``ssh``)
2313 2317
2314 2318 ``ssherrorhint``
2315 2319 A hint shown to the user in the case of SSH error (e.g.
2316 2320 ``Please see http://company/internalwiki/ssh.html``)
2317 2321
2318 2322 ``strict``
2319 2323 Require exact command names, instead of allowing unambiguous
2320 2324 abbreviations. (default: False)
2321 2325
2322 2326 ``style``
2323 2327 Name of style to use for command output.
2324 2328
2325 2329 ``supportcontact``
2326 2330 A URL where users should report a Mercurial traceback. Use this if you are a
2327 2331 large organisation with its own Mercurial deployment process and crash
2328 2332 reports should be addressed to your internal support.
2329 2333
2330 2334 ``textwidth``
2331 2335 Maximum width of help text. A longer line generated by ``hg help`` or
2332 2336 ``hg subcommand --help`` will be broken after white space to get this
2333 2337 width or the terminal width, whichever comes first.
2334 2338 A non-positive value will disable this and the terminal width will be
2335 2339 used. (default: 78)
2336 2340
2337 2341 ``timeout``
2338 2342 The timeout used when a lock is held (in seconds), a negative value
2339 2343 means no timeout. (default: 600)
2340 2344
2341 2345 ``timeout.warn``
2342 2346 Time (in seconds) before a warning is printed about held lock. A negative
2343 2347 value means no warning. (default: 0)
2344 2348
2345 2349 ``traceback``
2346 2350 Mercurial always prints a traceback when an unknown exception
2347 2351 occurs. Setting this to True will make Mercurial print a traceback
2348 2352 on all exceptions, even those recognized by Mercurial (such as
2349 2353 IOError or MemoryError). (default: False)
2350 2354
2351 2355 ``tweakdefaults``
2352 2356
2353 2357 By default Mercurial's behavior changes very little from release
2354 2358 to release, but over time the recommended config settings
2355 2359 shift. Enable this config to opt in to get automatic tweaks to
2356 2360 Mercurial's behavior over time. This config setting will have no
2357 2361 effect if ``HGPLAIN` is set or ``HGPLAINEXCEPT`` is set and does
2358 2362 not include ``tweakdefaults``. (default: False)
2359 2363
2360 2364 ``username``
2361 2365 The committer of a changeset created when running "commit".
2362 2366 Typically a person's name and email address, e.g. ``Fred Widget
2363 2367 <fred@example.com>``. Environment variables in the
2364 2368 username are expanded.
2365 2369
2366 2370 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2367 2371 hgrc is empty, e.g. if the system admin set ``username =`` in the
2368 2372 system hgrc, it has to be specified manually or in a different
2369 2373 hgrc file)
2370 2374
2371 2375 ``verbose``
2372 2376 Increase the amount of output printed. (default: False)
2373 2377
2374 2378
2375 2379 ``web``
2376 2380 -------
2377 2381
2378 2382 Web interface configuration. The settings in this section apply to
2379 2383 both the builtin webserver (started by :hg:`serve`) and the script you
2380 2384 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2381 2385 and WSGI).
2382 2386
2383 2387 The Mercurial webserver does no authentication (it does not prompt for
2384 2388 usernames and passwords to validate *who* users are), but it does do
2385 2389 authorization (it grants or denies access for *authenticated users*
2386 2390 based on settings in this section). You must either configure your
2387 2391 webserver to do authentication for you, or disable the authorization
2388 2392 checks.
2389 2393
2390 2394 For a quick setup in a trusted environment, e.g., a private LAN, where
2391 2395 you want it to accept pushes from anybody, you can use the following
2392 2396 command line::
2393 2397
2394 2398 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2395 2399
2396 2400 Note that this will allow anybody to push anything to the server and
2397 2401 that this should not be used for public servers.
2398 2402
2399 2403 The full set of options is:
2400 2404
2401 2405 ``accesslog``
2402 2406 Where to output the access log. (default: stdout)
2403 2407
2404 2408 ``address``
2405 2409 Interface address to bind to. (default: all)
2406 2410
2407 2411 ``allow-archive``
2408 2412 List of archive format (bz2, gz, zip) allowed for downloading.
2409 2413 (default: empty)
2410 2414
2411 2415 ``allowbz2``
2412 2416 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2413 2417 revisions.
2414 2418 (default: False)
2415 2419
2416 2420 ``allowgz``
2417 2421 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2418 2422 revisions.
2419 2423 (default: False)
2420 2424
2421 2425 ``allow-pull``
2422 2426 Whether to allow pulling from the repository. (default: True)
2423 2427
2424 2428 ``allow-push``
2425 2429 Whether to allow pushing to the repository. If empty or not set,
2426 2430 pushing is not allowed. If the special value ``*``, any remote
2427 2431 user can push, including unauthenticated users. Otherwise, the
2428 2432 remote user must have been authenticated, and the authenticated
2429 2433 user name must be present in this list. The contents of the
2430 2434 allow-push list are examined after the deny_push list.
2431 2435
2432 2436 ``allow_read``
2433 2437 If the user has not already been denied repository access due to
2434 2438 the contents of deny_read, this list determines whether to grant
2435 2439 repository access to the user. If this list is not empty, and the
2436 2440 user is unauthenticated or not present in the list, then access is
2437 2441 denied for the user. If the list is empty or not set, then access
2438 2442 is permitted to all users by default. Setting allow_read to the
2439 2443 special value ``*`` is equivalent to it not being set (i.e. access
2440 2444 is permitted to all users). The contents of the allow_read list are
2441 2445 examined after the deny_read list.
2442 2446
2443 2447 ``allowzip``
2444 2448 (DEPRECATED) Whether to allow .zip downloading of repository
2445 2449 revisions. This feature creates temporary files.
2446 2450 (default: False)
2447 2451
2448 2452 ``archivesubrepos``
2449 2453 Whether to recurse into subrepositories when archiving.
2450 2454 (default: False)
2451 2455
2452 2456 ``baseurl``
2453 2457 Base URL to use when publishing URLs in other locations, so
2454 2458 third-party tools like email notification hooks can construct
2455 2459 URLs. Example: ``http://hgserver/repos/``.
2456 2460
2457 2461 ``cacerts``
2458 2462 Path to file containing a list of PEM encoded certificate
2459 2463 authority certificates. Environment variables and ``~user``
2460 2464 constructs are expanded in the filename. If specified on the
2461 2465 client, then it will verify the identity of remote HTTPS servers
2462 2466 with these certificates.
2463 2467
2464 2468 To disable SSL verification temporarily, specify ``--insecure`` from
2465 2469 command line.
2466 2470
2467 2471 You can use OpenSSL's CA certificate file if your platform has
2468 2472 one. On most Linux systems this will be
2469 2473 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2470 2474 generate this file manually. The form must be as follows::
2471 2475
2472 2476 -----BEGIN CERTIFICATE-----
2473 2477 ... (certificate in base64 PEM encoding) ...
2474 2478 -----END CERTIFICATE-----
2475 2479 -----BEGIN CERTIFICATE-----
2476 2480 ... (certificate in base64 PEM encoding) ...
2477 2481 -----END CERTIFICATE-----
2478 2482
2479 2483 ``cache``
2480 2484 Whether to support caching in hgweb. (default: True)
2481 2485
2482 2486 ``certificate``
2483 2487 Certificate to use when running :hg:`serve`.
2484 2488
2485 2489 ``collapse``
2486 2490 With ``descend`` enabled, repositories in subdirectories are shown at
2487 2491 a single level alongside repositories in the current path. With
2488 2492 ``collapse`` also enabled, repositories residing at a deeper level than
2489 2493 the current path are grouped behind navigable directory entries that
2490 2494 lead to the locations of these repositories. In effect, this setting
2491 2495 collapses each collection of repositories found within a subdirectory
2492 2496 into a single entry for that subdirectory. (default: False)
2493 2497
2494 2498 ``comparisoncontext``
2495 2499 Number of lines of context to show in side-by-side file comparison. If
2496 2500 negative or the value ``full``, whole files are shown. (default: 5)
2497 2501
2498 2502 This setting can be overridden by a ``context`` request parameter to the
2499 2503 ``comparison`` command, taking the same values.
2500 2504
2501 2505 ``contact``
2502 2506 Name or email address of the person in charge of the repository.
2503 2507 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2504 2508
2505 2509 ``csp``
2506 2510 Send a ``Content-Security-Policy`` HTTP header with this value.
2507 2511
2508 2512 The value may contain a special string ``%nonce%``, which will be replaced
2509 2513 by a randomly-generated one-time use value. If the value contains
2510 2514 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2511 2515 one-time property of the nonce. This nonce will also be inserted into
2512 2516 ``<script>`` elements containing inline JavaScript.
2513 2517
2514 2518 Note: lots of HTML content sent by the server is derived from repository
2515 2519 data. Please consider the potential for malicious repository data to
2516 2520 "inject" itself into generated HTML content as part of your security
2517 2521 threat model.
2518 2522
2519 2523 ``deny_push``
2520 2524 Whether to deny pushing to the repository. If empty or not set,
2521 2525 push is not denied. If the special value ``*``, all remote users are
2522 2526 denied push. Otherwise, unauthenticated users are all denied, and
2523 2527 any authenticated user name present in this list is also denied. The
2524 2528 contents of the deny_push list are examined before the allow-push list.
2525 2529
2526 2530 ``deny_read``
2527 2531 Whether to deny reading/viewing of the repository. If this list is
2528 2532 not empty, unauthenticated users are all denied, and any
2529 2533 authenticated user name present in this list is also denied access to
2530 2534 the repository. If set to the special value ``*``, all remote users
2531 2535 are denied access (rarely needed ;). If deny_read is empty or not set,
2532 2536 the determination of repository access depends on the presence and
2533 2537 content of the allow_read list (see description). If both
2534 2538 deny_read and allow_read are empty or not set, then access is
2535 2539 permitted to all users by default. If the repository is being
2536 2540 served via hgwebdir, denied users will not be able to see it in
2537 2541 the list of repositories. The contents of the deny_read list have
2538 2542 priority over (are examined before) the contents of the allow_read
2539 2543 list.
2540 2544
2541 2545 ``descend``
2542 2546 hgwebdir indexes will not descend into subdirectories. Only repositories
2543 2547 directly in the current path will be shown (other repositories are still
2544 2548 available from the index corresponding to their containing path).
2545 2549
2546 2550 ``description``
2547 2551 Textual description of the repository's purpose or contents.
2548 2552 (default: "unknown")
2549 2553
2550 2554 ``encoding``
2551 2555 Character encoding name. (default: the current locale charset)
2552 2556 Example: "UTF-8".
2553 2557
2554 2558 ``errorlog``
2555 2559 Where to output the error log. (default: stderr)
2556 2560
2557 2561 ``guessmime``
2558 2562 Control MIME types for raw download of file content.
2559 2563 Set to True to let hgweb guess the content type from the file
2560 2564 extension. This will serve HTML files as ``text/html`` and might
2561 2565 allow cross-site scripting attacks when serving untrusted
2562 2566 repositories. (default: False)
2563 2567
2564 2568 ``hidden``
2565 2569 Whether to hide the repository in the hgwebdir index.
2566 2570 (default: False)
2567 2571
2568 2572 ``ipv6``
2569 2573 Whether to use IPv6. (default: False)
2570 2574
2571 2575 ``labels``
2572 2576 List of string *labels* associated with the repository.
2573 2577
2574 2578 Labels are exposed as a template keyword and can be used to customize
2575 2579 output. e.g. the ``index`` template can group or filter repositories
2576 2580 by labels and the ``summary`` template can display additional content
2577 2581 if a specific label is present.
2578 2582
2579 2583 ``logoimg``
2580 2584 File name of the logo image that some templates display on each page.
2581 2585 The file name is relative to ``staticurl``. That is, the full path to
2582 2586 the logo image is "staticurl/logoimg".
2583 2587 If unset, ``hglogo.png`` will be used.
2584 2588
2585 2589 ``logourl``
2586 2590 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2587 2591 will be used.
2588 2592
2589 2593 ``maxchanges``
2590 2594 Maximum number of changes to list on the changelog. (default: 10)
2591 2595
2592 2596 ``maxfiles``
2593 2597 Maximum number of files to list per changeset. (default: 10)
2594 2598
2595 2599 ``maxshortchanges``
2596 2600 Maximum number of changes to list on the shortlog, graph or filelog
2597 2601 pages. (default: 60)
2598 2602
2599 2603 ``name``
2600 2604 Repository name to use in the web interface.
2601 2605 (default: current working directory)
2602 2606
2603 2607 ``port``
2604 2608 Port to listen on. (default: 8000)
2605 2609
2606 2610 ``prefix``
2607 2611 Prefix path to serve from. (default: '' (server root))
2608 2612
2609 2613 ``push_ssl``
2610 2614 Whether to require that inbound pushes be transported over SSL to
2611 2615 prevent password sniffing. (default: True)
2612 2616
2613 2617 ``refreshinterval``
2614 2618 How frequently directory listings re-scan the filesystem for new
2615 2619 repositories, in seconds. This is relevant when wildcards are used
2616 2620 to define paths. Depending on how much filesystem traversal is
2617 2621 required, refreshing may negatively impact performance.
2618 2622
2619 2623 Values less than or equal to 0 always refresh.
2620 2624 (default: 20)
2621 2625
2622 2626 ``server-header``
2623 2627 Value for HTTP ``Server`` response header.
2624 2628
2625 2629 ``staticurl``
2626 2630 Base URL to use for static files. If unset, static files (e.g. the
2627 2631 hgicon.png favicon) will be served by the CGI script itself. Use
2628 2632 this setting to serve them directly with the HTTP server.
2629 2633 Example: ``http://hgserver/static/``.
2630 2634
2631 2635 ``stripes``
2632 2636 How many lines a "zebra stripe" should span in multi-line output.
2633 2637 Set to 0 to disable. (default: 1)
2634 2638
2635 2639 ``style``
2636 2640 Which template map style to use. The available options are the names of
2637 2641 subdirectories in the HTML templates path. (default: ``paper``)
2638 2642 Example: ``monoblue``.
2639 2643
2640 2644 ``templates``
2641 2645 Where to find the HTML templates. The default path to the HTML templates
2642 2646 can be obtained from ``hg debuginstall``.
2643 2647
2644 2648 ``websub``
2645 2649 ----------
2646 2650
2647 2651 Web substitution filter definition. You can use this section to
2648 2652 define a set of regular expression substitution patterns which
2649 2653 let you automatically modify the hgweb server output.
2650 2654
2651 2655 The default hgweb templates only apply these substitution patterns
2652 2656 on the revision description fields. You can apply them anywhere
2653 2657 you want when you create your own templates by adding calls to the
2654 2658 "websub" filter (usually after calling the "escape" filter).
2655 2659
2656 2660 This can be used, for example, to convert issue references to links
2657 2661 to your issue tracker, or to convert "markdown-like" syntax into
2658 2662 HTML (see the examples below).
2659 2663
2660 2664 Each entry in this section names a substitution filter.
2661 2665 The value of each entry defines the substitution expression itself.
2662 2666 The websub expressions follow the old interhg extension syntax,
2663 2667 which in turn imitates the Unix sed replacement syntax::
2664 2668
2665 2669 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2666 2670
2667 2671 You can use any separator other than "/". The final "i" is optional
2668 2672 and indicates that the search must be case insensitive.
2669 2673
2670 2674 Examples::
2671 2675
2672 2676 [websub]
2673 2677 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2674 2678 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2675 2679 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2676 2680
2677 2681 ``worker``
2678 2682 ----------
2679 2683
2680 2684 Parallel master/worker configuration. We currently perform working
2681 2685 directory updates in parallel on Unix-like systems, which greatly
2682 2686 helps performance.
2683 2687
2684 2688 ``enabled``
2685 2689 Whether to enable workers code to be used.
2686 2690 (default: true)
2687 2691
2688 2692 ``numcpus``
2689 2693 Number of CPUs to use for parallel operations. A zero or
2690 2694 negative value is treated as ``use the default``.
2691 2695 (default: 4 or the number of CPUs on the system, whichever is larger)
2692 2696
2693 2697 ``backgroundclose``
2694 2698 Whether to enable closing file handles on background threads during certain
2695 2699 operations. Some platforms aren't very efficient at closing file
2696 2700 handles that have been written or appended to. By performing file closing
2697 2701 on background threads, file write rate can increase substantially.
2698 2702 (default: true on Windows, false elsewhere)
2699 2703
2700 2704 ``backgroundcloseminfilecount``
2701 2705 Minimum number of files required to trigger background file closing.
2702 2706 Operations not writing this many files won't start background close
2703 2707 threads.
2704 2708 (default: 2048)
2705 2709
2706 2710 ``backgroundclosemaxqueue``
2707 2711 The maximum number of opened file handles waiting to be closed in the
2708 2712 background. This option only has an effect if ``backgroundclose`` is
2709 2713 enabled.
2710 2714 (default: 384)
2711 2715
2712 2716 ``backgroundclosethreadcount``
2713 2717 Number of threads to process background file closes. Only relevant if
2714 2718 ``backgroundclose`` is enabled.
2715 2719 (default: 4)
@@ -1,514 +1,514 b''
1 1 #require serve no-reposimplestore no-chg
2 2
3 3 #testcases stream-legacy stream-bundle2
4 4
5 5 #if stream-bundle2
6 6 $ cat << EOF >> $HGRCPATH
7 > [experimental]
7 > [server]
8 8 > bundle2.stream = yes
9 9 > EOF
10 10 #endif
11 11
12 12 Initialize repository
13 13 the status call is to check for issue5130
14 14
15 15 $ hg init server
16 16 $ cd server
17 17 $ touch foo
18 18 $ hg -q commit -A -m initial
19 19 >>> for i in range(1024):
20 20 ... with open(str(i), 'wb') as fh:
21 21 ... fh.write(b"%d" % i) and None
22 22 $ hg -q commit -A -m 'add a lot of files'
23 23 $ hg st
24 24 $ hg --config server.uncompressed=false serve -p $HGPORT -d --pid-file=hg.pid
25 25 $ cat hg.pid > $DAEMON_PIDS
26 26 $ cd ..
27 27
28 28 Cannot stream clone when server.uncompressed is set
29 29
30 30 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=stream_out'
31 31 200 Script output follows
32 32
33 33 1
34 34
35 35 #if stream-legacy
36 36 $ hg debugcapabilities http://localhost:$HGPORT
37 37 Main capabilities:
38 38 batch
39 39 branchmap
40 40 $USUAL_BUNDLE2_CAPS_SERVER$
41 41 changegroupsubset
42 42 compression=$BUNDLE2_COMPRESSIONS$
43 43 getbundle
44 44 httpheader=1024
45 45 httpmediatype=0.1rx,0.1tx,0.2tx
46 46 known
47 47 lookup
48 48 pushkey
49 49 unbundle=HG10GZ,HG10BZ,HG10UN
50 50 unbundlehash
51 51 Bundle2 capabilities:
52 52 HG20
53 53 bookmarks
54 54 changegroup
55 55 01
56 56 02
57 57 digests
58 58 md5
59 59 sha1
60 60 sha512
61 61 error
62 62 abort
63 63 unsupportedcontent
64 64 pushraced
65 65 pushkey
66 66 hgtagsfnodes
67 67 listkeys
68 68 phases
69 69 heads
70 70 pushkey
71 71 remote-changegroup
72 72 http
73 73 https
74 74 rev-branch-cache
75 75
76 76 $ hg clone --stream -U http://localhost:$HGPORT server-disabled
77 77 warning: stream clone requested but server has them disabled
78 78 requesting all changes
79 79 adding changesets
80 80 adding manifests
81 81 adding file changes
82 82 added 2 changesets with 1025 changes to 1025 files
83 83 new changesets 96ee1d7354c4:c17445101a72
84 84
85 85 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto 0.2 --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1"
86 86 200 Script output follows
87 87 content-type: application/mercurial-0.2
88 88
89 89
90 90 $ f --size body --hexdump --bytes 100
91 91 body: size=232
92 92 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
93 93 0010: cf 0b 45 52 52 4f 52 3a 41 42 4f 52 54 00 00 00 |..ERROR:ABORT...|
94 94 0020: 00 01 01 07 3c 04 72 6d 65 73 73 61 67 65 73 74 |....<.rmessagest|
95 95 0030: 72 65 61 6d 20 64 61 74 61 20 72 65 71 75 65 73 |ream data reques|
96 96 0040: 74 65 64 20 62 75 74 20 73 65 72 76 65 72 20 64 |ted but server d|
97 97 0050: 6f 65 73 20 6e 6f 74 20 61 6c 6c 6f 77 20 74 68 |oes not allow th|
98 98 0060: 69 73 20 66 |is f|
99 99
100 100 #endif
101 101 #if stream-bundle2
102 102 $ hg debugcapabilities http://localhost:$HGPORT
103 103 Main capabilities:
104 104 batch
105 105 branchmap
106 106 $USUAL_BUNDLE2_CAPS_SERVER$
107 107 changegroupsubset
108 108 compression=$BUNDLE2_COMPRESSIONS$
109 109 getbundle
110 110 httpheader=1024
111 111 httpmediatype=0.1rx,0.1tx,0.2tx
112 112 known
113 113 lookup
114 114 pushkey
115 115 unbundle=HG10GZ,HG10BZ,HG10UN
116 116 unbundlehash
117 117 Bundle2 capabilities:
118 118 HG20
119 119 bookmarks
120 120 changegroup
121 121 01
122 122 02
123 123 digests
124 124 md5
125 125 sha1
126 126 sha512
127 127 error
128 128 abort
129 129 unsupportedcontent
130 130 pushraced
131 131 pushkey
132 132 hgtagsfnodes
133 133 listkeys
134 134 phases
135 135 heads
136 136 pushkey
137 137 remote-changegroup
138 138 http
139 139 https
140 140 rev-branch-cache
141 141
142 142 $ hg clone --stream -U http://localhost:$HGPORT server-disabled
143 143 warning: stream clone requested but server has them disabled
144 144 requesting all changes
145 145 adding changesets
146 146 adding manifests
147 147 adding file changes
148 148 added 2 changesets with 1025 changes to 1025 files
149 149 new changesets 96ee1d7354c4:c17445101a72
150 150
151 151 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto 0.2 --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1"
152 152 200 Script output follows
153 153 content-type: application/mercurial-0.2
154 154
155 155
156 156 $ f --size body --hexdump --bytes 100
157 157 body: size=232
158 158 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
159 159 0010: cf 0b 45 52 52 4f 52 3a 41 42 4f 52 54 00 00 00 |..ERROR:ABORT...|
160 160 0020: 00 01 01 07 3c 04 72 6d 65 73 73 61 67 65 73 74 |....<.rmessagest|
161 161 0030: 72 65 61 6d 20 64 61 74 61 20 72 65 71 75 65 73 |ream data reques|
162 162 0040: 74 65 64 20 62 75 74 20 73 65 72 76 65 72 20 64 |ted but server d|
163 163 0050: 6f 65 73 20 6e 6f 74 20 61 6c 6c 6f 77 20 74 68 |oes not allow th|
164 164 0060: 69 73 20 66 |is f|
165 165
166 166 #endif
167 167
168 168 $ killdaemons.py
169 169 $ cd server
170 170 $ hg serve -p $HGPORT -d --pid-file=hg.pid
171 171 $ cat hg.pid > $DAEMON_PIDS
172 172 $ cd ..
173 173
174 174 Basic clone
175 175
176 176 #if stream-legacy
177 177 $ hg clone --stream -U http://localhost:$HGPORT clone1
178 178 streaming all changes
179 179 1027 files to transfer, 96.3 KB of data
180 180 transferred 96.3 KB in * seconds (*/sec) (glob)
181 181 searching for changes
182 182 no changes found
183 183 #endif
184 184 #if stream-bundle2
185 185 $ hg clone --stream -U http://localhost:$HGPORT clone1
186 186 streaming all changes
187 187 1030 files to transfer, 96.4 KB of data
188 188 transferred 96.4 KB in * seconds (* */sec) (glob)
189 189
190 190 $ ls -1 clone1/.hg/cache
191 191 branch2-served
192 192 rbc-names-v1
193 193 rbc-revs-v1
194 194 #endif
195 195
196 196 getbundle requests with stream=1 are uncompressed
197 197
198 198 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto '0.1 0.2 comp=zlib,none' --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1"
199 199 200 Script output follows
200 200 content-type: application/mercurial-0.2
201 201
202 202
203 203 $ f --size --hex --bytes 256 body
204 204 body: size=112230
205 205 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
206 206 0010: 70 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |p.STREAM2.......|
207 207 0020: 05 09 04 0c 35 62 79 74 65 63 6f 75 6e 74 39 38 |....5bytecount98|
208 208 0030: 37 35 38 66 69 6c 65 63 6f 75 6e 74 31 30 33 30 |758filecount1030|
209 209 0040: 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 65 |requirementsdote|
210 210 0050: 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 25 |ncode%2Cfncache%|
211 211 0060: 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 32 |2Cgeneraldelta%2|
212 212 0070: 43 72 65 76 6c 6f 67 76 31 25 32 43 73 74 6f 72 |Crevlogv1%2Cstor|
213 213 0080: 65 00 00 80 00 73 08 42 64 61 74 61 2f 30 2e 69 |e....s.Bdata/0.i|
214 214 0090: 00 03 00 01 00 00 00 00 00 00 00 02 00 00 00 01 |................|
215 215 00a0: 00 00 00 00 00 00 00 01 ff ff ff ff ff ff ff ff |................|
216 216 00b0: 80 29 63 a0 49 d3 23 87 bf ce fe 56 67 92 67 2c |.)c.I.#....Vg.g,|
217 217 00c0: 69 d1 ec 39 00 00 00 00 00 00 00 00 00 00 00 00 |i..9............|
218 218 00d0: 75 30 73 08 42 64 61 74 61 2f 31 2e 69 00 03 00 |u0s.Bdata/1.i...|
219 219 00e0: 01 00 00 00 00 00 00 00 02 00 00 00 01 00 00 00 |................|
220 220 00f0: 00 00 00 00 01 ff ff ff ff ff ff ff ff f9 76 da |..............v.|
221 221
222 222 --uncompressed is an alias to --stream
223 223
224 224 #if stream-legacy
225 225 $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed
226 226 streaming all changes
227 227 1027 files to transfer, 96.3 KB of data
228 228 transferred 96.3 KB in * seconds (*/sec) (glob)
229 229 searching for changes
230 230 no changes found
231 231 #endif
232 232 #if stream-bundle2
233 233 $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed
234 234 streaming all changes
235 235 1030 files to transfer, 96.4 KB of data
236 236 transferred 96.4 KB in * seconds (* */sec) (glob)
237 237 #endif
238 238
239 239 Clone with background file closing enabled
240 240
241 241 #if stream-legacy
242 242 $ hg --debug --config worker.backgroundclose=true --config worker.backgroundcloseminfilecount=1 clone --stream -U http://localhost:$HGPORT clone-background | grep -v adding
243 243 using http://localhost:$HGPORT/
244 244 sending capabilities command
245 245 sending branchmap command
246 246 streaming all changes
247 247 sending stream_out command
248 248 1027 files to transfer, 96.3 KB of data
249 249 starting 4 threads for background file closing
250 250 updating the branch cache
251 251 transferred 96.3 KB in * seconds (*/sec) (glob)
252 252 query 1; heads
253 253 sending batch command
254 254 searching for changes
255 255 all remote heads known locally
256 256 no changes found
257 257 sending getbundle command
258 258 bundle2-input-bundle: with-transaction
259 259 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
260 260 bundle2-input-part: "phase-heads" supported
261 261 bundle2-input-part: total payload size 24
262 262 bundle2-input-bundle: 1 parts total
263 263 checking for updated bookmarks
264 264 #endif
265 265 #if stream-bundle2
266 266 $ hg --debug --config worker.backgroundclose=true --config worker.backgroundcloseminfilecount=1 clone --stream -U http://localhost:$HGPORT clone-background | grep -v adding
267 267 using http://localhost:$HGPORT/
268 268 sending capabilities command
269 269 query 1; heads
270 270 sending batch command
271 271 streaming all changes
272 272 sending getbundle command
273 273 bundle2-input-bundle: with-transaction
274 274 bundle2-input-part: "stream2" (params: 3 mandatory) supported
275 275 applying stream bundle
276 276 1030 files to transfer, 96.4 KB of data
277 277 starting 4 threads for background file closing
278 278 starting 4 threads for background file closing
279 279 updating the branch cache
280 280 transferred 96.4 KB in * seconds (* */sec) (glob)
281 281 bundle2-input-part: total payload size 112077
282 282 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
283 283 bundle2-input-bundle: 1 parts total
284 284 checking for updated bookmarks
285 285 #endif
286 286
287 287 Cannot stream clone when there are secret changesets
288 288
289 289 $ hg -R server phase --force --secret -r tip
290 290 $ hg clone --stream -U http://localhost:$HGPORT secret-denied
291 291 warning: stream clone requested but server has them disabled
292 292 requesting all changes
293 293 adding changesets
294 294 adding manifests
295 295 adding file changes
296 296 added 1 changesets with 1 changes to 1 files
297 297 new changesets 96ee1d7354c4
298 298
299 299 $ killdaemons.py
300 300
301 301 Streaming of secrets can be overridden by server config
302 302
303 303 $ cd server
304 304 $ hg serve --config server.uncompressedallowsecret=true -p $HGPORT -d --pid-file=hg.pid
305 305 $ cat hg.pid > $DAEMON_PIDS
306 306 $ cd ..
307 307
308 308 #if stream-legacy
309 309 $ hg clone --stream -U http://localhost:$HGPORT secret-allowed
310 310 streaming all changes
311 311 1027 files to transfer, 96.3 KB of data
312 312 transferred 96.3 KB in * seconds (*/sec) (glob)
313 313 searching for changes
314 314 no changes found
315 315 #endif
316 316 #if stream-bundle2
317 317 $ hg clone --stream -U http://localhost:$HGPORT secret-allowed
318 318 streaming all changes
319 319 1030 files to transfer, 96.4 KB of data
320 320 transferred 96.4 KB in * seconds (* */sec) (glob)
321 321 #endif
322 322
323 323 $ killdaemons.py
324 324
325 325 Verify interaction between preferuncompressed and secret presence
326 326
327 327 $ cd server
328 328 $ hg serve --config server.preferuncompressed=true -p $HGPORT -d --pid-file=hg.pid
329 329 $ cat hg.pid > $DAEMON_PIDS
330 330 $ cd ..
331 331
332 332 $ hg clone -U http://localhost:$HGPORT preferuncompressed-secret
333 333 requesting all changes
334 334 adding changesets
335 335 adding manifests
336 336 adding file changes
337 337 added 1 changesets with 1 changes to 1 files
338 338 new changesets 96ee1d7354c4
339 339
340 340 $ killdaemons.py
341 341
342 342 Clone not allowed when full bundles disabled and can't serve secrets
343 343
344 344 $ cd server
345 345 $ hg serve --config server.disablefullbundle=true -p $HGPORT -d --pid-file=hg.pid
346 346 $ cat hg.pid > $DAEMON_PIDS
347 347 $ cd ..
348 348
349 349 $ hg clone --stream http://localhost:$HGPORT secret-full-disabled
350 350 warning: stream clone requested but server has them disabled
351 351 requesting all changes
352 352 remote: abort: server has pull-based clones disabled
353 353 abort: pull failed on remote
354 354 (remove --pull if specified or upgrade Mercurial)
355 355 [255]
356 356
357 357 Local stream clone with secrets involved
358 358 (This is just a test over behavior: if you have access to the repo's files,
359 359 there is no security so it isn't important to prevent a clone here.)
360 360
361 361 $ hg clone -U --stream server local-secret
362 362 warning: stream clone requested but server has them disabled
363 363 requesting all changes
364 364 adding changesets
365 365 adding manifests
366 366 adding file changes
367 367 added 1 changesets with 1 changes to 1 files
368 368 new changesets 96ee1d7354c4
369 369
370 370 Stream clone while repo is changing:
371 371
372 372 $ mkdir changing
373 373 $ cd changing
374 374
375 375 extension for delaying the server process so we reliably can modify the repo
376 376 while cloning
377 377
378 378 $ cat > delayer.py <<EOF
379 379 > import time
380 380 > from mercurial import extensions, vfs
381 381 > def __call__(orig, self, path, *args, **kwargs):
382 382 > if path == 'data/f1.i':
383 383 > time.sleep(2)
384 384 > return orig(self, path, *args, **kwargs)
385 385 > extensions.wrapfunction(vfs.vfs, '__call__', __call__)
386 386 > EOF
387 387
388 388 prepare repo with small and big file to cover both code paths in emitrevlogdata
389 389
390 390 $ hg init repo
391 391 $ touch repo/f1
392 392 $ $TESTDIR/seq.py 50000 > repo/f2
393 393 $ hg -R repo ci -Aqm "0"
394 394 $ hg serve -R repo -p $HGPORT1 -d --pid-file=hg.pid --config extensions.delayer=delayer.py
395 395 $ cat hg.pid >> $DAEMON_PIDS
396 396
397 397 clone while modifying the repo between stating file with write lock and
398 398 actually serving file content
399 399
400 400 $ hg clone -q --stream -U http://localhost:$HGPORT1 clone &
401 401 $ sleep 1
402 402 $ echo >> repo/f1
403 403 $ echo >> repo/f2
404 404 $ hg -R repo ci -m "1"
405 405 $ wait
406 406 $ hg -R clone id
407 407 000000000000
408 408 $ cd ..
409 409
410 410 Stream repository with bookmarks
411 411 --------------------------------
412 412
413 413 (revert introduction of secret changeset)
414 414
415 415 $ hg -R server phase --draft 'secret()'
416 416
417 417 add a bookmark
418 418
419 419 $ hg -R server bookmark -r tip some-bookmark
420 420
421 421 clone it
422 422
423 423 #if stream-legacy
424 424 $ hg clone --stream http://localhost:$HGPORT with-bookmarks
425 425 streaming all changes
426 426 1027 files to transfer, 96.3 KB of data
427 427 transferred 96.3 KB in * seconds (*) (glob)
428 428 searching for changes
429 429 no changes found
430 430 updating to branch default
431 431 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
432 432 #endif
433 433 #if stream-bundle2
434 434 $ hg clone --stream http://localhost:$HGPORT with-bookmarks
435 435 streaming all changes
436 436 1033 files to transfer, 96.6 KB of data
437 437 transferred 96.6 KB in * seconds (* */sec) (glob)
438 438 updating to branch default
439 439 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
440 440 #endif
441 441 $ hg -R with-bookmarks bookmarks
442 442 some-bookmark 1:c17445101a72
443 443
444 444 Stream repository with phases
445 445 -----------------------------
446 446
447 447 Clone as publishing
448 448
449 449 $ hg -R server phase -r 'all()'
450 450 0: draft
451 451 1: draft
452 452
453 453 #if stream-legacy
454 454 $ hg clone --stream http://localhost:$HGPORT phase-publish
455 455 streaming all changes
456 456 1027 files to transfer, 96.3 KB of data
457 457 transferred 96.3 KB in * seconds (*) (glob)
458 458 searching for changes
459 459 no changes found
460 460 updating to branch default
461 461 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
462 462 #endif
463 463 #if stream-bundle2
464 464 $ hg clone --stream http://localhost:$HGPORT phase-publish
465 465 streaming all changes
466 466 1033 files to transfer, 96.6 KB of data
467 467 transferred 96.6 KB in * seconds (* */sec) (glob)
468 468 updating to branch default
469 469 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
470 470 #endif
471 471 $ hg -R phase-publish phase -r 'all()'
472 472 0: public
473 473 1: public
474 474
475 475 Clone as non publishing
476 476
477 477 $ cat << EOF >> server/.hg/hgrc
478 478 > [phases]
479 479 > publish = False
480 480 > EOF
481 481 $ killdaemons.py
482 482 $ hg -R server serve -p $HGPORT -d --pid-file=hg.pid
483 483 $ cat hg.pid > $DAEMON_PIDS
484 484
485 485 #if stream-legacy
486 486
487 487 With v1 of the stream protocol, changeset are always cloned as public. It make
488 488 stream v1 unsuitable for non-publishing repository.
489 489
490 490 $ hg clone --stream http://localhost:$HGPORT phase-no-publish
491 491 streaming all changes
492 492 1027 files to transfer, 96.3 KB of data
493 493 transferred 96.3 KB in * seconds (*) (glob)
494 494 searching for changes
495 495 no changes found
496 496 updating to branch default
497 497 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
498 498 $ hg -R phase-no-publish phase -r 'all()'
499 499 0: public
500 500 1: public
501 501 #endif
502 502 #if stream-bundle2
503 503 $ hg clone --stream http://localhost:$HGPORT phase-no-publish
504 504 streaming all changes
505 505 1034 files to transfer, 96.7 KB of data
506 506 transferred 96.7 KB in * seconds (* */sec) (glob)
507 507 updating to branch default
508 508 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
509 509 $ hg -R phase-no-publish phase -r 'all()'
510 510 0: draft
511 511 1: draft
512 512 #endif
513 513
514 514 $ killdaemons.py
General Comments 0
You need to be logged in to leave comments. Login now