##// END OF EJS Templates
server: allow customizing the default repo filter...
Joerg Sonnenberger -
r42006:d6569f1e default
parent child Browse files
Show More
@@ -0,0 +1,38
1 $ hg init test
2 $ cd test
3 $ hg debugbuilddag '+2'
4 $ hg phase --public 0
5
6 $ hg serve -p $HGPORT -d --pid-file=hg.pid -E errors.log
7 $ cat hg.pid >> $DAEMON_PIDS
8 $ cd ..
9 $ hg init test2
10 $ cd test2
11 $ hg incoming http://foo:xyzzy@localhost:$HGPORT/
12 comparing with http://foo:***@localhost:$HGPORT/
13 changeset: 0:1ea73414a91b
14 user: debugbuilddag
15 date: Thu Jan 01 00:00:00 1970 +0000
16 summary: r0
17
18 changeset: 1:66f7d451a68b
19 tag: tip
20 user: debugbuilddag
21 date: Thu Jan 01 00:00:01 1970 +0000
22 summary: r1
23
24 $ killdaemons.py
25
26 $ cd ../test
27 $ hg --config server.view=immutable serve -p $HGPORT -d --pid-file=hg.pid -E errors.log
28 $ cat hg.pid >> $DAEMON_PIDS
29 $ cd ../test2
30 $ hg incoming http://foo:xyzzy@localhost:$HGPORT/
31 comparing with http://foo:***@localhost:$HGPORT/
32 changeset: 0:1ea73414a91b
33 tag: tip
34 user: debugbuilddag
35 date: Thu Jan 01 00:00:00 1970 +0000
36 summary: r0
37
38 $ killdaemons.py
@@ -1,1461 +1,1464
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 def _registerdiffopts(section, configprefix=''):
117 117 coreconfigitem(section, configprefix + 'nodates',
118 118 default=False,
119 119 )
120 120 coreconfigitem(section, configprefix + 'showfunc',
121 121 default=False,
122 122 )
123 123 coreconfigitem(section, configprefix + 'unified',
124 124 default=None,
125 125 )
126 126 coreconfigitem(section, configprefix + 'git',
127 127 default=False,
128 128 )
129 129 coreconfigitem(section, configprefix + 'ignorews',
130 130 default=False,
131 131 )
132 132 coreconfigitem(section, configprefix + 'ignorewsamount',
133 133 default=False,
134 134 )
135 135 coreconfigitem(section, configprefix + 'ignoreblanklines',
136 136 default=False,
137 137 )
138 138 coreconfigitem(section, configprefix + 'ignorewseol',
139 139 default=False,
140 140 )
141 141 coreconfigitem(section, configprefix + 'nobinary',
142 142 default=False,
143 143 )
144 144 coreconfigitem(section, configprefix + 'noprefix',
145 145 default=False,
146 146 )
147 147 coreconfigitem(section, configprefix + 'word-diff',
148 148 default=False,
149 149 )
150 150
151 151 coreconfigitem('alias', '.*',
152 152 default=dynamicdefault,
153 153 generic=True,
154 154 )
155 155 coreconfigitem('auth', 'cookiefile',
156 156 default=None,
157 157 )
158 158 _registerdiffopts(section='annotate')
159 159 # bookmarks.pushing: internal hack for discovery
160 160 coreconfigitem('bookmarks', 'pushing',
161 161 default=list,
162 162 )
163 163 # bundle.mainreporoot: internal hack for bundlerepo
164 164 coreconfigitem('bundle', 'mainreporoot',
165 165 default='',
166 166 )
167 167 coreconfigitem('censor', 'policy',
168 168 default='abort',
169 169 )
170 170 coreconfigitem('chgserver', 'idletimeout',
171 171 default=3600,
172 172 )
173 173 coreconfigitem('chgserver', 'skiphash',
174 174 default=False,
175 175 )
176 176 coreconfigitem('cmdserver', 'log',
177 177 default=None,
178 178 )
179 179 coreconfigitem('cmdserver', 'max-log-files',
180 180 default=7,
181 181 )
182 182 coreconfigitem('cmdserver', 'max-log-size',
183 183 default='1 MB',
184 184 )
185 185 coreconfigitem('cmdserver', 'max-repo-cache',
186 186 default=0,
187 187 )
188 188 coreconfigitem('cmdserver', 'message-encodings',
189 189 default=list,
190 190 )
191 191 coreconfigitem('cmdserver', 'track-log',
192 192 default=lambda: ['chgserver', 'cmdserver', 'repocache'],
193 193 )
194 194 coreconfigitem('color', '.*',
195 195 default=None,
196 196 generic=True,
197 197 )
198 198 coreconfigitem('color', 'mode',
199 199 default='auto',
200 200 )
201 201 coreconfigitem('color', 'pagermode',
202 202 default=dynamicdefault,
203 203 )
204 204 _registerdiffopts(section='commands', configprefix='commit.interactive.')
205 205 coreconfigitem('commands', 'grep.all-files',
206 206 default=False,
207 207 )
208 208 coreconfigitem('commands', 'resolve.confirm',
209 209 default=False,
210 210 )
211 211 coreconfigitem('commands', 'resolve.explicit-re-merge',
212 212 default=False,
213 213 )
214 214 coreconfigitem('commands', 'resolve.mark-check',
215 215 default='none',
216 216 )
217 217 _registerdiffopts(section='commands', configprefix='revert.interactive.')
218 218 coreconfigitem('commands', 'show.aliasprefix',
219 219 default=list,
220 220 )
221 221 coreconfigitem('commands', 'status.relative',
222 222 default=False,
223 223 )
224 224 coreconfigitem('commands', 'status.skipstates',
225 225 default=[],
226 226 )
227 227 coreconfigitem('commands', 'status.terse',
228 228 default='',
229 229 )
230 230 coreconfigitem('commands', 'status.verbose',
231 231 default=False,
232 232 )
233 233 coreconfigitem('commands', 'update.check',
234 234 default=None,
235 235 )
236 236 coreconfigitem('commands', 'update.requiredest',
237 237 default=False,
238 238 )
239 239 coreconfigitem('committemplate', '.*',
240 240 default=None,
241 241 generic=True,
242 242 )
243 243 coreconfigitem('convert', 'bzr.saverev',
244 244 default=True,
245 245 )
246 246 coreconfigitem('convert', 'cvsps.cache',
247 247 default=True,
248 248 )
249 249 coreconfigitem('convert', 'cvsps.fuzz',
250 250 default=60,
251 251 )
252 252 coreconfigitem('convert', 'cvsps.logencoding',
253 253 default=None,
254 254 )
255 255 coreconfigitem('convert', 'cvsps.mergefrom',
256 256 default=None,
257 257 )
258 258 coreconfigitem('convert', 'cvsps.mergeto',
259 259 default=None,
260 260 )
261 261 coreconfigitem('convert', 'git.committeractions',
262 262 default=lambda: ['messagedifferent'],
263 263 )
264 264 coreconfigitem('convert', 'git.extrakeys',
265 265 default=list,
266 266 )
267 267 coreconfigitem('convert', 'git.findcopiesharder',
268 268 default=False,
269 269 )
270 270 coreconfigitem('convert', 'git.remoteprefix',
271 271 default='remote',
272 272 )
273 273 coreconfigitem('convert', 'git.renamelimit',
274 274 default=400,
275 275 )
276 276 coreconfigitem('convert', 'git.saverev',
277 277 default=True,
278 278 )
279 279 coreconfigitem('convert', 'git.similarity',
280 280 default=50,
281 281 )
282 282 coreconfigitem('convert', 'git.skipsubmodules',
283 283 default=False,
284 284 )
285 285 coreconfigitem('convert', 'hg.clonebranches',
286 286 default=False,
287 287 )
288 288 coreconfigitem('convert', 'hg.ignoreerrors',
289 289 default=False,
290 290 )
291 291 coreconfigitem('convert', 'hg.revs',
292 292 default=None,
293 293 )
294 294 coreconfigitem('convert', 'hg.saverev',
295 295 default=False,
296 296 )
297 297 coreconfigitem('convert', 'hg.sourcename',
298 298 default=None,
299 299 )
300 300 coreconfigitem('convert', 'hg.startrev',
301 301 default=None,
302 302 )
303 303 coreconfigitem('convert', 'hg.tagsbranch',
304 304 default='default',
305 305 )
306 306 coreconfigitem('convert', 'hg.usebranchnames',
307 307 default=True,
308 308 )
309 309 coreconfigitem('convert', 'ignoreancestorcheck',
310 310 default=False,
311 311 )
312 312 coreconfigitem('convert', 'localtimezone',
313 313 default=False,
314 314 )
315 315 coreconfigitem('convert', 'p4.encoding',
316 316 default=dynamicdefault,
317 317 )
318 318 coreconfigitem('convert', 'p4.startrev',
319 319 default=0,
320 320 )
321 321 coreconfigitem('convert', 'skiptags',
322 322 default=False,
323 323 )
324 324 coreconfigitem('convert', 'svn.debugsvnlog',
325 325 default=True,
326 326 )
327 327 coreconfigitem('convert', 'svn.trunk',
328 328 default=None,
329 329 )
330 330 coreconfigitem('convert', 'svn.tags',
331 331 default=None,
332 332 )
333 333 coreconfigitem('convert', 'svn.branches',
334 334 default=None,
335 335 )
336 336 coreconfigitem('convert', 'svn.startrev',
337 337 default=0,
338 338 )
339 339 coreconfigitem('debug', 'dirstate.delaywrite',
340 340 default=0,
341 341 )
342 342 coreconfigitem('defaults', '.*',
343 343 default=None,
344 344 generic=True,
345 345 )
346 346 coreconfigitem('devel', 'all-warnings',
347 347 default=False,
348 348 )
349 349 coreconfigitem('devel', 'bundle2.debug',
350 350 default=False,
351 351 )
352 352 coreconfigitem('devel', 'bundle.delta',
353 353 default='',
354 354 )
355 355 coreconfigitem('devel', 'cache-vfs',
356 356 default=None,
357 357 )
358 358 coreconfigitem('devel', 'check-locks',
359 359 default=False,
360 360 )
361 361 coreconfigitem('devel', 'check-relroot',
362 362 default=False,
363 363 )
364 364 coreconfigitem('devel', 'default-date',
365 365 default=None,
366 366 )
367 367 coreconfigitem('devel', 'deprec-warn',
368 368 default=False,
369 369 )
370 370 coreconfigitem('devel', 'disableloaddefaultcerts',
371 371 default=False,
372 372 )
373 373 coreconfigitem('devel', 'warn-empty-changegroup',
374 374 default=False,
375 375 )
376 376 coreconfigitem('devel', 'legacy.exchange',
377 377 default=list,
378 378 )
379 379 coreconfigitem('devel', 'servercafile',
380 380 default='',
381 381 )
382 382 coreconfigitem('devel', 'serverexactprotocol',
383 383 default='',
384 384 )
385 385 coreconfigitem('devel', 'serverrequirecert',
386 386 default=False,
387 387 )
388 388 coreconfigitem('devel', 'strip-obsmarkers',
389 389 default=True,
390 390 )
391 391 coreconfigitem('devel', 'warn-config',
392 392 default=None,
393 393 )
394 394 coreconfigitem('devel', 'warn-config-default',
395 395 default=None,
396 396 )
397 397 coreconfigitem('devel', 'user.obsmarker',
398 398 default=None,
399 399 )
400 400 coreconfigitem('devel', 'warn-config-unknown',
401 401 default=None,
402 402 )
403 403 coreconfigitem('devel', 'debug.copies',
404 404 default=False,
405 405 )
406 406 coreconfigitem('devel', 'debug.extensions',
407 407 default=False,
408 408 )
409 409 coreconfigitem('devel', 'debug.peer-request',
410 410 default=False,
411 411 )
412 412 _registerdiffopts(section='diff')
413 413 coreconfigitem('email', 'bcc',
414 414 default=None,
415 415 )
416 416 coreconfigitem('email', 'cc',
417 417 default=None,
418 418 )
419 419 coreconfigitem('email', 'charsets',
420 420 default=list,
421 421 )
422 422 coreconfigitem('email', 'from',
423 423 default=None,
424 424 )
425 425 coreconfigitem('email', 'method',
426 426 default='smtp',
427 427 )
428 428 coreconfigitem('email', 'reply-to',
429 429 default=None,
430 430 )
431 431 coreconfigitem('email', 'to',
432 432 default=None,
433 433 )
434 434 coreconfigitem('experimental', 'archivemetatemplate',
435 435 default=dynamicdefault,
436 436 )
437 437 coreconfigitem('experimental', 'auto-publish',
438 438 default='publish',
439 439 )
440 440 coreconfigitem('experimental', 'bundle-phases',
441 441 default=False,
442 442 )
443 443 coreconfigitem('experimental', 'bundle2-advertise',
444 444 default=True,
445 445 )
446 446 coreconfigitem('experimental', 'bundle2-output-capture',
447 447 default=False,
448 448 )
449 449 coreconfigitem('experimental', 'bundle2.pushback',
450 450 default=False,
451 451 )
452 452 coreconfigitem('experimental', 'bundle2lazylocking',
453 453 default=False,
454 454 )
455 455 coreconfigitem('experimental', 'bundlecomplevel',
456 456 default=None,
457 457 )
458 458 coreconfigitem('experimental', 'bundlecomplevel.bzip2',
459 459 default=None,
460 460 )
461 461 coreconfigitem('experimental', 'bundlecomplevel.gzip',
462 462 default=None,
463 463 )
464 464 coreconfigitem('experimental', 'bundlecomplevel.none',
465 465 default=None,
466 466 )
467 467 coreconfigitem('experimental', 'bundlecomplevel.zstd',
468 468 default=None,
469 469 )
470 470 coreconfigitem('experimental', 'changegroup3',
471 471 default=False,
472 472 )
473 473 coreconfigitem('experimental', 'cleanup-as-archived',
474 474 default=False,
475 475 )
476 476 coreconfigitem('experimental', 'clientcompressionengines',
477 477 default=list,
478 478 )
479 479 coreconfigitem('experimental', 'copytrace',
480 480 default='on',
481 481 )
482 482 coreconfigitem('experimental', 'copytrace.movecandidateslimit',
483 483 default=100,
484 484 )
485 485 coreconfigitem('experimental', 'copytrace.sourcecommitlimit',
486 486 default=100,
487 487 )
488 488 coreconfigitem('experimental', 'copies.read-from',
489 489 default="filelog-only",
490 490 )
491 491 coreconfigitem('experimental', 'crecordtest',
492 492 default=None,
493 493 )
494 494 coreconfigitem('experimental', 'directaccess',
495 495 default=False,
496 496 )
497 497 coreconfigitem('experimental', 'directaccess.revnums',
498 498 default=False,
499 499 )
500 500 coreconfigitem('experimental', 'editortmpinhg',
501 501 default=False,
502 502 )
503 503 coreconfigitem('experimental', 'evolution',
504 504 default=list,
505 505 )
506 506 coreconfigitem('experimental', 'evolution.allowdivergence',
507 507 default=False,
508 508 alias=[('experimental', 'allowdivergence')]
509 509 )
510 510 coreconfigitem('experimental', 'evolution.allowunstable',
511 511 default=None,
512 512 )
513 513 coreconfigitem('experimental', 'evolution.createmarkers',
514 514 default=None,
515 515 )
516 516 coreconfigitem('experimental', 'evolution.effect-flags',
517 517 default=True,
518 518 alias=[('experimental', 'effect-flags')]
519 519 )
520 520 coreconfigitem('experimental', 'evolution.exchange',
521 521 default=None,
522 522 )
523 523 coreconfigitem('experimental', 'evolution.bundle-obsmarker',
524 524 default=False,
525 525 )
526 526 coreconfigitem('experimental', 'evolution.report-instabilities',
527 527 default=True,
528 528 )
529 529 coreconfigitem('experimental', 'evolution.track-operation',
530 530 default=True,
531 531 )
532 532 coreconfigitem('experimental', 'maxdeltachainspan',
533 533 default=-1,
534 534 )
535 535 coreconfigitem('experimental', 'mergetempdirprefix',
536 536 default=None,
537 537 )
538 538 coreconfigitem('experimental', 'mmapindexthreshold',
539 539 default=None,
540 540 )
541 541 coreconfigitem('experimental', 'narrow',
542 542 default=False,
543 543 )
544 544 coreconfigitem('experimental', 'nonnormalparanoidcheck',
545 545 default=False,
546 546 )
547 547 coreconfigitem('experimental', 'exportableenviron',
548 548 default=list,
549 549 )
550 550 coreconfigitem('experimental', 'extendedheader.index',
551 551 default=None,
552 552 )
553 553 coreconfigitem('experimental', 'extendedheader.similarity',
554 554 default=False,
555 555 )
556 556 coreconfigitem('experimental', 'format.compression',
557 557 default='zlib',
558 558 )
559 559 coreconfigitem('experimental', 'graphshorten',
560 560 default=False,
561 561 )
562 562 coreconfigitem('experimental', 'graphstyle.parent',
563 563 default=dynamicdefault,
564 564 )
565 565 coreconfigitem('experimental', 'graphstyle.missing',
566 566 default=dynamicdefault,
567 567 )
568 568 coreconfigitem('experimental', 'graphstyle.grandparent',
569 569 default=dynamicdefault,
570 570 )
571 571 coreconfigitem('experimental', 'hook-track-tags',
572 572 default=False,
573 573 )
574 574 coreconfigitem('experimental', 'httppeer.advertise-v2',
575 575 default=False,
576 576 )
577 577 coreconfigitem('experimental', 'httppeer.v2-encoder-order',
578 578 default=None,
579 579 )
580 580 coreconfigitem('experimental', 'httppostargs',
581 581 default=False,
582 582 )
583 583 coreconfigitem('experimental', 'mergedriver',
584 584 default=None,
585 585 )
586 586 coreconfigitem('experimental', 'nointerrupt', default=False)
587 587 coreconfigitem('experimental', 'nointerrupt-interactiveonly', default=True)
588 588
589 589 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
590 590 default=False,
591 591 )
592 592 coreconfigitem('experimental', 'remotenames',
593 593 default=False,
594 594 )
595 595 coreconfigitem('experimental', 'removeemptydirs',
596 596 default=True,
597 597 )
598 598 coreconfigitem('experimental', 'revisions.prefixhexnode',
599 599 default=False,
600 600 )
601 601 coreconfigitem('experimental', 'revlogv2',
602 602 default=None,
603 603 )
604 604 coreconfigitem('experimental', 'revisions.disambiguatewithin',
605 605 default=None,
606 606 )
607 607 coreconfigitem('experimental', 'server.filesdata.recommended-batch-size',
608 608 default=50000,
609 609 )
610 610 coreconfigitem('experimental', 'server.manifestdata.recommended-batch-size',
611 611 default=100000,
612 612 )
613 613 coreconfigitem('experimental', 'server.stream-narrow-clones',
614 614 default=False,
615 615 )
616 616 coreconfigitem('experimental', 'single-head-per-branch',
617 617 default=False,
618 618 )
619 619 coreconfigitem('experimental', 'sshserver.support-v2',
620 620 default=False,
621 621 )
622 622 coreconfigitem('experimental', 'sparse-read',
623 623 default=False,
624 624 )
625 625 coreconfigitem('experimental', 'sparse-read.density-threshold',
626 626 default=0.50,
627 627 )
628 628 coreconfigitem('experimental', 'sparse-read.min-gap-size',
629 629 default='65K',
630 630 )
631 631 coreconfigitem('experimental', 'treemanifest',
632 632 default=False,
633 633 )
634 634 coreconfigitem('experimental', 'update.atomic-file',
635 635 default=False,
636 636 )
637 637 coreconfigitem('experimental', 'sshpeer.advertise-v2',
638 638 default=False,
639 639 )
640 640 coreconfigitem('experimental', 'web.apiserver',
641 641 default=False,
642 642 )
643 643 coreconfigitem('experimental', 'web.api.http-v2',
644 644 default=False,
645 645 )
646 646 coreconfigitem('experimental', 'web.api.debugreflect',
647 647 default=False,
648 648 )
649 649 coreconfigitem('experimental', 'worker.wdir-get-thread-safe',
650 650 default=False,
651 651 )
652 652 coreconfigitem('experimental', 'xdiff',
653 653 default=False,
654 654 )
655 655 coreconfigitem('extensions', '.*',
656 656 default=None,
657 657 generic=True,
658 658 )
659 659 coreconfigitem('extdata', '.*',
660 660 default=None,
661 661 generic=True,
662 662 )
663 663 coreconfigitem('format', 'chunkcachesize',
664 664 default=None,
665 665 )
666 666 coreconfigitem('format', 'dotencode',
667 667 default=True,
668 668 )
669 669 coreconfigitem('format', 'generaldelta',
670 670 default=False,
671 671 )
672 672 coreconfigitem('format', 'manifestcachesize',
673 673 default=None,
674 674 )
675 675 coreconfigitem('format', 'maxchainlen',
676 676 default=dynamicdefault,
677 677 )
678 678 coreconfigitem('format', 'obsstore-version',
679 679 default=None,
680 680 )
681 681 coreconfigitem('format', 'sparse-revlog',
682 682 default=True,
683 683 )
684 684 coreconfigitem('format', 'usefncache',
685 685 default=True,
686 686 )
687 687 coreconfigitem('format', 'usegeneraldelta',
688 688 default=True,
689 689 )
690 690 coreconfigitem('format', 'usestore',
691 691 default=True,
692 692 )
693 693 coreconfigitem('format', 'internal-phase',
694 694 default=False,
695 695 )
696 696 coreconfigitem('fsmonitor', 'warn_when_unused',
697 697 default=True,
698 698 )
699 699 coreconfigitem('fsmonitor', 'warn_update_file_count',
700 700 default=50000,
701 701 )
702 702 coreconfigitem('help', br'hidden-command\..*',
703 703 default=False,
704 704 generic=True,
705 705 )
706 706 coreconfigitem('help', br'hidden-topic\..*',
707 707 default=False,
708 708 generic=True,
709 709 )
710 710 coreconfigitem('hooks', '.*',
711 711 default=dynamicdefault,
712 712 generic=True,
713 713 )
714 714 coreconfigitem('hgweb-paths', '.*',
715 715 default=list,
716 716 generic=True,
717 717 )
718 718 coreconfigitem('hostfingerprints', '.*',
719 719 default=list,
720 720 generic=True,
721 721 )
722 722 coreconfigitem('hostsecurity', 'ciphers',
723 723 default=None,
724 724 )
725 725 coreconfigitem('hostsecurity', 'disabletls10warning',
726 726 default=False,
727 727 )
728 728 coreconfigitem('hostsecurity', 'minimumprotocol',
729 729 default=dynamicdefault,
730 730 )
731 731 coreconfigitem('hostsecurity', '.*:minimumprotocol$',
732 732 default=dynamicdefault,
733 733 generic=True,
734 734 )
735 735 coreconfigitem('hostsecurity', '.*:ciphers$',
736 736 default=dynamicdefault,
737 737 generic=True,
738 738 )
739 739 coreconfigitem('hostsecurity', '.*:fingerprints$',
740 740 default=list,
741 741 generic=True,
742 742 )
743 743 coreconfigitem('hostsecurity', '.*:verifycertsfile$',
744 744 default=None,
745 745 generic=True,
746 746 )
747 747
748 748 coreconfigitem('http_proxy', 'always',
749 749 default=False,
750 750 )
751 751 coreconfigitem('http_proxy', 'host',
752 752 default=None,
753 753 )
754 754 coreconfigitem('http_proxy', 'no',
755 755 default=list,
756 756 )
757 757 coreconfigitem('http_proxy', 'passwd',
758 758 default=None,
759 759 )
760 760 coreconfigitem('http_proxy', 'user',
761 761 default=None,
762 762 )
763 763
764 764 coreconfigitem('http', 'timeout',
765 765 default=None,
766 766 )
767 767
768 768 coreconfigitem('logtoprocess', 'commandexception',
769 769 default=None,
770 770 )
771 771 coreconfigitem('logtoprocess', 'commandfinish',
772 772 default=None,
773 773 )
774 774 coreconfigitem('logtoprocess', 'command',
775 775 default=None,
776 776 )
777 777 coreconfigitem('logtoprocess', 'develwarn',
778 778 default=None,
779 779 )
780 780 coreconfigitem('logtoprocess', 'uiblocked',
781 781 default=None,
782 782 )
783 783 coreconfigitem('merge', 'checkunknown',
784 784 default='abort',
785 785 )
786 786 coreconfigitem('merge', 'checkignored',
787 787 default='abort',
788 788 )
789 789 coreconfigitem('experimental', 'merge.checkpathconflicts',
790 790 default=False,
791 791 )
792 792 coreconfigitem('merge', 'followcopies',
793 793 default=True,
794 794 )
795 795 coreconfigitem('merge', 'on-failure',
796 796 default='continue',
797 797 )
798 798 coreconfigitem('merge', 'preferancestor',
799 799 default=lambda: ['*'],
800 800 )
801 801 coreconfigitem('merge', 'strict-capability-check',
802 802 default=False,
803 803 )
804 804 coreconfigitem('merge-tools', '.*',
805 805 default=None,
806 806 generic=True,
807 807 )
808 808 coreconfigitem('merge-tools', br'.*\.args$',
809 809 default="$local $base $other",
810 810 generic=True,
811 811 priority=-1,
812 812 )
813 813 coreconfigitem('merge-tools', br'.*\.binary$',
814 814 default=False,
815 815 generic=True,
816 816 priority=-1,
817 817 )
818 818 coreconfigitem('merge-tools', br'.*\.check$',
819 819 default=list,
820 820 generic=True,
821 821 priority=-1,
822 822 )
823 823 coreconfigitem('merge-tools', br'.*\.checkchanged$',
824 824 default=False,
825 825 generic=True,
826 826 priority=-1,
827 827 )
828 828 coreconfigitem('merge-tools', br'.*\.executable$',
829 829 default=dynamicdefault,
830 830 generic=True,
831 831 priority=-1,
832 832 )
833 833 coreconfigitem('merge-tools', br'.*\.fixeol$',
834 834 default=False,
835 835 generic=True,
836 836 priority=-1,
837 837 )
838 838 coreconfigitem('merge-tools', br'.*\.gui$',
839 839 default=False,
840 840 generic=True,
841 841 priority=-1,
842 842 )
843 843 coreconfigitem('merge-tools', br'.*\.mergemarkers$',
844 844 default='basic',
845 845 generic=True,
846 846 priority=-1,
847 847 )
848 848 coreconfigitem('merge-tools', br'.*\.mergemarkertemplate$',
849 849 default=dynamicdefault, # take from ui.mergemarkertemplate
850 850 generic=True,
851 851 priority=-1,
852 852 )
853 853 coreconfigitem('merge-tools', br'.*\.priority$',
854 854 default=0,
855 855 generic=True,
856 856 priority=-1,
857 857 )
858 858 coreconfigitem('merge-tools', br'.*\.premerge$',
859 859 default=dynamicdefault,
860 860 generic=True,
861 861 priority=-1,
862 862 )
863 863 coreconfigitem('merge-tools', br'.*\.symlink$',
864 864 default=False,
865 865 generic=True,
866 866 priority=-1,
867 867 )
868 868 coreconfigitem('pager', 'attend-.*',
869 869 default=dynamicdefault,
870 870 generic=True,
871 871 )
872 872 coreconfigitem('pager', 'ignore',
873 873 default=list,
874 874 )
875 875 coreconfigitem('pager', 'pager',
876 876 default=dynamicdefault,
877 877 )
878 878 coreconfigitem('patch', 'eol',
879 879 default='strict',
880 880 )
881 881 coreconfigitem('patch', 'fuzz',
882 882 default=2,
883 883 )
884 884 coreconfigitem('paths', 'default',
885 885 default=None,
886 886 )
887 887 coreconfigitem('paths', 'default-push',
888 888 default=None,
889 889 )
890 890 coreconfigitem('paths', '.*',
891 891 default=None,
892 892 generic=True,
893 893 )
894 894 coreconfigitem('phases', 'checksubrepos',
895 895 default='follow',
896 896 )
897 897 coreconfigitem('phases', 'new-commit',
898 898 default='draft',
899 899 )
900 900 coreconfigitem('phases', 'publish',
901 901 default=True,
902 902 )
903 903 coreconfigitem('profiling', 'enabled',
904 904 default=False,
905 905 )
906 906 coreconfigitem('profiling', 'format',
907 907 default='text',
908 908 )
909 909 coreconfigitem('profiling', 'freq',
910 910 default=1000,
911 911 )
912 912 coreconfigitem('profiling', 'limit',
913 913 default=30,
914 914 )
915 915 coreconfigitem('profiling', 'nested',
916 916 default=0,
917 917 )
918 918 coreconfigitem('profiling', 'output',
919 919 default=None,
920 920 )
921 921 coreconfigitem('profiling', 'showmax',
922 922 default=0.999,
923 923 )
924 924 coreconfigitem('profiling', 'showmin',
925 925 default=dynamicdefault,
926 926 )
927 927 coreconfigitem('profiling', 'sort',
928 928 default='inlinetime',
929 929 )
930 930 coreconfigitem('profiling', 'statformat',
931 931 default='hotpath',
932 932 )
933 933 coreconfigitem('profiling', 'time-track',
934 934 default=dynamicdefault,
935 935 )
936 936 coreconfigitem('profiling', 'type',
937 937 default='stat',
938 938 )
939 939 coreconfigitem('progress', 'assume-tty',
940 940 default=False,
941 941 )
942 942 coreconfigitem('progress', 'changedelay',
943 943 default=1,
944 944 )
945 945 coreconfigitem('progress', 'clear-complete',
946 946 default=True,
947 947 )
948 948 coreconfigitem('progress', 'debug',
949 949 default=False,
950 950 )
951 951 coreconfigitem('progress', 'delay',
952 952 default=3,
953 953 )
954 954 coreconfigitem('progress', 'disable',
955 955 default=False,
956 956 )
957 957 coreconfigitem('progress', 'estimateinterval',
958 958 default=60.0,
959 959 )
960 960 coreconfigitem('progress', 'format',
961 961 default=lambda: ['topic', 'bar', 'number', 'estimate'],
962 962 )
963 963 coreconfigitem('progress', 'refresh',
964 964 default=0.1,
965 965 )
966 966 coreconfigitem('progress', 'width',
967 967 default=dynamicdefault,
968 968 )
969 969 coreconfigitem('push', 'pushvars.server',
970 970 default=False,
971 971 )
972 972 coreconfigitem('rewrite', 'backup-bundle',
973 973 default=True,
974 974 alias=[('ui', 'history-editing-backup')],
975 975 )
976 976 coreconfigitem('rewrite', 'update-timestamp',
977 977 default=False,
978 978 )
979 979 coreconfigitem('storage', 'new-repo-backend',
980 980 default='revlogv1',
981 981 )
982 982 coreconfigitem('storage', 'revlog.optimize-delta-parent-choice',
983 983 default=True,
984 984 alias=[('format', 'aggressivemergedeltas')],
985 985 )
986 986 coreconfigitem('storage', 'revlog.reuse-external-delta',
987 987 default=True,
988 988 )
989 989 coreconfigitem('storage', 'revlog.reuse-external-delta-parent',
990 990 default=None,
991 991 )
992 992 coreconfigitem('server', 'bookmarks-pushkey-compat',
993 993 default=True,
994 994 )
995 995 coreconfigitem('server', 'bundle1',
996 996 default=True,
997 997 )
998 998 coreconfigitem('server', 'bundle1gd',
999 999 default=None,
1000 1000 )
1001 1001 coreconfigitem('server', 'bundle1.pull',
1002 1002 default=None,
1003 1003 )
1004 1004 coreconfigitem('server', 'bundle1gd.pull',
1005 1005 default=None,
1006 1006 )
1007 1007 coreconfigitem('server', 'bundle1.push',
1008 1008 default=None,
1009 1009 )
1010 1010 coreconfigitem('server', 'bundle1gd.push',
1011 1011 default=None,
1012 1012 )
1013 1013 coreconfigitem('server', 'bundle2.stream',
1014 1014 default=True,
1015 1015 alias=[('experimental', 'bundle2.stream')]
1016 1016 )
1017 1017 coreconfigitem('server', 'compressionengines',
1018 1018 default=list,
1019 1019 )
1020 1020 coreconfigitem('server', 'concurrent-push-mode',
1021 1021 default='strict',
1022 1022 )
1023 1023 coreconfigitem('server', 'disablefullbundle',
1024 1024 default=False,
1025 1025 )
1026 1026 coreconfigitem('server', 'maxhttpheaderlen',
1027 1027 default=1024,
1028 1028 )
1029 1029 coreconfigitem('server', 'pullbundle',
1030 1030 default=False,
1031 1031 )
1032 1032 coreconfigitem('server', 'preferuncompressed',
1033 1033 default=False,
1034 1034 )
1035 1035 coreconfigitem('server', 'streamunbundle',
1036 1036 default=False,
1037 1037 )
1038 1038 coreconfigitem('server', 'uncompressed',
1039 1039 default=True,
1040 1040 )
1041 1041 coreconfigitem('server', 'uncompressedallowsecret',
1042 1042 default=False,
1043 1043 )
1044 coreconfigitem('server', 'view',
1045 default='served',
1046 )
1044 1047 coreconfigitem('server', 'validate',
1045 1048 default=False,
1046 1049 )
1047 1050 coreconfigitem('server', 'zliblevel',
1048 1051 default=-1,
1049 1052 )
1050 1053 coreconfigitem('server', 'zstdlevel',
1051 1054 default=3,
1052 1055 )
1053 1056 coreconfigitem('share', 'pool',
1054 1057 default=None,
1055 1058 )
1056 1059 coreconfigitem('share', 'poolnaming',
1057 1060 default='identity',
1058 1061 )
1059 1062 coreconfigitem('smtp', 'host',
1060 1063 default=None,
1061 1064 )
1062 1065 coreconfigitem('smtp', 'local_hostname',
1063 1066 default=None,
1064 1067 )
1065 1068 coreconfigitem('smtp', 'password',
1066 1069 default=None,
1067 1070 )
1068 1071 coreconfigitem('smtp', 'port',
1069 1072 default=dynamicdefault,
1070 1073 )
1071 1074 coreconfigitem('smtp', 'tls',
1072 1075 default='none',
1073 1076 )
1074 1077 coreconfigitem('smtp', 'username',
1075 1078 default=None,
1076 1079 )
1077 1080 coreconfigitem('sparse', 'missingwarning',
1078 1081 default=True,
1079 1082 )
1080 1083 coreconfigitem('subrepos', 'allowed',
1081 1084 default=dynamicdefault, # to make backporting simpler
1082 1085 )
1083 1086 coreconfigitem('subrepos', 'hg:allowed',
1084 1087 default=dynamicdefault,
1085 1088 )
1086 1089 coreconfigitem('subrepos', 'git:allowed',
1087 1090 default=dynamicdefault,
1088 1091 )
1089 1092 coreconfigitem('subrepos', 'svn:allowed',
1090 1093 default=dynamicdefault,
1091 1094 )
1092 1095 coreconfigitem('templates', '.*',
1093 1096 default=None,
1094 1097 generic=True,
1095 1098 )
1096 1099 coreconfigitem('templateconfig', '.*',
1097 1100 default=dynamicdefault,
1098 1101 generic=True,
1099 1102 )
1100 1103 coreconfigitem('trusted', 'groups',
1101 1104 default=list,
1102 1105 )
1103 1106 coreconfigitem('trusted', 'users',
1104 1107 default=list,
1105 1108 )
1106 1109 coreconfigitem('ui', '_usedassubrepo',
1107 1110 default=False,
1108 1111 )
1109 1112 coreconfigitem('ui', 'allowemptycommit',
1110 1113 default=False,
1111 1114 )
1112 1115 coreconfigitem('ui', 'archivemeta',
1113 1116 default=True,
1114 1117 )
1115 1118 coreconfigitem('ui', 'askusername',
1116 1119 default=False,
1117 1120 )
1118 1121 coreconfigitem('ui', 'clonebundlefallback',
1119 1122 default=False,
1120 1123 )
1121 1124 coreconfigitem('ui', 'clonebundleprefers',
1122 1125 default=list,
1123 1126 )
1124 1127 coreconfigitem('ui', 'clonebundles',
1125 1128 default=True,
1126 1129 )
1127 1130 coreconfigitem('ui', 'color',
1128 1131 default='auto',
1129 1132 )
1130 1133 coreconfigitem('ui', 'commitsubrepos',
1131 1134 default=False,
1132 1135 )
1133 1136 coreconfigitem('ui', 'debug',
1134 1137 default=False,
1135 1138 )
1136 1139 coreconfigitem('ui', 'debugger',
1137 1140 default=None,
1138 1141 )
1139 1142 coreconfigitem('ui', 'editor',
1140 1143 default=dynamicdefault,
1141 1144 )
1142 1145 coreconfigitem('ui', 'fallbackencoding',
1143 1146 default=None,
1144 1147 )
1145 1148 coreconfigitem('ui', 'forcecwd',
1146 1149 default=None,
1147 1150 )
1148 1151 coreconfigitem('ui', 'forcemerge',
1149 1152 default=None,
1150 1153 )
1151 1154 coreconfigitem('ui', 'formatdebug',
1152 1155 default=False,
1153 1156 )
1154 1157 coreconfigitem('ui', 'formatjson',
1155 1158 default=False,
1156 1159 )
1157 1160 coreconfigitem('ui', 'formatted',
1158 1161 default=None,
1159 1162 )
1160 1163 coreconfigitem('ui', 'graphnodetemplate',
1161 1164 default=None,
1162 1165 )
1163 1166 coreconfigitem('ui', 'interactive',
1164 1167 default=None,
1165 1168 )
1166 1169 coreconfigitem('ui', 'interface',
1167 1170 default=None,
1168 1171 )
1169 1172 coreconfigitem('ui', 'interface.chunkselector',
1170 1173 default=None,
1171 1174 )
1172 1175 coreconfigitem('ui', 'large-file-limit',
1173 1176 default=10000000,
1174 1177 )
1175 1178 coreconfigitem('ui', 'logblockedtimes',
1176 1179 default=False,
1177 1180 )
1178 1181 coreconfigitem('ui', 'logtemplate',
1179 1182 default=None,
1180 1183 )
1181 1184 coreconfigitem('ui', 'merge',
1182 1185 default=None,
1183 1186 )
1184 1187 coreconfigitem('ui', 'mergemarkers',
1185 1188 default='basic',
1186 1189 )
1187 1190 coreconfigitem('ui', 'mergemarkertemplate',
1188 1191 default=('{node|short} '
1189 1192 '{ifeq(tags, "tip", "", '
1190 1193 'ifeq(tags, "", "", "{tags} "))}'
1191 1194 '{if(bookmarks, "{bookmarks} ")}'
1192 1195 '{ifeq(branch, "default", "", "{branch} ")}'
1193 1196 '- {author|user}: {desc|firstline}')
1194 1197 )
1195 1198 coreconfigitem('ui', 'message-output',
1196 1199 default='stdio',
1197 1200 )
1198 1201 coreconfigitem('ui', 'nontty',
1199 1202 default=False,
1200 1203 )
1201 1204 coreconfigitem('ui', 'origbackuppath',
1202 1205 default=None,
1203 1206 )
1204 1207 coreconfigitem('ui', 'paginate',
1205 1208 default=True,
1206 1209 )
1207 1210 coreconfigitem('ui', 'patch',
1208 1211 default=None,
1209 1212 )
1210 1213 coreconfigitem('ui', 'pre-merge-tool-output-template',
1211 1214 default=None,
1212 1215 )
1213 1216 coreconfigitem('ui', 'portablefilenames',
1214 1217 default='warn',
1215 1218 )
1216 1219 coreconfigitem('ui', 'promptecho',
1217 1220 default=False,
1218 1221 )
1219 1222 coreconfigitem('ui', 'quiet',
1220 1223 default=False,
1221 1224 )
1222 1225 coreconfigitem('ui', 'quietbookmarkmove',
1223 1226 default=False,
1224 1227 )
1225 1228 coreconfigitem('ui', 'relative-paths',
1226 1229 default='legacy',
1227 1230 )
1228 1231 coreconfigitem('ui', 'remotecmd',
1229 1232 default='hg',
1230 1233 )
1231 1234 coreconfigitem('ui', 'report_untrusted',
1232 1235 default=True,
1233 1236 )
1234 1237 coreconfigitem('ui', 'rollback',
1235 1238 default=True,
1236 1239 )
1237 1240 coreconfigitem('ui', 'signal-safe-lock',
1238 1241 default=True,
1239 1242 )
1240 1243 coreconfigitem('ui', 'slash',
1241 1244 default=False,
1242 1245 )
1243 1246 coreconfigitem('ui', 'ssh',
1244 1247 default='ssh',
1245 1248 )
1246 1249 coreconfigitem('ui', 'ssherrorhint',
1247 1250 default=None,
1248 1251 )
1249 1252 coreconfigitem('ui', 'statuscopies',
1250 1253 default=False,
1251 1254 )
1252 1255 coreconfigitem('ui', 'strict',
1253 1256 default=False,
1254 1257 )
1255 1258 coreconfigitem('ui', 'style',
1256 1259 default='',
1257 1260 )
1258 1261 coreconfigitem('ui', 'supportcontact',
1259 1262 default=None,
1260 1263 )
1261 1264 coreconfigitem('ui', 'textwidth',
1262 1265 default=78,
1263 1266 )
1264 1267 coreconfigitem('ui', 'timeout',
1265 1268 default='600',
1266 1269 )
1267 1270 coreconfigitem('ui', 'timeout.warn',
1268 1271 default=0,
1269 1272 )
1270 1273 coreconfigitem('ui', 'traceback',
1271 1274 default=False,
1272 1275 )
1273 1276 coreconfigitem('ui', 'tweakdefaults',
1274 1277 default=False,
1275 1278 )
1276 1279 coreconfigitem('ui', 'username',
1277 1280 alias=[('ui', 'user')]
1278 1281 )
1279 1282 coreconfigitem('ui', 'verbose',
1280 1283 default=False,
1281 1284 )
1282 1285 coreconfigitem('verify', 'skipflags',
1283 1286 default=None,
1284 1287 )
1285 1288 coreconfigitem('web', 'allowbz2',
1286 1289 default=False,
1287 1290 )
1288 1291 coreconfigitem('web', 'allowgz',
1289 1292 default=False,
1290 1293 )
1291 1294 coreconfigitem('web', 'allow-pull',
1292 1295 alias=[('web', 'allowpull')],
1293 1296 default=True,
1294 1297 )
1295 1298 coreconfigitem('web', 'allow-push',
1296 1299 alias=[('web', 'allow_push')],
1297 1300 default=list,
1298 1301 )
1299 1302 coreconfigitem('web', 'allowzip',
1300 1303 default=False,
1301 1304 )
1302 1305 coreconfigitem('web', 'archivesubrepos',
1303 1306 default=False,
1304 1307 )
1305 1308 coreconfigitem('web', 'cache',
1306 1309 default=True,
1307 1310 )
1308 1311 coreconfigitem('web', 'comparisoncontext',
1309 1312 default=5,
1310 1313 )
1311 1314 coreconfigitem('web', 'contact',
1312 1315 default=None,
1313 1316 )
1314 1317 coreconfigitem('web', 'deny_push',
1315 1318 default=list,
1316 1319 )
1317 1320 coreconfigitem('web', 'guessmime',
1318 1321 default=False,
1319 1322 )
1320 1323 coreconfigitem('web', 'hidden',
1321 1324 default=False,
1322 1325 )
1323 1326 coreconfigitem('web', 'labels',
1324 1327 default=list,
1325 1328 )
1326 1329 coreconfigitem('web', 'logoimg',
1327 1330 default='hglogo.png',
1328 1331 )
1329 1332 coreconfigitem('web', 'logourl',
1330 1333 default='https://mercurial-scm.org/',
1331 1334 )
1332 1335 coreconfigitem('web', 'accesslog',
1333 1336 default='-',
1334 1337 )
1335 1338 coreconfigitem('web', 'address',
1336 1339 default='',
1337 1340 )
1338 1341 coreconfigitem('web', 'allow-archive',
1339 1342 alias=[('web', 'allow_archive')],
1340 1343 default=list,
1341 1344 )
1342 1345 coreconfigitem('web', 'allow_read',
1343 1346 default=list,
1344 1347 )
1345 1348 coreconfigitem('web', 'baseurl',
1346 1349 default=None,
1347 1350 )
1348 1351 coreconfigitem('web', 'cacerts',
1349 1352 default=None,
1350 1353 )
1351 1354 coreconfigitem('web', 'certificate',
1352 1355 default=None,
1353 1356 )
1354 1357 coreconfigitem('web', 'collapse',
1355 1358 default=False,
1356 1359 )
1357 1360 coreconfigitem('web', 'csp',
1358 1361 default=None,
1359 1362 )
1360 1363 coreconfigitem('web', 'deny_read',
1361 1364 default=list,
1362 1365 )
1363 1366 coreconfigitem('web', 'descend',
1364 1367 default=True,
1365 1368 )
1366 1369 coreconfigitem('web', 'description',
1367 1370 default="",
1368 1371 )
1369 1372 coreconfigitem('web', 'encoding',
1370 1373 default=lambda: encoding.encoding,
1371 1374 )
1372 1375 coreconfigitem('web', 'errorlog',
1373 1376 default='-',
1374 1377 )
1375 1378 coreconfigitem('web', 'ipv6',
1376 1379 default=False,
1377 1380 )
1378 1381 coreconfigitem('web', 'maxchanges',
1379 1382 default=10,
1380 1383 )
1381 1384 coreconfigitem('web', 'maxfiles',
1382 1385 default=10,
1383 1386 )
1384 1387 coreconfigitem('web', 'maxshortchanges',
1385 1388 default=60,
1386 1389 )
1387 1390 coreconfigitem('web', 'motd',
1388 1391 default='',
1389 1392 )
1390 1393 coreconfigitem('web', 'name',
1391 1394 default=dynamicdefault,
1392 1395 )
1393 1396 coreconfigitem('web', 'port',
1394 1397 default=8000,
1395 1398 )
1396 1399 coreconfigitem('web', 'prefix',
1397 1400 default='',
1398 1401 )
1399 1402 coreconfigitem('web', 'push_ssl',
1400 1403 default=True,
1401 1404 )
1402 1405 coreconfigitem('web', 'refreshinterval',
1403 1406 default=20,
1404 1407 )
1405 1408 coreconfigitem('web', 'server-header',
1406 1409 default=None,
1407 1410 )
1408 1411 coreconfigitem('web', 'static',
1409 1412 default=None,
1410 1413 )
1411 1414 coreconfigitem('web', 'staticurl',
1412 1415 default=None,
1413 1416 )
1414 1417 coreconfigitem('web', 'stripes',
1415 1418 default=1,
1416 1419 )
1417 1420 coreconfigitem('web', 'style',
1418 1421 default='paper',
1419 1422 )
1420 1423 coreconfigitem('web', 'templates',
1421 1424 default=None,
1422 1425 )
1423 1426 coreconfigitem('web', 'view',
1424 1427 default='served',
1425 1428 )
1426 1429 coreconfigitem('worker', 'backgroundclose',
1427 1430 default=dynamicdefault,
1428 1431 )
1429 1432 # Windows defaults to a limit of 512 open files. A buffer of 128
1430 1433 # should give us enough headway.
1431 1434 coreconfigitem('worker', 'backgroundclosemaxqueue',
1432 1435 default=384,
1433 1436 )
1434 1437 coreconfigitem('worker', 'backgroundcloseminfilecount',
1435 1438 default=2048,
1436 1439 )
1437 1440 coreconfigitem('worker', 'backgroundclosethreadcount',
1438 1441 default=4,
1439 1442 )
1440 1443 coreconfigitem('worker', 'enabled',
1441 1444 default=True,
1442 1445 )
1443 1446 coreconfigitem('worker', 'numcpus',
1444 1447 default=None,
1445 1448 )
1446 1449
1447 1450 # Rebase related configuration moved to core because other extension are doing
1448 1451 # strange things. For example, shelve import the extensions to reuse some bit
1449 1452 # without formally loading it.
1450 1453 coreconfigitem('commands', 'rebase.requiredest',
1451 1454 default=False,
1452 1455 )
1453 1456 coreconfigitem('experimental', 'rebaseskipobsolete',
1454 1457 default=True,
1455 1458 )
1456 1459 coreconfigitem('rebase', 'singletransaction',
1457 1460 default=False,
1458 1461 )
1459 1462 coreconfigitem('rebase', 'experimental.inmemory',
1460 1463 default=False,
1461 1464 )
@@ -1,2817 +1,2823
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 condenses 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 ``sparse-revlog``
861 861 Enable or disable the ``sparse-revlog`` delta strategy. This format improves
862 862 delta re-use inside revlog. For very branchy repositories, it results in a
863 863 smaller store. For repositories with many revisions, it also helps
864 864 performance (by using shortened delta chains.)
865 865
866 866 Repositories with this on-disk format require Mercurial version 4.7
867 867
868 868 Enabled by default.
869 869
870 870 ``graph``
871 871 ---------
872 872
873 873 Web graph view configuration. This section let you change graph
874 874 elements display properties by branches, for instance to make the
875 875 ``default`` branch stand out.
876 876
877 877 Each line has the following format::
878 878
879 879 <branch>.<argument> = <value>
880 880
881 881 where ``<branch>`` is the name of the branch being
882 882 customized. Example::
883 883
884 884 [graph]
885 885 # 2px width
886 886 default.width = 2
887 887 # red color
888 888 default.color = FF0000
889 889
890 890 Supported arguments:
891 891
892 892 ``width``
893 893 Set branch edges width in pixels.
894 894
895 895 ``color``
896 896 Set branch edges color in hexadecimal RGB notation.
897 897
898 898 ``hooks``
899 899 ---------
900 900
901 901 Commands or Python functions that get automatically executed by
902 902 various actions such as starting or finishing a commit. Multiple
903 903 hooks can be run for the same action by appending a suffix to the
904 904 action. Overriding a site-wide hook can be done by changing its
905 905 value or setting it to an empty string. Hooks can be prioritized
906 906 by adding a prefix of ``priority.`` to the hook name on a new line
907 907 and setting the priority. The default priority is 0.
908 908
909 909 Example ``.hg/hgrc``::
910 910
911 911 [hooks]
912 912 # update working directory after adding changesets
913 913 changegroup.update = hg update
914 914 # do not use the site-wide hook
915 915 incoming =
916 916 incoming.email = /my/email/hook
917 917 incoming.autobuild = /my/build/hook
918 918 # force autobuild hook to run before other incoming hooks
919 919 priority.incoming.autobuild = 1
920 920
921 921 Most hooks are run with environment variables set that give useful
922 922 additional information. For each hook below, the environment variables
923 923 it is passed are listed with names in the form ``$HG_foo``. The
924 924 ``$HG_HOOKTYPE`` and ``$HG_HOOKNAME`` variables are set for all hooks.
925 925 They contain the type of hook which triggered the run and the full name
926 926 of the hook in the config, respectively. In the example above, this will
927 927 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
928 928
929 929 .. container:: windows
930 930
931 931 Some basic Unix syntax can be enabled for portability, including ``$VAR``
932 932 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
933 933 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
934 934 on Unix. To use a literal ``$`` or ``~``, it must be escaped with a back
935 935 slash or inside of a strong quote. Strong quotes will be replaced by
936 936 double quotes after processing.
937 937
938 938 This feature is enabled by adding a prefix of ``tonative.`` to the hook
939 939 name on a new line, and setting it to ``True``. For example::
940 940
941 941 [hooks]
942 942 incoming.autobuild = /my/build/hook
943 943 # enable translation to cmd.exe syntax for autobuild hook
944 944 tonative.incoming.autobuild = True
945 945
946 946 ``changegroup``
947 947 Run after a changegroup has been added via push, pull or unbundle. The ID of
948 948 the first new changeset is in ``$HG_NODE`` and last is in ``$HG_NODE_LAST``.
949 949 The URL from which changes came is in ``$HG_URL``.
950 950
951 951 ``commit``
952 952 Run after a changeset has been created in the local repository. The ID
953 953 of the newly created changeset is in ``$HG_NODE``. Parent changeset
954 954 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
955 955
956 956 ``incoming``
957 957 Run after a changeset has been pulled, pushed, or unbundled into
958 958 the local repository. The ID of the newly arrived changeset is in
959 959 ``$HG_NODE``. The URL that was source of the changes is in ``$HG_URL``.
960 960
961 961 ``outgoing``
962 962 Run after sending changes from the local repository to another. The ID of
963 963 first changeset sent is in ``$HG_NODE``. The source of operation is in
964 964 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
965 965
966 966 ``post-<command>``
967 967 Run after successful invocations of the associated command. The
968 968 contents of the command line are passed as ``$HG_ARGS`` and the result
969 969 code in ``$HG_RESULT``. Parsed command line arguments are passed as
970 970 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
971 971 the python data internally passed to <command>. ``$HG_OPTS`` is a
972 972 dictionary of options (with unspecified options set to their defaults).
973 973 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
974 974
975 975 ``fail-<command>``
976 976 Run after a failed invocation of an associated command. The contents
977 977 of the command line are passed as ``$HG_ARGS``. Parsed command line
978 978 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
979 979 string representations of the python data internally passed to
980 980 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
981 981 options set to their defaults). ``$HG_PATS`` is a list of arguments.
982 982 Hook failure is ignored.
983 983
984 984 ``pre-<command>``
985 985 Run before executing the associated command. The contents of the
986 986 command line are passed as ``$HG_ARGS``. Parsed command line arguments
987 987 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
988 988 representations of the data internally passed to <command>. ``$HG_OPTS``
989 989 is a dictionary of options (with unspecified options set to their
990 990 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
991 991 failure, the command doesn't execute and Mercurial returns the failure
992 992 code.
993 993
994 994 ``prechangegroup``
995 995 Run before a changegroup is added via push, pull or unbundle. Exit
996 996 status 0 allows the changegroup to proceed. A non-zero status will
997 997 cause the push, pull or unbundle to fail. The URL from which changes
998 998 will come is in ``$HG_URL``.
999 999
1000 1000 ``precommit``
1001 1001 Run before starting a local commit. Exit status 0 allows the
1002 1002 commit to proceed. A non-zero status will cause the commit to fail.
1003 1003 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1004 1004
1005 1005 ``prelistkeys``
1006 1006 Run before listing pushkeys (like bookmarks) in the
1007 1007 repository. A non-zero status will cause failure. The key namespace is
1008 1008 in ``$HG_NAMESPACE``.
1009 1009
1010 1010 ``preoutgoing``
1011 1011 Run before collecting changes to send from the local repository to
1012 1012 another. A non-zero status will cause failure. This lets you prevent
1013 1013 pull over HTTP or SSH. It can also prevent propagating commits (via
1014 1014 local pull, push (outbound) or bundle commands), but not completely,
1015 1015 since you can just copy files instead. The source of operation is in
1016 1016 ``$HG_SOURCE``. If "serve", the operation is happening on behalf of a remote
1017 1017 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1018 1018 is happening on behalf of a repository on same system.
1019 1019
1020 1020 ``prepushkey``
1021 1021 Run before a pushkey (like a bookmark) is added to the
1022 1022 repository. A non-zero status will cause the key to be rejected. The
1023 1023 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
1024 1024 the old value (if any) is in ``$HG_OLD``, and the new value is in
1025 1025 ``$HG_NEW``.
1026 1026
1027 1027 ``pretag``
1028 1028 Run before creating a tag. Exit status 0 allows the tag to be
1029 1029 created. A non-zero status will cause the tag to fail. The ID of the
1030 1030 changeset to tag is in ``$HG_NODE``. The name of tag is in ``$HG_TAG``. The
1031 1031 tag is local if ``$HG_LOCAL=1``, or in the repository if ``$HG_LOCAL=0``.
1032 1032
1033 1033 ``pretxnopen``
1034 1034 Run before any new repository transaction is open. The reason for the
1035 1035 transaction will be in ``$HG_TXNNAME``, and a unique identifier for the
1036 1036 transaction will be in ``HG_TXNID``. A non-zero status will prevent the
1037 1037 transaction from being opened.
1038 1038
1039 1039 ``pretxnclose``
1040 1040 Run right before the transaction is actually finalized. Any repository change
1041 1041 will be visible to the hook program. This lets you validate the transaction
1042 1042 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1043 1043 status will cause the transaction to be rolled back. The reason for the
1044 1044 transaction opening will be in ``$HG_TXNNAME``, and a unique identifier for
1045 1045 the transaction will be in ``HG_TXNID``. The rest of the available data will
1046 1046 vary according the transaction type. New changesets will add ``$HG_NODE``
1047 1047 (the ID of the first added changeset), ``$HG_NODE_LAST`` (the ID of the last
1048 1048 added changeset), ``$HG_URL`` and ``$HG_SOURCE`` variables. Bookmark and
1049 1049 phase changes will set ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``
1050 1050 respectively, etc.
1051 1051
1052 1052 ``pretxnclose-bookmark``
1053 1053 Run right before a bookmark change is actually finalized. Any repository
1054 1054 change will be visible to the hook program. This lets you validate the
1055 1055 transaction content or change it. Exit status 0 allows the commit to
1056 1056 proceed. A non-zero status will cause the transaction to be rolled back.
1057 1057 The name of the bookmark will be available in ``$HG_BOOKMARK``, the new
1058 1058 bookmark location will be available in ``$HG_NODE`` while the previous
1059 1059 location will be available in ``$HG_OLDNODE``. In case of a bookmark
1060 1060 creation ``$HG_OLDNODE`` will be empty. In case of deletion ``$HG_NODE``
1061 1061 will be empty.
1062 1062 In addition, the reason for the transaction opening will be in
1063 1063 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1064 1064 ``HG_TXNID``.
1065 1065
1066 1066 ``pretxnclose-phase``
1067 1067 Run right before a phase change is actually finalized. Any repository change
1068 1068 will be visible to the hook program. This lets you validate the transaction
1069 1069 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1070 1070 status will cause the transaction to be rolled back. The hook is called
1071 1071 multiple times, once for each revision affected by a phase change.
1072 1072 The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``
1073 1073 while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``
1074 1074 will be empty. In addition, the reason for the transaction opening will be in
1075 1075 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1076 1076 ``HG_TXNID``. The hook is also run for newly added revisions. In this case
1077 1077 the ``$HG_OLDPHASE`` entry will be empty.
1078 1078
1079 1079 ``txnclose``
1080 1080 Run after any repository transaction has been committed. At this
1081 1081 point, the transaction can no longer be rolled back. The hook will run
1082 1082 after the lock is released. See :hg:`help config.hooks.pretxnclose` for
1083 1083 details about available variables.
1084 1084
1085 1085 ``txnclose-bookmark``
1086 1086 Run after any bookmark change has been committed. At this point, the
1087 1087 transaction can no longer be rolled back. The hook will run after the lock
1088 1088 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1089 1089 about available variables.
1090 1090
1091 1091 ``txnclose-phase``
1092 1092 Run after any phase change has been committed. At this point, the
1093 1093 transaction can no longer be rolled back. The hook will run after the lock
1094 1094 is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
1095 1095 available variables.
1096 1096
1097 1097 ``txnabort``
1098 1098 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
1099 1099 for details about available variables.
1100 1100
1101 1101 ``pretxnchangegroup``
1102 1102 Run after a changegroup has been added via push, pull or unbundle, but before
1103 1103 the transaction has been committed. The changegroup is visible to the hook
1104 1104 program. This allows validation of incoming changes before accepting them.
1105 1105 The ID of the first new changeset is in ``$HG_NODE`` and last is in
1106 1106 ``$HG_NODE_LAST``. Exit status 0 allows the transaction to commit. A non-zero
1107 1107 status will cause the transaction to be rolled back, and the push, pull or
1108 1108 unbundle will fail. The URL that was the source of changes is in ``$HG_URL``.
1109 1109
1110 1110 ``pretxncommit``
1111 1111 Run after a changeset has been created, but before the transaction is
1112 1112 committed. The changeset is visible to the hook program. This allows
1113 1113 validation of the commit message and changes. Exit status 0 allows the
1114 1114 commit to proceed. A non-zero status will cause the transaction to
1115 1115 be rolled back. The ID of the new changeset is in ``$HG_NODE``. The parent
1116 1116 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1117 1117
1118 1118 ``preupdate``
1119 1119 Run before updating the working directory. Exit status 0 allows
1120 1120 the update to proceed. A non-zero status will prevent the update.
1121 1121 The changeset ID of first new parent is in ``$HG_PARENT1``. If updating to a
1122 1122 merge, the ID of second new parent is in ``$HG_PARENT2``.
1123 1123
1124 1124 ``listkeys``
1125 1125 Run after listing pushkeys (like bookmarks) in the repository. The
1126 1126 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1127 1127 dictionary containing the keys and values.
1128 1128
1129 1129 ``pushkey``
1130 1130 Run after a pushkey (like a bookmark) is added to the
1131 1131 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
1132 1132 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
1133 1133 value is in ``$HG_NEW``.
1134 1134
1135 1135 ``tag``
1136 1136 Run after a tag is created. The ID of the tagged changeset is in ``$HG_NODE``.
1137 1137 The name of tag is in ``$HG_TAG``. The tag is local if ``$HG_LOCAL=1``, or in
1138 1138 the repository if ``$HG_LOCAL=0``.
1139 1139
1140 1140 ``update``
1141 1141 Run after updating the working directory. The changeset ID of first
1142 1142 new parent is in ``$HG_PARENT1``. If updating to a merge, the ID of second new
1143 1143 parent is in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
1144 1144 update failed (e.g. because conflicts were not resolved), ``$HG_ERROR=1``.
1145 1145
1146 1146 .. note::
1147 1147
1148 1148 It is generally better to use standard hooks rather than the
1149 1149 generic pre- and post- command hooks, as they are guaranteed to be
1150 1150 called in the appropriate contexts for influencing transactions.
1151 1151 Also, hooks like "commit" will be called in all contexts that
1152 1152 generate a commit (e.g. tag) and not just the commit command.
1153 1153
1154 1154 .. note::
1155 1155
1156 1156 Environment variables with empty values may not be passed to
1157 1157 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1158 1158 will have an empty value under Unix-like platforms for non-merge
1159 1159 changesets, while it will not be available at all under Windows.
1160 1160
1161 1161 The syntax for Python hooks is as follows::
1162 1162
1163 1163 hookname = python:modulename.submodule.callable
1164 1164 hookname = python:/path/to/python/module.py:callable
1165 1165
1166 1166 Python hooks are run within the Mercurial process. Each hook is
1167 1167 called with at least three keyword arguments: a ui object (keyword
1168 1168 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1169 1169 keyword that tells what kind of hook is used. Arguments listed as
1170 1170 environment variables above are passed as keyword arguments, with no
1171 1171 ``HG_`` prefix, and names in lower case.
1172 1172
1173 1173 If a Python hook returns a "true" value or raises an exception, this
1174 1174 is treated as a failure.
1175 1175
1176 1176
1177 1177 ``hostfingerprints``
1178 1178 --------------------
1179 1179
1180 1180 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1181 1181
1182 1182 Fingerprints of the certificates of known HTTPS servers.
1183 1183
1184 1184 A HTTPS connection to a server with a fingerprint configured here will
1185 1185 only succeed if the servers certificate matches the fingerprint.
1186 1186 This is very similar to how ssh known hosts works.
1187 1187
1188 1188 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
1189 1189 Multiple values can be specified (separated by spaces or commas). This can
1190 1190 be used to define both old and new fingerprints while a host transitions
1191 1191 to a new certificate.
1192 1192
1193 1193 The CA chain and web.cacerts is not used for servers with a fingerprint.
1194 1194
1195 1195 For example::
1196 1196
1197 1197 [hostfingerprints]
1198 1198 hg.intevation.de = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1199 1199 hg.intevation.org = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1200 1200
1201 1201 ``hostsecurity``
1202 1202 ----------------
1203 1203
1204 1204 Used to specify global and per-host security settings for connecting to
1205 1205 other machines.
1206 1206
1207 1207 The following options control default behavior for all hosts.
1208 1208
1209 1209 ``ciphers``
1210 1210 Defines the cryptographic ciphers to use for connections.
1211 1211
1212 1212 Value must be a valid OpenSSL Cipher List Format as documented at
1213 1213 https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
1214 1214
1215 1215 This setting is for advanced users only. Setting to incorrect values
1216 1216 can significantly lower connection security or decrease performance.
1217 1217 You have been warned.
1218 1218
1219 1219 This option requires Python 2.7.
1220 1220
1221 1221 ``minimumprotocol``
1222 1222 Defines the minimum channel encryption protocol to use.
1223 1223
1224 1224 By default, the highest version of TLS supported by both client and server
1225 1225 is used.
1226 1226
1227 1227 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1228 1228
1229 1229 When running on an old Python version, only ``tls1.0`` is allowed since
1230 1230 old versions of Python only support up to TLS 1.0.
1231 1231
1232 1232 When running a Python that supports modern TLS versions, the default is
1233 1233 ``tls1.1``. ``tls1.0`` can still be used to allow TLS 1.0. However, this
1234 1234 weakens security and should only be used as a feature of last resort if
1235 1235 a server does not support TLS 1.1+.
1236 1236
1237 1237 Options in the ``[hostsecurity]`` section can have the form
1238 1238 ``hostname``:``setting``. This allows multiple settings to be defined on a
1239 1239 per-host basis.
1240 1240
1241 1241 The following per-host settings can be defined.
1242 1242
1243 1243 ``ciphers``
1244 1244 This behaves like ``ciphers`` as described above except it only applies
1245 1245 to the host on which it is defined.
1246 1246
1247 1247 ``fingerprints``
1248 1248 A list of hashes of the DER encoded peer/remote certificate. Values have
1249 1249 the form ``algorithm``:``fingerprint``. e.g.
1250 1250 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1251 1251 In addition, colons (``:``) can appear in the fingerprint part.
1252 1252
1253 1253 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1254 1254 ``sha512``.
1255 1255
1256 1256 Use of ``sha256`` or ``sha512`` is preferred.
1257 1257
1258 1258 If a fingerprint is specified, the CA chain is not validated for this
1259 1259 host and Mercurial will require the remote certificate to match one
1260 1260 of the fingerprints specified. This means if the server updates its
1261 1261 certificate, Mercurial will abort until a new fingerprint is defined.
1262 1262 This can provide stronger security than traditional CA-based validation
1263 1263 at the expense of convenience.
1264 1264
1265 1265 This option takes precedence over ``verifycertsfile``.
1266 1266
1267 1267 ``minimumprotocol``
1268 1268 This behaves like ``minimumprotocol`` as described above except it
1269 1269 only applies to the host on which it is defined.
1270 1270
1271 1271 ``verifycertsfile``
1272 1272 Path to file a containing a list of PEM encoded certificates used to
1273 1273 verify the server certificate. Environment variables and ``~user``
1274 1274 constructs are expanded in the filename.
1275 1275
1276 1276 The server certificate or the certificate's certificate authority (CA)
1277 1277 must match a certificate from this file or certificate verification
1278 1278 will fail and connections to the server will be refused.
1279 1279
1280 1280 If defined, only certificates provided by this file will be used:
1281 1281 ``web.cacerts`` and any system/default certificates will not be
1282 1282 used.
1283 1283
1284 1284 This option has no effect if the per-host ``fingerprints`` option
1285 1285 is set.
1286 1286
1287 1287 The format of the file is as follows::
1288 1288
1289 1289 -----BEGIN CERTIFICATE-----
1290 1290 ... (certificate in base64 PEM encoding) ...
1291 1291 -----END CERTIFICATE-----
1292 1292 -----BEGIN CERTIFICATE-----
1293 1293 ... (certificate in base64 PEM encoding) ...
1294 1294 -----END CERTIFICATE-----
1295 1295
1296 1296 For example::
1297 1297
1298 1298 [hostsecurity]
1299 1299 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
1300 1300 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
1301 1301 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
1302 1302 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1303 1303
1304 1304 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1305 1305 when connecting to ``hg.example.com``::
1306 1306
1307 1307 [hostsecurity]
1308 1308 minimumprotocol = tls1.2
1309 1309 hg.example.com:minimumprotocol = tls1.1
1310 1310
1311 1311 ``http_proxy``
1312 1312 --------------
1313 1313
1314 1314 Used to access web-based Mercurial repositories through a HTTP
1315 1315 proxy.
1316 1316
1317 1317 ``host``
1318 1318 Host name and (optional) port of the proxy server, for example
1319 1319 "myproxy:8000".
1320 1320
1321 1321 ``no``
1322 1322 Optional. Comma-separated list of host names that should bypass
1323 1323 the proxy.
1324 1324
1325 1325 ``passwd``
1326 1326 Optional. Password to authenticate with at the proxy server.
1327 1327
1328 1328 ``user``
1329 1329 Optional. User name to authenticate with at the proxy server.
1330 1330
1331 1331 ``always``
1332 1332 Optional. Always use the proxy, even for localhost and any entries
1333 1333 in ``http_proxy.no``. (default: False)
1334 1334
1335 1335 ``http``
1336 1336 ----------
1337 1337
1338 1338 Used to configure access to Mercurial repositories via HTTP.
1339 1339
1340 1340 ``timeout``
1341 1341 If set, blocking operations will timeout after that many seconds.
1342 1342 (default: None)
1343 1343
1344 1344 ``merge``
1345 1345 ---------
1346 1346
1347 1347 This section specifies behavior during merges and updates.
1348 1348
1349 1349 ``checkignored``
1350 1350 Controls behavior when an ignored file on disk has the same name as a tracked
1351 1351 file in the changeset being merged or updated to, and has different
1352 1352 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1353 1353 abort on such files. With ``warn``, warn on such files and back them up as
1354 1354 ``.orig``. With ``ignore``, don't print a warning and back them up as
1355 1355 ``.orig``. (default: ``abort``)
1356 1356
1357 1357 ``checkunknown``
1358 1358 Controls behavior when an unknown file that isn't ignored has the same name
1359 1359 as a tracked file in the changeset being merged or updated to, and has
1360 1360 different contents. Similar to ``merge.checkignored``, except for files that
1361 1361 are not ignored. (default: ``abort``)
1362 1362
1363 1363 ``on-failure``
1364 1364 When set to ``continue`` (the default), the merge process attempts to
1365 1365 merge all unresolved files using the merge chosen tool, regardless of
1366 1366 whether previous file merge attempts during the process succeeded or not.
1367 1367 Setting this to ``prompt`` will prompt after any merge failure continue
1368 1368 or halt the merge process. Setting this to ``halt`` will automatically
1369 1369 halt the merge process on any merge tool failure. The merge process
1370 1370 can be restarted by using the ``resolve`` command. When a merge is
1371 1371 halted, the repository is left in a normal ``unresolved`` merge state.
1372 1372 (default: ``continue``)
1373 1373
1374 1374 ``strict-capability-check``
1375 1375 Whether capabilities of internal merge tools are checked strictly
1376 1376 or not, while examining rules to decide merge tool to be used.
1377 1377 (default: False)
1378 1378
1379 1379 ``merge-patterns``
1380 1380 ------------------
1381 1381
1382 1382 This section specifies merge tools to associate with particular file
1383 1383 patterns. Tools matched here will take precedence over the default
1384 1384 merge tool. Patterns are globs by default, rooted at the repository
1385 1385 root.
1386 1386
1387 1387 Example::
1388 1388
1389 1389 [merge-patterns]
1390 1390 **.c = kdiff3
1391 1391 **.jpg = myimgmerge
1392 1392
1393 1393 ``merge-tools``
1394 1394 ---------------
1395 1395
1396 1396 This section configures external merge tools to use for file-level
1397 1397 merges. This section has likely been preconfigured at install time.
1398 1398 Use :hg:`config merge-tools` to check the existing configuration.
1399 1399 Also see :hg:`help merge-tools` for more details.
1400 1400
1401 1401 Example ``~/.hgrc``::
1402 1402
1403 1403 [merge-tools]
1404 1404 # Override stock tool location
1405 1405 kdiff3.executable = ~/bin/kdiff3
1406 1406 # Specify command line
1407 1407 kdiff3.args = $base $local $other -o $output
1408 1408 # Give higher priority
1409 1409 kdiff3.priority = 1
1410 1410
1411 1411 # Changing the priority of preconfigured tool
1412 1412 meld.priority = 0
1413 1413
1414 1414 # Disable a preconfigured tool
1415 1415 vimdiff.disabled = yes
1416 1416
1417 1417 # Define new tool
1418 1418 myHtmlTool.args = -m $local $other $base $output
1419 1419 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1420 1420 myHtmlTool.priority = 1
1421 1421
1422 1422 Supported arguments:
1423 1423
1424 1424 ``priority``
1425 1425 The priority in which to evaluate this tool.
1426 1426 (default: 0)
1427 1427
1428 1428 ``executable``
1429 1429 Either just the name of the executable or its pathname.
1430 1430
1431 1431 .. container:: windows
1432 1432
1433 1433 On Windows, the path can use environment variables with ${ProgramFiles}
1434 1434 syntax.
1435 1435
1436 1436 (default: the tool name)
1437 1437
1438 1438 ``args``
1439 1439 The arguments to pass to the tool executable. You can refer to the
1440 1440 files being merged as well as the output file through these
1441 1441 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1442 1442
1443 1443 The meaning of ``$local`` and ``$other`` can vary depending on which action is
1444 1444 being performed. During an update or merge, ``$local`` represents the original
1445 1445 state of the file, while ``$other`` represents the commit you are updating to or
1446 1446 the commit you are merging with. During a rebase, ``$local`` represents the
1447 1447 destination of the rebase, and ``$other`` represents the commit being rebased.
1448 1448
1449 1449 Some operations define custom labels to assist with identifying the revisions,
1450 1450 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1451 1451 labels are not available, these will be ``local``, ``other``, and ``base``,
1452 1452 respectively.
1453 1453 (default: ``$local $base $other``)
1454 1454
1455 1455 ``premerge``
1456 1456 Attempt to run internal non-interactive 3-way merge tool before
1457 1457 launching external tool. Options are ``true``, ``false``, ``keep`` or
1458 1458 ``keep-merge3``. The ``keep`` option will leave markers in the file if the
1459 1459 premerge fails. The ``keep-merge3`` will do the same but include information
1460 1460 about the base of the merge in the marker (see internal :merge3 in
1461 1461 :hg:`help merge-tools`).
1462 1462 (default: True)
1463 1463
1464 1464 ``binary``
1465 1465 This tool can merge binary files. (default: False, unless tool
1466 1466 was selected by file pattern match)
1467 1467
1468 1468 ``symlink``
1469 1469 This tool can merge symlinks. (default: False)
1470 1470
1471 1471 ``check``
1472 1472 A list of merge success-checking options:
1473 1473
1474 1474 ``changed``
1475 1475 Ask whether merge was successful when the merged file shows no changes.
1476 1476 ``conflicts``
1477 1477 Check whether there are conflicts even though the tool reported success.
1478 1478 ``prompt``
1479 1479 Always prompt for merge success, regardless of success reported by tool.
1480 1480
1481 1481 ``fixeol``
1482 1482 Attempt to fix up EOL changes caused by the merge tool.
1483 1483 (default: False)
1484 1484
1485 1485 ``gui``
1486 1486 This tool requires a graphical interface to run. (default: False)
1487 1487
1488 1488 ``mergemarkers``
1489 1489 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1490 1490 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1491 1491 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1492 1492 markers generated during premerge will be ``detailed`` if either this option or
1493 1493 the corresponding option in the ``[ui]`` section is ``detailed``.
1494 1494 (default: ``basic``)
1495 1495
1496 1496 ``mergemarkertemplate``
1497 1497 This setting can be used to override ``mergemarkertemplate`` from the ``[ui]``
1498 1498 section on a per-tool basis; this applies to the ``$label``-prefixed variables
1499 1499 and to the conflict markers that are generated if ``premerge`` is ``keep` or
1500 1500 ``keep-merge3``. See the corresponding variable in ``[ui]`` for more
1501 1501 information.
1502 1502
1503 1503 .. container:: windows
1504 1504
1505 1505 ``regkey``
1506 1506 Windows registry key which describes install location of this
1507 1507 tool. Mercurial will search for this key first under
1508 1508 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1509 1509 (default: None)
1510 1510
1511 1511 ``regkeyalt``
1512 1512 An alternate Windows registry key to try if the first key is not
1513 1513 found. The alternate key uses the same ``regname`` and ``regappend``
1514 1514 semantics of the primary key. The most common use for this key
1515 1515 is to search for 32bit applications on 64bit operating systems.
1516 1516 (default: None)
1517 1517
1518 1518 ``regname``
1519 1519 Name of value to read from specified registry key.
1520 1520 (default: the unnamed (default) value)
1521 1521
1522 1522 ``regappend``
1523 1523 String to append to the value read from the registry, typically
1524 1524 the executable name of the tool.
1525 1525 (default: None)
1526 1526
1527 1527 ``pager``
1528 1528 ---------
1529 1529
1530 1530 Setting used to control when to paginate and with what external tool. See
1531 1531 :hg:`help pager` for details.
1532 1532
1533 1533 ``pager``
1534 1534 Define the external tool used as pager.
1535 1535
1536 1536 If no pager is set, Mercurial uses the environment variable $PAGER.
1537 1537 If neither pager.pager, nor $PAGER is set, a default pager will be
1538 1538 used, typically `less` on Unix and `more` on Windows. Example::
1539 1539
1540 1540 [pager]
1541 1541 pager = less -FRX
1542 1542
1543 1543 ``ignore``
1544 1544 List of commands to disable the pager for. Example::
1545 1545
1546 1546 [pager]
1547 1547 ignore = version, help, update
1548 1548
1549 1549 ``patch``
1550 1550 ---------
1551 1551
1552 1552 Settings used when applying patches, for instance through the 'import'
1553 1553 command or with Mercurial Queues extension.
1554 1554
1555 1555 ``eol``
1556 1556 When set to 'strict' patch content and patched files end of lines
1557 1557 are preserved. When set to ``lf`` or ``crlf``, both files end of
1558 1558 lines are ignored when patching and the result line endings are
1559 1559 normalized to either LF (Unix) or CRLF (Windows). When set to
1560 1560 ``auto``, end of lines are again ignored while patching but line
1561 1561 endings in patched files are normalized to their original setting
1562 1562 on a per-file basis. If target file does not exist or has no end
1563 1563 of line, patch line endings are preserved.
1564 1564 (default: strict)
1565 1565
1566 1566 ``fuzz``
1567 1567 The number of lines of 'fuzz' to allow when applying patches. This
1568 1568 controls how much context the patcher is allowed to ignore when
1569 1569 trying to apply a patch.
1570 1570 (default: 2)
1571 1571
1572 1572 ``paths``
1573 1573 ---------
1574 1574
1575 1575 Assigns symbolic names and behavior to repositories.
1576 1576
1577 1577 Options are symbolic names defining the URL or directory that is the
1578 1578 location of the repository. Example::
1579 1579
1580 1580 [paths]
1581 1581 my_server = https://example.com/my_repo
1582 1582 local_path = /home/me/repo
1583 1583
1584 1584 These symbolic names can be used from the command line. To pull
1585 1585 from ``my_server``: :hg:`pull my_server`. To push to ``local_path``:
1586 1586 :hg:`push local_path`.
1587 1587
1588 1588 Options containing colons (``:``) denote sub-options that can influence
1589 1589 behavior for that specific path. Example::
1590 1590
1591 1591 [paths]
1592 1592 my_server = https://example.com/my_path
1593 1593 my_server:pushurl = ssh://example.com/my_path
1594 1594
1595 1595 The following sub-options can be defined:
1596 1596
1597 1597 ``pushurl``
1598 1598 The URL to use for push operations. If not defined, the location
1599 1599 defined by the path's main entry is used.
1600 1600
1601 1601 ``pushrev``
1602 1602 A revset defining which revisions to push by default.
1603 1603
1604 1604 When :hg:`push` is executed without a ``-r`` argument, the revset
1605 1605 defined by this sub-option is evaluated to determine what to push.
1606 1606
1607 1607 For example, a value of ``.`` will push the working directory's
1608 1608 revision by default.
1609 1609
1610 1610 Revsets specifying bookmarks will not result in the bookmark being
1611 1611 pushed.
1612 1612
1613 1613 The following special named paths exist:
1614 1614
1615 1615 ``default``
1616 1616 The URL or directory to use when no source or remote is specified.
1617 1617
1618 1618 :hg:`clone` will automatically define this path to the location the
1619 1619 repository was cloned from.
1620 1620
1621 1621 ``default-push``
1622 1622 (deprecated) The URL or directory for the default :hg:`push` location.
1623 1623 ``default:pushurl`` should be used instead.
1624 1624
1625 1625 ``phases``
1626 1626 ----------
1627 1627
1628 1628 Specifies default handling of phases. See :hg:`help phases` for more
1629 1629 information about working with phases.
1630 1630
1631 1631 ``publish``
1632 1632 Controls draft phase behavior when working as a server. When true,
1633 1633 pushed changesets are set to public in both client and server and
1634 1634 pulled or cloned changesets are set to public in the client.
1635 1635 (default: True)
1636 1636
1637 1637 ``new-commit``
1638 1638 Phase of newly-created commits.
1639 1639 (default: draft)
1640 1640
1641 1641 ``checksubrepos``
1642 1642 Check the phase of the current revision of each subrepository. Allowed
1643 1643 values are "ignore", "follow" and "abort". For settings other than
1644 1644 "ignore", the phase of the current revision of each subrepository is
1645 1645 checked before committing the parent repository. If any of those phases is
1646 1646 greater than the phase of the parent repository (e.g. if a subrepo is in a
1647 1647 "secret" phase while the parent repo is in "draft" phase), the commit is
1648 1648 either aborted (if checksubrepos is set to "abort") or the higher phase is
1649 1649 used for the parent repository commit (if set to "follow").
1650 1650 (default: follow)
1651 1651
1652 1652
1653 1653 ``profiling``
1654 1654 -------------
1655 1655
1656 1656 Specifies profiling type, format, and file output. Two profilers are
1657 1657 supported: an instrumenting profiler (named ``ls``), and a sampling
1658 1658 profiler (named ``stat``).
1659 1659
1660 1660 In this section description, 'profiling data' stands for the raw data
1661 1661 collected during profiling, while 'profiling report' stands for a
1662 1662 statistical text report generated from the profiling data.
1663 1663
1664 1664 ``enabled``
1665 1665 Enable the profiler.
1666 1666 (default: false)
1667 1667
1668 1668 This is equivalent to passing ``--profile`` on the command line.
1669 1669
1670 1670 ``type``
1671 1671 The type of profiler to use.
1672 1672 (default: stat)
1673 1673
1674 1674 ``ls``
1675 1675 Use Python's built-in instrumenting profiler. This profiler
1676 1676 works on all platforms, but each line number it reports is the
1677 1677 first line of a function. This restriction makes it difficult to
1678 1678 identify the expensive parts of a non-trivial function.
1679 1679 ``stat``
1680 1680 Use a statistical profiler, statprof. This profiler is most
1681 1681 useful for profiling commands that run for longer than about 0.1
1682 1682 seconds.
1683 1683
1684 1684 ``format``
1685 1685 Profiling format. Specific to the ``ls`` instrumenting profiler.
1686 1686 (default: text)
1687 1687
1688 1688 ``text``
1689 1689 Generate a profiling report. When saving to a file, it should be
1690 1690 noted that only the report is saved, and the profiling data is
1691 1691 not kept.
1692 1692 ``kcachegrind``
1693 1693 Format profiling data for kcachegrind use: when saving to a
1694 1694 file, the generated file can directly be loaded into
1695 1695 kcachegrind.
1696 1696
1697 1697 ``statformat``
1698 1698 Profiling format for the ``stat`` profiler.
1699 1699 (default: hotpath)
1700 1700
1701 1701 ``hotpath``
1702 1702 Show a tree-based display containing the hot path of execution (where
1703 1703 most time was spent).
1704 1704 ``bymethod``
1705 1705 Show a table of methods ordered by how frequently they are active.
1706 1706 ``byline``
1707 1707 Show a table of lines in files ordered by how frequently they are active.
1708 1708 ``json``
1709 1709 Render profiling data as JSON.
1710 1710
1711 1711 ``frequency``
1712 1712 Sampling frequency. Specific to the ``stat`` sampling profiler.
1713 1713 (default: 1000)
1714 1714
1715 1715 ``output``
1716 1716 File path where profiling data or report should be saved. If the
1717 1717 file exists, it is replaced. (default: None, data is printed on
1718 1718 stderr)
1719 1719
1720 1720 ``sort``
1721 1721 Sort field. Specific to the ``ls`` instrumenting profiler.
1722 1722 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1723 1723 ``inlinetime``.
1724 1724 (default: inlinetime)
1725 1725
1726 1726 ``time-track``
1727 1727 Control if the stat profiler track ``cpu`` or ``real`` time.
1728 1728 (default: ``cpu`` on Windows, otherwise ``real``)
1729 1729
1730 1730 ``limit``
1731 1731 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1732 1732 (default: 30)
1733 1733
1734 1734 ``nested``
1735 1735 Show at most this number of lines of drill-down info after each main entry.
1736 1736 This can help explain the difference between Total and Inline.
1737 1737 Specific to the ``ls`` instrumenting profiler.
1738 1738 (default: 0)
1739 1739
1740 1740 ``showmin``
1741 1741 Minimum fraction of samples an entry must have for it to be displayed.
1742 1742 Can be specified as a float between ``0.0`` and ``1.0`` or can have a
1743 1743 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
1744 1744
1745 1745 Only used by the ``stat`` profiler.
1746 1746
1747 1747 For the ``hotpath`` format, default is ``0.05``.
1748 1748 For the ``chrome`` format, default is ``0.005``.
1749 1749
1750 1750 The option is unused on other formats.
1751 1751
1752 1752 ``showmax``
1753 1753 Maximum fraction of samples an entry can have before it is ignored in
1754 1754 display. Values format is the same as ``showmin``.
1755 1755
1756 1756 Only used by the ``stat`` profiler.
1757 1757
1758 1758 For the ``chrome`` format, default is ``0.999``.
1759 1759
1760 1760 The option is unused on other formats.
1761 1761
1762 1762 ``progress``
1763 1763 ------------
1764 1764
1765 1765 Mercurial commands can draw progress bars that are as informative as
1766 1766 possible. Some progress bars only offer indeterminate information, while others
1767 1767 have a definite end point.
1768 1768
1769 1769 ``debug``
1770 1770 Whether to print debug info when updating the progress bar. (default: False)
1771 1771
1772 1772 ``delay``
1773 1773 Number of seconds (float) before showing the progress bar. (default: 3)
1774 1774
1775 1775 ``changedelay``
1776 1776 Minimum delay before showing a new topic. When set to less than 3 * refresh,
1777 1777 that value will be used instead. (default: 1)
1778 1778
1779 1779 ``estimateinterval``
1780 1780 Maximum sampling interval in seconds for speed and estimated time
1781 1781 calculation. (default: 60)
1782 1782
1783 1783 ``refresh``
1784 1784 Time in seconds between refreshes of the progress bar. (default: 0.1)
1785 1785
1786 1786 ``format``
1787 1787 Format of the progress bar.
1788 1788
1789 1789 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1790 1790 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1791 1791 last 20 characters of the item, but this can be changed by adding either
1792 1792 ``-<num>`` which would take the last num characters, or ``+<num>`` for the
1793 1793 first num characters.
1794 1794
1795 1795 (default: topic bar number estimate)
1796 1796
1797 1797 ``width``
1798 1798 If set, the maximum width of the progress information (that is, min(width,
1799 1799 term width) will be used).
1800 1800
1801 1801 ``clear-complete``
1802 1802 Clear the progress bar after it's done. (default: True)
1803 1803
1804 1804 ``disable``
1805 1805 If true, don't show a progress bar.
1806 1806
1807 1807 ``assume-tty``
1808 1808 If true, ALWAYS show a progress bar, unless disable is given.
1809 1809
1810 1810 ``rebase``
1811 1811 ----------
1812 1812
1813 1813 ``evolution.allowdivergence``
1814 1814 Default to False, when True allow creating divergence when performing
1815 1815 rebase of obsolete changesets.
1816 1816
1817 1817 ``revsetalias``
1818 1818 ---------------
1819 1819
1820 1820 Alias definitions for revsets. See :hg:`help revsets` for details.
1821 1821
1822 1822 ``rewrite``
1823 1823 -----------
1824 1824
1825 1825 ``backup-bundle``
1826 1826 Whether to save stripped changesets to a bundle file. (default: True)
1827 1827
1828 1828 ``update-timestamp``
1829 1829 If true, updates the date and time of the changeset to current. It is only
1830 1830 applicable for hg amend in current version.
1831 1831
1832 1832 ``storage``
1833 1833 -----------
1834 1834
1835 1835 Control the strategy Mercurial uses internally to store history. Options in this
1836 1836 category impact performance and repository size.
1837 1837
1838 1838 ``revlog.optimize-delta-parent-choice``
1839 1839 When storing a merge revision, both parents will be equally considered as
1840 1840 a possible delta base. This results in better delta selection and improved
1841 1841 revlog compression. This option is enabled by default.
1842 1842
1843 1843 Turning this option off can result in large increase of repository size for
1844 1844 repository with many merges.
1845 1845
1846 1846 ``revlog.reuse-external-delta-parent``
1847 1847 Control the order in which delta parents are considered when adding new
1848 1848 revisions from an external source.
1849 1849 (typically: apply bundle from `hg pull` or `hg push`).
1850 1850
1851 1851 New revisions are usually provided as a delta against other revisions. By
1852 1852 default, Mercurial will try to reuse this delta first, therefore using the
1853 1853 same "delta parent" as the source. Directly using delta's from the source
1854 1854 reduces CPU usage and usually speeds up operation. However, in some case,
1855 1855 the source might have sub-optimal delta bases and forcing their reevaluation
1856 1856 is useful. For example, pushes from an old client could have sub-optimal
1857 1857 delta's parent that the server want to optimize. (lack of general delta, bad
1858 1858 parents, choice, lack of sparse-revlog, etc).
1859 1859
1860 1860 This option is enabled by default. Turning it off will ensure bad delta
1861 1861 parent choices from older client do not propagate to this repository, at
1862 1862 the cost of a small increase in CPU consumption.
1863 1863
1864 1864 Note: this option only control the order in which delta parents are
1865 1865 considered. Even when disabled, the existing delta from the source will be
1866 1866 reused if the same delta parent is selected.
1867 1867
1868 1868 ``revlog.reuse-external-delta``
1869 1869 Control the reuse of delta from external source.
1870 1870 (typically: apply bundle from `hg pull` or `hg push`).
1871 1871
1872 1872 New revisions are usually provided as a delta against another revision. By
1873 1873 default, Mercurial will not recompute the same delta again, trusting
1874 1874 externally provided deltas. There have been rare cases of small adjustment
1875 1875 to the diffing algorithm in the past. So in some rare case, recomputing
1876 1876 delta provided by ancient clients can provides better results. Disabling
1877 1877 this option means going through a full delta recomputation for all incoming
1878 1878 revisions. It means a large increase in CPU usage and will slow operations
1879 1879 down.
1880 1880
1881 1881 This option is enabled by default. When disabled, it also disables the
1882 1882 related ``storage.revlog.reuse-external-delta-parent`` option.
1883 1883
1884 1884 ``server``
1885 1885 ----------
1886 1886
1887 1887 Controls generic server settings.
1888 1888
1889 1889 ``bookmarks-pushkey-compat``
1890 1890 Trigger pushkey hook when being pushed bookmark updates. This config exist
1891 1891 for compatibility purpose (default to True)
1892 1892
1893 1893 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
1894 1894 movement we recommend you migrate them to ``txnclose-bookmark`` and
1895 1895 ``pretxnclose-bookmark``.
1896 1896
1897 1897 ``compressionengines``
1898 1898 List of compression engines and their relative priority to advertise
1899 1899 to clients.
1900 1900
1901 1901 The order of compression engines determines their priority, the first
1902 1902 having the highest priority. If a compression engine is not listed
1903 1903 here, it won't be advertised to clients.
1904 1904
1905 1905 If not set (the default), built-in defaults are used. Run
1906 1906 :hg:`debuginstall` to list available compression engines and their
1907 1907 default wire protocol priority.
1908 1908
1909 1909 Older Mercurial clients only support zlib compression and this setting
1910 1910 has no effect for legacy clients.
1911 1911
1912 1912 ``uncompressed``
1913 1913 Whether to allow clients to clone a repository using the
1914 1914 uncompressed streaming protocol. This transfers about 40% more
1915 1915 data than a regular clone, but uses less memory and CPU on both
1916 1916 server and client. Over a LAN (100 Mbps or better) or a very fast
1917 1917 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
1918 1918 regular clone. Over most WAN connections (anything slower than
1919 1919 about 6 Mbps), uncompressed streaming is slower, because of the
1920 1920 extra data transfer overhead. This mode will also temporarily hold
1921 1921 the write lock while determining what data to transfer.
1922 1922 (default: True)
1923 1923
1924 1924 ``uncompressedallowsecret``
1925 1925 Whether to allow stream clones when the repository contains secret
1926 1926 changesets. (default: False)
1927 1927
1928 1928 ``preferuncompressed``
1929 1929 When set, clients will try to use the uncompressed streaming
1930 1930 protocol. (default: False)
1931 1931
1932 1932 ``disablefullbundle``
1933 1933 When set, servers will refuse attempts to do pull-based clones.
1934 1934 If this option is set, ``preferuncompressed`` and/or clone bundles
1935 1935 are highly recommended. Partial clones will still be allowed.
1936 1936 (default: False)
1937 1937
1938 1938 ``streamunbundle``
1939 1939 When set, servers will apply data sent from the client directly,
1940 1940 otherwise it will be written to a temporary file first. This option
1941 1941 effectively prevents concurrent pushes.
1942 1942
1943 1943 ``pullbundle``
1944 1944 When set, the server will check pullbundle.manifest for bundles
1945 1945 covering the requested heads and common nodes. The first matching
1946 1946 entry will be streamed to the client.
1947 1947
1948 1948 For HTTP transport, the stream will still use zlib compression
1949 1949 for older clients.
1950 1950
1951 1951 ``concurrent-push-mode``
1952 1952 Level of allowed race condition between two pushing clients.
1953 1953
1954 1954 - 'strict': push is abort if another client touched the repository
1955 1955 while the push was preparing. (default)
1956 1956 - 'check-related': push is only aborted if it affects head that got also
1957 1957 affected while the push was preparing.
1958 1958
1959 1959 This requires compatible client (version 4.3 and later). Old client will
1960 1960 use 'strict'.
1961 1961
1962 1962 ``validate``
1963 1963 Whether to validate the completeness of pushed changesets by
1964 1964 checking that all new file revisions specified in manifests are
1965 1965 present. (default: False)
1966 1966
1967 1967 ``maxhttpheaderlen``
1968 1968 Instruct HTTP clients not to send request headers longer than this
1969 1969 many bytes. (default: 1024)
1970 1970
1971 1971 ``bundle1``
1972 1972 Whether to allow clients to push and pull using the legacy bundle1
1973 1973 exchange format. (default: True)
1974 1974
1975 1975 ``bundle1gd``
1976 1976 Like ``bundle1`` but only used if the repository is using the
1977 1977 *generaldelta* storage format. (default: True)
1978 1978
1979 1979 ``bundle1.push``
1980 1980 Whether to allow clients to push using the legacy bundle1 exchange
1981 1981 format. (default: True)
1982 1982
1983 1983 ``bundle1gd.push``
1984 1984 Like ``bundle1.push`` but only used if the repository is using the
1985 1985 *generaldelta* storage format. (default: True)
1986 1986
1987 1987 ``bundle1.pull``
1988 1988 Whether to allow clients to pull using the legacy bundle1 exchange
1989 1989 format. (default: True)
1990 1990
1991 1991 ``bundle1gd.pull``
1992 1992 Like ``bundle1.pull`` but only used if the repository is using the
1993 1993 *generaldelta* storage format. (default: True)
1994 1994
1995 1995 Large repositories using the *generaldelta* storage format should
1996 1996 consider setting this option because converting *generaldelta*
1997 1997 repositories to the exchange format required by the bundle1 data
1998 1998 format can consume a lot of CPU.
1999 1999
2000 2000 ``bundle2.stream``
2001 2001 Whether to allow clients to pull using the bundle2 streaming protocol.
2002 2002 (default: True)
2003 2003
2004 2004 ``zliblevel``
2005 2005 Integer between ``-1`` and ``9`` that controls the zlib compression level
2006 2006 for wire protocol commands that send zlib compressed output (notably the
2007 2007 commands that send repository history data).
2008 2008
2009 2009 The default (``-1``) uses the default zlib compression level, which is
2010 2010 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2011 2011 maximum compression.
2012 2012
2013 2013 Setting this option allows server operators to make trade-offs between
2014 2014 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2015 2015 but sends more bytes to clients.
2016 2016
2017 2017 This option only impacts the HTTP server.
2018 2018
2019 2019 ``zstdlevel``
2020 2020 Integer between ``1`` and ``22`` that controls the zstd compression level
2021 2021 for wire protocol commands. ``1`` is the minimal amount of compression and
2022 2022 ``22`` is the highest amount of compression.
2023 2023
2024 2024 The default (``3``) should be significantly faster than zlib while likely
2025 2025 delivering better compression ratios.
2026 2026
2027 2027 This option only impacts the HTTP server.
2028 2028
2029 2029 See also ``server.zliblevel``.
2030 2030
2031 ``view``
2032 Repository filter used when exchanging revisions with the peer.
2033
2034 The default view (``served``) excludes secret and hidden changesets.
2035 Another useful value is ``immutable`` (no draft, secret or hidden changesets).
2036
2031 2037 ``smtp``
2032 2038 --------
2033 2039
2034 2040 Configuration for extensions that need to send email messages.
2035 2041
2036 2042 ``host``
2037 2043 Host name of mail server, e.g. "mail.example.com".
2038 2044
2039 2045 ``port``
2040 2046 Optional. Port to connect to on mail server. (default: 465 if
2041 2047 ``tls`` is smtps; 25 otherwise)
2042 2048
2043 2049 ``tls``
2044 2050 Optional. Method to enable TLS when connecting to mail server: starttls,
2045 2051 smtps or none. (default: none)
2046 2052
2047 2053 ``username``
2048 2054 Optional. User name for authenticating with the SMTP server.
2049 2055 (default: None)
2050 2056
2051 2057 ``password``
2052 2058 Optional. Password for authenticating with the SMTP server. If not
2053 2059 specified, interactive sessions will prompt the user for a
2054 2060 password; non-interactive sessions will fail. (default: None)
2055 2061
2056 2062 ``local_hostname``
2057 2063 Optional. The hostname that the sender can use to identify
2058 2064 itself to the MTA.
2059 2065
2060 2066
2061 2067 ``subpaths``
2062 2068 ------------
2063 2069
2064 2070 Subrepository source URLs can go stale if a remote server changes name
2065 2071 or becomes temporarily unavailable. This section lets you define
2066 2072 rewrite rules of the form::
2067 2073
2068 2074 <pattern> = <replacement>
2069 2075
2070 2076 where ``pattern`` is a regular expression matching a subrepository
2071 2077 source URL and ``replacement`` is the replacement string used to
2072 2078 rewrite it. Groups can be matched in ``pattern`` and referenced in
2073 2079 ``replacements``. For instance::
2074 2080
2075 2081 http://server/(.*)-hg/ = http://hg.server/\1/
2076 2082
2077 2083 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2078 2084
2079 2085 Relative subrepository paths are first made absolute, and the
2080 2086 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2081 2087 doesn't match the full path, an attempt is made to apply it on the
2082 2088 relative path alone. The rules are applied in definition order.
2083 2089
2084 2090 ``subrepos``
2085 2091 ------------
2086 2092
2087 2093 This section contains options that control the behavior of the
2088 2094 subrepositories feature. See also :hg:`help subrepos`.
2089 2095
2090 2096 Security note: auditing in Mercurial is known to be insufficient to
2091 2097 prevent clone-time code execution with carefully constructed Git
2092 2098 subrepos. It is unknown if a similar detect is present in Subversion
2093 2099 subrepos. Both Git and Subversion subrepos are disabled by default
2094 2100 out of security concerns. These subrepo types can be enabled using
2095 2101 the respective options below.
2096 2102
2097 2103 ``allowed``
2098 2104 Whether subrepositories are allowed in the working directory.
2099 2105
2100 2106 When false, commands involving subrepositories (like :hg:`update`)
2101 2107 will fail for all subrepository types.
2102 2108 (default: true)
2103 2109
2104 2110 ``hg:allowed``
2105 2111 Whether Mercurial subrepositories are allowed in the working
2106 2112 directory. This option only has an effect if ``subrepos.allowed``
2107 2113 is true.
2108 2114 (default: true)
2109 2115
2110 2116 ``git:allowed``
2111 2117 Whether Git subrepositories are allowed in the working directory.
2112 2118 This option only has an effect if ``subrepos.allowed`` is true.
2113 2119
2114 2120 See the security note above before enabling Git subrepos.
2115 2121 (default: false)
2116 2122
2117 2123 ``svn:allowed``
2118 2124 Whether Subversion subrepositories are allowed in the working
2119 2125 directory. This option only has an effect if ``subrepos.allowed``
2120 2126 is true.
2121 2127
2122 2128 See the security note above before enabling Subversion subrepos.
2123 2129 (default: false)
2124 2130
2125 2131 ``templatealias``
2126 2132 -----------------
2127 2133
2128 2134 Alias definitions for templates. See :hg:`help templates` for details.
2129 2135
2130 2136 ``templates``
2131 2137 -------------
2132 2138
2133 2139 Use the ``[templates]`` section to define template strings.
2134 2140 See :hg:`help templates` for details.
2135 2141
2136 2142 ``trusted``
2137 2143 -----------
2138 2144
2139 2145 Mercurial will not use the settings in the
2140 2146 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2141 2147 user or to a trusted group, as various hgrc features allow arbitrary
2142 2148 commands to be run. This issue is often encountered when configuring
2143 2149 hooks or extensions for shared repositories or servers. However,
2144 2150 the web interface will use some safe settings from the ``[web]``
2145 2151 section.
2146 2152
2147 2153 This section specifies what users and groups are trusted. The
2148 2154 current user is always trusted. To trust everybody, list a user or a
2149 2155 group with name ``*``. These settings must be placed in an
2150 2156 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2151 2157 user or service running Mercurial.
2152 2158
2153 2159 ``users``
2154 2160 Comma-separated list of trusted users.
2155 2161
2156 2162 ``groups``
2157 2163 Comma-separated list of trusted groups.
2158 2164
2159 2165
2160 2166 ``ui``
2161 2167 ------
2162 2168
2163 2169 User interface controls.
2164 2170
2165 2171 ``archivemeta``
2166 2172 Whether to include the .hg_archival.txt file containing meta data
2167 2173 (hashes for the repository base and for tip) in archives created
2168 2174 by the :hg:`archive` command or downloaded via hgweb.
2169 2175 (default: True)
2170 2176
2171 2177 ``askusername``
2172 2178 Whether to prompt for a username when committing. If True, and
2173 2179 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2174 2180 be prompted to enter a username. If no username is entered, the
2175 2181 default ``USER@HOST`` is used instead.
2176 2182 (default: False)
2177 2183
2178 2184 ``clonebundles``
2179 2185 Whether the "clone bundles" feature is enabled.
2180 2186
2181 2187 When enabled, :hg:`clone` may download and apply a server-advertised
2182 2188 bundle file from a URL instead of using the normal exchange mechanism.
2183 2189
2184 2190 This can likely result in faster and more reliable clones.
2185 2191
2186 2192 (default: True)
2187 2193
2188 2194 ``clonebundlefallback``
2189 2195 Whether failure to apply an advertised "clone bundle" from a server
2190 2196 should result in fallback to a regular clone.
2191 2197
2192 2198 This is disabled by default because servers advertising "clone
2193 2199 bundles" often do so to reduce server load. If advertised bundles
2194 2200 start mass failing and clients automatically fall back to a regular
2195 2201 clone, this would add significant and unexpected load to the server
2196 2202 since the server is expecting clone operations to be offloaded to
2197 2203 pre-generated bundles. Failing fast (the default behavior) ensures
2198 2204 clients don't overwhelm the server when "clone bundle" application
2199 2205 fails.
2200 2206
2201 2207 (default: False)
2202 2208
2203 2209 ``clonebundleprefers``
2204 2210 Defines preferences for which "clone bundles" to use.
2205 2211
2206 2212 Servers advertising "clone bundles" may advertise multiple available
2207 2213 bundles. Each bundle may have different attributes, such as the bundle
2208 2214 type and compression format. This option is used to prefer a particular
2209 2215 bundle over another.
2210 2216
2211 2217 The following keys are defined by Mercurial:
2212 2218
2213 2219 BUNDLESPEC
2214 2220 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2215 2221 e.g. ``gzip-v2`` or ``bzip2-v1``.
2216 2222
2217 2223 COMPRESSION
2218 2224 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2219 2225
2220 2226 Server operators may define custom keys.
2221 2227
2222 2228 Example values: ``COMPRESSION=bzip2``,
2223 2229 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2224 2230
2225 2231 By default, the first bundle advertised by the server is used.
2226 2232
2227 2233 ``color``
2228 2234 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2229 2235 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2230 2236 seems possible. See :hg:`help color` for details.
2231 2237
2232 2238 ``commitsubrepos``
2233 2239 Whether to commit modified subrepositories when committing the
2234 2240 parent repository. If False and one subrepository has uncommitted
2235 2241 changes, abort the commit.
2236 2242 (default: False)
2237 2243
2238 2244 ``debug``
2239 2245 Print debugging information. (default: False)
2240 2246
2241 2247 ``editor``
2242 2248 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2243 2249
2244 2250 ``fallbackencoding``
2245 2251 Encoding to try if it's not possible to decode the changelog using
2246 2252 UTF-8. (default: ISO-8859-1)
2247 2253
2248 2254 ``graphnodetemplate``
2249 2255 The template used to print changeset nodes in an ASCII revision graph.
2250 2256 (default: ``{graphnode}``)
2251 2257
2252 2258 ``ignore``
2253 2259 A file to read per-user ignore patterns from. This file should be
2254 2260 in the same format as a repository-wide .hgignore file. Filenames
2255 2261 are relative to the repository root. This option supports hook syntax,
2256 2262 so if you want to specify multiple ignore files, you can do so by
2257 2263 setting something like ``ignore.other = ~/.hgignore2``. For details
2258 2264 of the ignore file format, see the ``hgignore(5)`` man page.
2259 2265
2260 2266 ``interactive``
2261 2267 Allow to prompt the user. (default: True)
2262 2268
2263 2269 ``interface``
2264 2270 Select the default interface for interactive features (default: text).
2265 2271 Possible values are 'text' and 'curses'.
2266 2272
2267 2273 ``interface.chunkselector``
2268 2274 Select the interface for change recording (e.g. :hg:`commit -i`).
2269 2275 Possible values are 'text' and 'curses'.
2270 2276 This config overrides the interface specified by ui.interface.
2271 2277
2272 2278 ``large-file-limit``
2273 2279 Largest file size that gives no memory use warning.
2274 2280 Possible values are integers or 0 to disable the check.
2275 2281 (default: 10000000)
2276 2282
2277 2283 ``logtemplate``
2278 2284 Template string for commands that print changesets.
2279 2285
2280 2286 ``merge``
2281 2287 The conflict resolution program to use during a manual merge.
2282 2288 For more information on merge tools see :hg:`help merge-tools`.
2283 2289 For configuring merge tools see the ``[merge-tools]`` section.
2284 2290
2285 2291 ``mergemarkers``
2286 2292 Sets the merge conflict marker label styling. The ``detailed``
2287 2293 style uses the ``mergemarkertemplate`` setting to style the labels.
2288 2294 The ``basic`` style just uses 'local' and 'other' as the marker label.
2289 2295 One of ``basic`` or ``detailed``.
2290 2296 (default: ``basic``)
2291 2297
2292 2298 ``mergemarkertemplate``
2293 2299 The template used to print the commit description next to each conflict
2294 2300 marker during merge conflicts. See :hg:`help templates` for the template
2295 2301 format.
2296 2302
2297 2303 Defaults to showing the hash, tags, branches, bookmarks, author, and
2298 2304 the first line of the commit description.
2299 2305
2300 2306 If you use non-ASCII characters in names for tags, branches, bookmarks,
2301 2307 authors, and/or commit descriptions, you must pay attention to encodings of
2302 2308 managed files. At template expansion, non-ASCII characters use the encoding
2303 2309 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2304 2310 environment variables that govern your locale. If the encoding of the merge
2305 2311 markers is different from the encoding of the merged files,
2306 2312 serious problems may occur.
2307 2313
2308 2314 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2309 2315
2310 2316 ``message-output``
2311 2317 Where to write status and error messages. (default: ``stdio``)
2312 2318
2313 2319 ``stderr``
2314 2320 Everything to stderr.
2315 2321 ``stdio``
2316 2322 Status to stdout, and error to stderr.
2317 2323
2318 2324 ``origbackuppath``
2319 2325 The path to a directory used to store generated .orig files. If the path is
2320 2326 not a directory, one will be created. If set, files stored in this
2321 2327 directory have the same name as the original file and do not have a .orig
2322 2328 suffix.
2323 2329
2324 2330 ``paginate``
2325 2331 Control the pagination of command output (default: True). See :hg:`help pager`
2326 2332 for details.
2327 2333
2328 2334 ``patch``
2329 2335 An optional external tool that ``hg import`` and some extensions
2330 2336 will use for applying patches. By default Mercurial uses an
2331 2337 internal patch utility. The external tool must work as the common
2332 2338 Unix ``patch`` program. In particular, it must accept a ``-p``
2333 2339 argument to strip patch headers, a ``-d`` argument to specify the
2334 2340 current directory, a file name to patch, and a patch file to take
2335 2341 from stdin.
2336 2342
2337 2343 It is possible to specify a patch tool together with extra
2338 2344 arguments. For example, setting this option to ``patch --merge``
2339 2345 will use the ``patch`` program with its 2-way merge option.
2340 2346
2341 2347 ``portablefilenames``
2342 2348 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2343 2349 (default: ``warn``)
2344 2350
2345 2351 ``warn``
2346 2352 Print a warning message on POSIX platforms, if a file with a non-portable
2347 2353 filename is added (e.g. a file with a name that can't be created on
2348 2354 Windows because it contains reserved parts like ``AUX``, reserved
2349 2355 characters like ``:``, or would cause a case collision with an existing
2350 2356 file).
2351 2357
2352 2358 ``ignore``
2353 2359 Don't print a warning.
2354 2360
2355 2361 ``abort``
2356 2362 The command is aborted.
2357 2363
2358 2364 ``true``
2359 2365 Alias for ``warn``.
2360 2366
2361 2367 ``false``
2362 2368 Alias for ``ignore``.
2363 2369
2364 2370 .. container:: windows
2365 2371
2366 2372 On Windows, this configuration option is ignored and the command aborted.
2367 2373
2368 2374 ``pre-merge-tool-output-template``
2369 2375 A template that is printed before executing an external merge tool. This can
2370 2376 be used to print out additional context that might be useful to have during
2371 2377 the conflict resolution, such as the description of the various commits
2372 2378 involved or bookmarks/tags.
2373 2379
2374 2380 Additional information is available in the ``local`, ``base``, and ``other``
2375 2381 dicts. For example: ``{local.label}``, ``{base.name}``, or
2376 2382 ``{other.islink}``.
2377 2383
2378 2384 ``quiet``
2379 2385 Reduce the amount of output printed.
2380 2386 (default: False)
2381 2387
2382 2388 ``relative-paths``
2383 2389 Prefer relative paths in the UI.
2384 2390
2385 2391 ``remotecmd``
2386 2392 Remote command to use for clone/push/pull operations.
2387 2393 (default: ``hg``)
2388 2394
2389 2395 ``report_untrusted``
2390 2396 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2391 2397 trusted user or group.
2392 2398 (default: True)
2393 2399
2394 2400 ``slash``
2395 2401 (Deprecated. Use ``slashpath`` template filter instead.)
2396 2402
2397 2403 Display paths using a slash (``/``) as the path separator. This
2398 2404 only makes a difference on systems where the default path
2399 2405 separator is not the slash character (e.g. Windows uses the
2400 2406 backslash character (``\``)).
2401 2407 (default: False)
2402 2408
2403 2409 ``statuscopies``
2404 2410 Display copies in the status command.
2405 2411
2406 2412 ``ssh``
2407 2413 Command to use for SSH connections. (default: ``ssh``)
2408 2414
2409 2415 ``ssherrorhint``
2410 2416 A hint shown to the user in the case of SSH error (e.g.
2411 2417 ``Please see http://company/internalwiki/ssh.html``)
2412 2418
2413 2419 ``strict``
2414 2420 Require exact command names, instead of allowing unambiguous
2415 2421 abbreviations. (default: False)
2416 2422
2417 2423 ``style``
2418 2424 Name of style to use for command output.
2419 2425
2420 2426 ``supportcontact``
2421 2427 A URL where users should report a Mercurial traceback. Use this if you are a
2422 2428 large organisation with its own Mercurial deployment process and crash
2423 2429 reports should be addressed to your internal support.
2424 2430
2425 2431 ``textwidth``
2426 2432 Maximum width of help text. A longer line generated by ``hg help`` or
2427 2433 ``hg subcommand --help`` will be broken after white space to get this
2428 2434 width or the terminal width, whichever comes first.
2429 2435 A non-positive value will disable this and the terminal width will be
2430 2436 used. (default: 78)
2431 2437
2432 2438 ``timeout``
2433 2439 The timeout used when a lock is held (in seconds), a negative value
2434 2440 means no timeout. (default: 600)
2435 2441
2436 2442 ``timeout.warn``
2437 2443 Time (in seconds) before a warning is printed about held lock. A negative
2438 2444 value means no warning. (default: 0)
2439 2445
2440 2446 ``traceback``
2441 2447 Mercurial always prints a traceback when an unknown exception
2442 2448 occurs. Setting this to True will make Mercurial print a traceback
2443 2449 on all exceptions, even those recognized by Mercurial (such as
2444 2450 IOError or MemoryError). (default: False)
2445 2451
2446 2452 ``tweakdefaults``
2447 2453
2448 2454 By default Mercurial's behavior changes very little from release
2449 2455 to release, but over time the recommended config settings
2450 2456 shift. Enable this config to opt in to get automatic tweaks to
2451 2457 Mercurial's behavior over time. This config setting will have no
2452 2458 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2453 2459 not include ``tweakdefaults``. (default: False)
2454 2460
2455 2461 It currently means::
2456 2462
2457 2463 .. tweakdefaultsmarker
2458 2464
2459 2465 ``username``
2460 2466 The committer of a changeset created when running "commit".
2461 2467 Typically a person's name and email address, e.g. ``Fred Widget
2462 2468 <fred@example.com>``. Environment variables in the
2463 2469 username are expanded.
2464 2470
2465 2471 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2466 2472 hgrc is empty, e.g. if the system admin set ``username =`` in the
2467 2473 system hgrc, it has to be specified manually or in a different
2468 2474 hgrc file)
2469 2475
2470 2476 ``verbose``
2471 2477 Increase the amount of output printed. (default: False)
2472 2478
2473 2479
2474 2480 ``web``
2475 2481 -------
2476 2482
2477 2483 Web interface configuration. The settings in this section apply to
2478 2484 both the builtin webserver (started by :hg:`serve`) and the script you
2479 2485 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2480 2486 and WSGI).
2481 2487
2482 2488 The Mercurial webserver does no authentication (it does not prompt for
2483 2489 usernames and passwords to validate *who* users are), but it does do
2484 2490 authorization (it grants or denies access for *authenticated users*
2485 2491 based on settings in this section). You must either configure your
2486 2492 webserver to do authentication for you, or disable the authorization
2487 2493 checks.
2488 2494
2489 2495 For a quick setup in a trusted environment, e.g., a private LAN, where
2490 2496 you want it to accept pushes from anybody, you can use the following
2491 2497 command line::
2492 2498
2493 2499 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2494 2500
2495 2501 Note that this will allow anybody to push anything to the server and
2496 2502 that this should not be used for public servers.
2497 2503
2498 2504 The full set of options is:
2499 2505
2500 2506 ``accesslog``
2501 2507 Where to output the access log. (default: stdout)
2502 2508
2503 2509 ``address``
2504 2510 Interface address to bind to. (default: all)
2505 2511
2506 2512 ``allow-archive``
2507 2513 List of archive format (bz2, gz, zip) allowed for downloading.
2508 2514 (default: empty)
2509 2515
2510 2516 ``allowbz2``
2511 2517 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2512 2518 revisions.
2513 2519 (default: False)
2514 2520
2515 2521 ``allowgz``
2516 2522 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2517 2523 revisions.
2518 2524 (default: False)
2519 2525
2520 2526 ``allow-pull``
2521 2527 Whether to allow pulling from the repository. (default: True)
2522 2528
2523 2529 ``allow-push``
2524 2530 Whether to allow pushing to the repository. If empty or not set,
2525 2531 pushing is not allowed. If the special value ``*``, any remote
2526 2532 user can push, including unauthenticated users. Otherwise, the
2527 2533 remote user must have been authenticated, and the authenticated
2528 2534 user name must be present in this list. The contents of the
2529 2535 allow-push list are examined after the deny_push list.
2530 2536
2531 2537 ``allow_read``
2532 2538 If the user has not already been denied repository access due to
2533 2539 the contents of deny_read, this list determines whether to grant
2534 2540 repository access to the user. If this list is not empty, and the
2535 2541 user is unauthenticated or not present in the list, then access is
2536 2542 denied for the user. If the list is empty or not set, then access
2537 2543 is permitted to all users by default. Setting allow_read to the
2538 2544 special value ``*`` is equivalent to it not being set (i.e. access
2539 2545 is permitted to all users). The contents of the allow_read list are
2540 2546 examined after the deny_read list.
2541 2547
2542 2548 ``allowzip``
2543 2549 (DEPRECATED) Whether to allow .zip downloading of repository
2544 2550 revisions. This feature creates temporary files.
2545 2551 (default: False)
2546 2552
2547 2553 ``archivesubrepos``
2548 2554 Whether to recurse into subrepositories when archiving.
2549 2555 (default: False)
2550 2556
2551 2557 ``baseurl``
2552 2558 Base URL to use when publishing URLs in other locations, so
2553 2559 third-party tools like email notification hooks can construct
2554 2560 URLs. Example: ``http://hgserver/repos/``.
2555 2561
2556 2562 ``cacerts``
2557 2563 Path to file containing a list of PEM encoded certificate
2558 2564 authority certificates. Environment variables and ``~user``
2559 2565 constructs are expanded in the filename. If specified on the
2560 2566 client, then it will verify the identity of remote HTTPS servers
2561 2567 with these certificates.
2562 2568
2563 2569 To disable SSL verification temporarily, specify ``--insecure`` from
2564 2570 command line.
2565 2571
2566 2572 You can use OpenSSL's CA certificate file if your platform has
2567 2573 one. On most Linux systems this will be
2568 2574 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2569 2575 generate this file manually. The form must be as follows::
2570 2576
2571 2577 -----BEGIN CERTIFICATE-----
2572 2578 ... (certificate in base64 PEM encoding) ...
2573 2579 -----END CERTIFICATE-----
2574 2580 -----BEGIN CERTIFICATE-----
2575 2581 ... (certificate in base64 PEM encoding) ...
2576 2582 -----END CERTIFICATE-----
2577 2583
2578 2584 ``cache``
2579 2585 Whether to support caching in hgweb. (default: True)
2580 2586
2581 2587 ``certificate``
2582 2588 Certificate to use when running :hg:`serve`.
2583 2589
2584 2590 ``collapse``
2585 2591 With ``descend`` enabled, repositories in subdirectories are shown at
2586 2592 a single level alongside repositories in the current path. With
2587 2593 ``collapse`` also enabled, repositories residing at a deeper level than
2588 2594 the current path are grouped behind navigable directory entries that
2589 2595 lead to the locations of these repositories. In effect, this setting
2590 2596 collapses each collection of repositories found within a subdirectory
2591 2597 into a single entry for that subdirectory. (default: False)
2592 2598
2593 2599 ``comparisoncontext``
2594 2600 Number of lines of context to show in side-by-side file comparison. If
2595 2601 negative or the value ``full``, whole files are shown. (default: 5)
2596 2602
2597 2603 This setting can be overridden by a ``context`` request parameter to the
2598 2604 ``comparison`` command, taking the same values.
2599 2605
2600 2606 ``contact``
2601 2607 Name or email address of the person in charge of the repository.
2602 2608 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2603 2609
2604 2610 ``csp``
2605 2611 Send a ``Content-Security-Policy`` HTTP header with this value.
2606 2612
2607 2613 The value may contain a special string ``%nonce%``, which will be replaced
2608 2614 by a randomly-generated one-time use value. If the value contains
2609 2615 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2610 2616 one-time property of the nonce. This nonce will also be inserted into
2611 2617 ``<script>`` elements containing inline JavaScript.
2612 2618
2613 2619 Note: lots of HTML content sent by the server is derived from repository
2614 2620 data. Please consider the potential for malicious repository data to
2615 2621 "inject" itself into generated HTML content as part of your security
2616 2622 threat model.
2617 2623
2618 2624 ``deny_push``
2619 2625 Whether to deny pushing to the repository. If empty or not set,
2620 2626 push is not denied. If the special value ``*``, all remote users are
2621 2627 denied push. Otherwise, unauthenticated users are all denied, and
2622 2628 any authenticated user name present in this list is also denied. The
2623 2629 contents of the deny_push list are examined before the allow-push list.
2624 2630
2625 2631 ``deny_read``
2626 2632 Whether to deny reading/viewing of the repository. If this list is
2627 2633 not empty, unauthenticated users are all denied, and any
2628 2634 authenticated user name present in this list is also denied access to
2629 2635 the repository. If set to the special value ``*``, all remote users
2630 2636 are denied access (rarely needed ;). If deny_read is empty or not set,
2631 2637 the determination of repository access depends on the presence and
2632 2638 content of the allow_read list (see description). If both
2633 2639 deny_read and allow_read are empty or not set, then access is
2634 2640 permitted to all users by default. If the repository is being
2635 2641 served via hgwebdir, denied users will not be able to see it in
2636 2642 the list of repositories. The contents of the deny_read list have
2637 2643 priority over (are examined before) the contents of the allow_read
2638 2644 list.
2639 2645
2640 2646 ``descend``
2641 2647 hgwebdir indexes will not descend into subdirectories. Only repositories
2642 2648 directly in the current path will be shown (other repositories are still
2643 2649 available from the index corresponding to their containing path).
2644 2650
2645 2651 ``description``
2646 2652 Textual description of the repository's purpose or contents.
2647 2653 (default: "unknown")
2648 2654
2649 2655 ``encoding``
2650 2656 Character encoding name. (default: the current locale charset)
2651 2657 Example: "UTF-8".
2652 2658
2653 2659 ``errorlog``
2654 2660 Where to output the error log. (default: stderr)
2655 2661
2656 2662 ``guessmime``
2657 2663 Control MIME types for raw download of file content.
2658 2664 Set to True to let hgweb guess the content type from the file
2659 2665 extension. This will serve HTML files as ``text/html`` and might
2660 2666 allow cross-site scripting attacks when serving untrusted
2661 2667 repositories. (default: False)
2662 2668
2663 2669 ``hidden``
2664 2670 Whether to hide the repository in the hgwebdir index.
2665 2671 (default: False)
2666 2672
2667 2673 ``ipv6``
2668 2674 Whether to use IPv6. (default: False)
2669 2675
2670 2676 ``labels``
2671 2677 List of string *labels* associated with the repository.
2672 2678
2673 2679 Labels are exposed as a template keyword and can be used to customize
2674 2680 output. e.g. the ``index`` template can group or filter repositories
2675 2681 by labels and the ``summary`` template can display additional content
2676 2682 if a specific label is present.
2677 2683
2678 2684 ``logoimg``
2679 2685 File name of the logo image that some templates display on each page.
2680 2686 The file name is relative to ``staticurl``. That is, the full path to
2681 2687 the logo image is "staticurl/logoimg".
2682 2688 If unset, ``hglogo.png`` will be used.
2683 2689
2684 2690 ``logourl``
2685 2691 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2686 2692 will be used.
2687 2693
2688 2694 ``maxchanges``
2689 2695 Maximum number of changes to list on the changelog. (default: 10)
2690 2696
2691 2697 ``maxfiles``
2692 2698 Maximum number of files to list per changeset. (default: 10)
2693 2699
2694 2700 ``maxshortchanges``
2695 2701 Maximum number of changes to list on the shortlog, graph or filelog
2696 2702 pages. (default: 60)
2697 2703
2698 2704 ``name``
2699 2705 Repository name to use in the web interface.
2700 2706 (default: current working directory)
2701 2707
2702 2708 ``port``
2703 2709 Port to listen on. (default: 8000)
2704 2710
2705 2711 ``prefix``
2706 2712 Prefix path to serve from. (default: '' (server root))
2707 2713
2708 2714 ``push_ssl``
2709 2715 Whether to require that inbound pushes be transported over SSL to
2710 2716 prevent password sniffing. (default: True)
2711 2717
2712 2718 ``refreshinterval``
2713 2719 How frequently directory listings re-scan the filesystem for new
2714 2720 repositories, in seconds. This is relevant when wildcards are used
2715 2721 to define paths. Depending on how much filesystem traversal is
2716 2722 required, refreshing may negatively impact performance.
2717 2723
2718 2724 Values less than or equal to 0 always refresh.
2719 2725 (default: 20)
2720 2726
2721 2727 ``server-header``
2722 2728 Value for HTTP ``Server`` response header.
2723 2729
2724 2730 ``static``
2725 2731 Directory where static files are served from.
2726 2732
2727 2733 ``staticurl``
2728 2734 Base URL to use for static files. If unset, static files (e.g. the
2729 2735 hgicon.png favicon) will be served by the CGI script itself. Use
2730 2736 this setting to serve them directly with the HTTP server.
2731 2737 Example: ``http://hgserver/static/``.
2732 2738
2733 2739 ``stripes``
2734 2740 How many lines a "zebra stripe" should span in multi-line output.
2735 2741 Set to 0 to disable. (default: 1)
2736 2742
2737 2743 ``style``
2738 2744 Which template map style to use. The available options are the names of
2739 2745 subdirectories in the HTML templates path. (default: ``paper``)
2740 2746 Example: ``monoblue``.
2741 2747
2742 2748 ``templates``
2743 2749 Where to find the HTML templates. The default path to the HTML templates
2744 2750 can be obtained from ``hg debuginstall``.
2745 2751
2746 2752 ``websub``
2747 2753 ----------
2748 2754
2749 2755 Web substitution filter definition. You can use this section to
2750 2756 define a set of regular expression substitution patterns which
2751 2757 let you automatically modify the hgweb server output.
2752 2758
2753 2759 The default hgweb templates only apply these substitution patterns
2754 2760 on the revision description fields. You can apply them anywhere
2755 2761 you want when you create your own templates by adding calls to the
2756 2762 "websub" filter (usually after calling the "escape" filter).
2757 2763
2758 2764 This can be used, for example, to convert issue references to links
2759 2765 to your issue tracker, or to convert "markdown-like" syntax into
2760 2766 HTML (see the examples below).
2761 2767
2762 2768 Each entry in this section names a substitution filter.
2763 2769 The value of each entry defines the substitution expression itself.
2764 2770 The websub expressions follow the old interhg extension syntax,
2765 2771 which in turn imitates the Unix sed replacement syntax::
2766 2772
2767 2773 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2768 2774
2769 2775 You can use any separator other than "/". The final "i" is optional
2770 2776 and indicates that the search must be case insensitive.
2771 2777
2772 2778 Examples::
2773 2779
2774 2780 [websub]
2775 2781 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2776 2782 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2777 2783 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2778 2784
2779 2785 ``worker``
2780 2786 ----------
2781 2787
2782 2788 Parallel master/worker configuration. We currently perform working
2783 2789 directory updates in parallel on Unix-like systems, which greatly
2784 2790 helps performance.
2785 2791
2786 2792 ``enabled``
2787 2793 Whether to enable workers code to be used.
2788 2794 (default: true)
2789 2795
2790 2796 ``numcpus``
2791 2797 Number of CPUs to use for parallel operations. A zero or
2792 2798 negative value is treated as ``use the default``.
2793 2799 (default: 4 or the number of CPUs on the system, whichever is larger)
2794 2800
2795 2801 ``backgroundclose``
2796 2802 Whether to enable closing file handles on background threads during certain
2797 2803 operations. Some platforms aren't very efficient at closing file
2798 2804 handles that have been written or appended to. By performing file closing
2799 2805 on background threads, file write rate can increase substantially.
2800 2806 (default: true on Windows, false elsewhere)
2801 2807
2802 2808 ``backgroundcloseminfilecount``
2803 2809 Minimum number of files required to trigger background file closing.
2804 2810 Operations not writing this many files won't start background close
2805 2811 threads.
2806 2812 (default: 2048)
2807 2813
2808 2814 ``backgroundclosemaxqueue``
2809 2815 The maximum number of opened file handles waiting to be closed in the
2810 2816 background. This option only has an effect if ``backgroundclose`` is
2811 2817 enabled.
2812 2818 (default: 384)
2813 2819
2814 2820 ``backgroundclosethreadcount``
2815 2821 Number of threads to process background file closes. Only relevant if
2816 2822 ``backgroundclose`` is enabled.
2817 2823 (default: 4)
@@ -1,671 +1,671
1 1 # wireprotov1server.py - Wire protocol version 1 server functionality
2 2 #
3 3 # Copyright 2005-2010 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import binascii
11 11 import os
12 12
13 13 from .i18n import _
14 14 from .node import (
15 15 hex,
16 16 nullid,
17 17 )
18 18
19 19 from . import (
20 20 bundle2,
21 21 changegroup as changegroupmod,
22 22 discovery,
23 23 encoding,
24 24 error,
25 25 exchange,
26 26 pushkey as pushkeymod,
27 27 pycompat,
28 28 streamclone,
29 29 util,
30 30 wireprototypes,
31 31 )
32 32
33 33 from .utils import (
34 34 procutil,
35 35 stringutil,
36 36 )
37 37
38 38 urlerr = util.urlerr
39 39 urlreq = util.urlreq
40 40
41 41 bundle2requiredmain = _('incompatible Mercurial client; bundle2 required')
42 42 bundle2requiredhint = _('see https://www.mercurial-scm.org/wiki/'
43 43 'IncompatibleClient')
44 44 bundle2required = '%s\n(%s)\n' % (bundle2requiredmain, bundle2requiredhint)
45 45
46 46 def clientcompressionsupport(proto):
47 47 """Returns a list of compression methods supported by the client.
48 48
49 49 Returns a list of the compression methods supported by the client
50 50 according to the protocol capabilities. If no such capability has
51 51 been announced, fallback to the default of zlib and uncompressed.
52 52 """
53 53 for cap in proto.getprotocaps():
54 54 if cap.startswith('comp='):
55 55 return cap[5:].split(',')
56 56 return ['zlib', 'none']
57 57
58 58 # wire protocol command can either return a string or one of these classes.
59 59
60 60 def getdispatchrepo(repo, proto, command):
61 61 """Obtain the repo used for processing wire protocol commands.
62 62
63 63 The intent of this function is to serve as a monkeypatch point for
64 64 extensions that need commands to operate on different repo views under
65 65 specialized circumstances.
66 66 """
67 return repo.filtered('served')
67 viewconfig = repo.ui.config('server', 'view')
68 return repo.filtered(viewconfig)
68 69
69 70 def dispatch(repo, proto, command):
70 71 repo = getdispatchrepo(repo, proto, command)
71 72
72 73 func, spec = commands[command]
73 74 args = proto.getargs(spec)
74 75
75 76 return func(repo, proto, *args)
76 77
77 78 def options(cmd, keys, others):
78 79 opts = {}
79 80 for k in keys:
80 81 if k in others:
81 82 opts[k] = others[k]
82 83 del others[k]
83 84 if others:
84 85 procutil.stderr.write("warning: %s ignored unexpected arguments %s\n"
85 86 % (cmd, ",".join(others)))
86 87 return opts
87 88
88 89 def bundle1allowed(repo, action):
89 90 """Whether a bundle1 operation is allowed from the server.
90 91
91 92 Priority is:
92 93
93 94 1. server.bundle1gd.<action> (if generaldelta active)
94 95 2. server.bundle1.<action>
95 96 3. server.bundle1gd (if generaldelta active)
96 97 4. server.bundle1
97 98 """
98 99 ui = repo.ui
99 100 gd = 'generaldelta' in repo.requirements
100 101
101 102 if gd:
102 103 v = ui.configbool('server', 'bundle1gd.%s' % action)
103 104 if v is not None:
104 105 return v
105 106
106 107 v = ui.configbool('server', 'bundle1.%s' % action)
107 108 if v is not None:
108 109 return v
109 110
110 111 if gd:
111 112 v = ui.configbool('server', 'bundle1gd')
112 113 if v is not None:
113 114 return v
114 115
115 116 return ui.configbool('server', 'bundle1')
116 117
117 118 commands = wireprototypes.commanddict()
118 119
119 120 def wireprotocommand(name, args=None, permission='push'):
120 121 """Decorator to declare a wire protocol command.
121 122
122 123 ``name`` is the name of the wire protocol command being provided.
123 124
124 125 ``args`` defines the named arguments accepted by the command. It is
125 126 a space-delimited list of argument names. ``*`` denotes a special value
126 127 that says to accept all named arguments.
127 128
128 129 ``permission`` defines the permission type needed to run this command.
129 130 Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
130 131 respectively. Default is to assume command requires ``push`` permissions
131 132 because otherwise commands not declaring their permissions could modify
132 133 a repository that is supposed to be read-only.
133 134 """
134 135 transports = {k for k, v in wireprototypes.TRANSPORTS.items()
135 136 if v['version'] == 1}
136 137
137 138 # Because SSHv2 is a mirror of SSHv1, we allow "batch" commands through to
138 139 # SSHv2.
139 140 # TODO undo this hack when SSH is using the unified frame protocol.
140 141 if name == b'batch':
141 142 transports.add(wireprototypes.SSHV2)
142 143
143 144 if permission not in ('push', 'pull'):
144 145 raise error.ProgrammingError('invalid wire protocol permission; '
145 146 'got %s; expected "push" or "pull"' %
146 147 permission)
147 148
148 149 if args is None:
149 150 args = ''
150 151
151 152 if not isinstance(args, bytes):
152 153 raise error.ProgrammingError('arguments for version 1 commands '
153 154 'must be declared as bytes')
154 155
155 156 def register(func):
156 157 if name in commands:
157 158 raise error.ProgrammingError('%s command already registered '
158 159 'for version 1' % name)
159 160 commands[name] = wireprototypes.commandentry(
160 161 func, args=args, transports=transports, permission=permission)
161 162
162 163 return func
163 164 return register
164 165
165 166 # TODO define a more appropriate permissions type to use for this.
166 167 @wireprotocommand('batch', 'cmds *', permission='pull')
167 168 def batch(repo, proto, cmds, others):
168 169 unescapearg = wireprototypes.unescapebatcharg
169 repo = repo.filtered("served")
170 170 res = []
171 171 for pair in cmds.split(';'):
172 172 op, args = pair.split(' ', 1)
173 173 vals = {}
174 174 for a in args.split(','):
175 175 if a:
176 176 n, v = a.split('=')
177 177 vals[unescapearg(n)] = unescapearg(v)
178 178 func, spec = commands[op]
179 179
180 180 # Validate that client has permissions to perform this command.
181 181 perm = commands[op].permission
182 182 assert perm in ('push', 'pull')
183 183 proto.checkperm(perm)
184 184
185 185 if spec:
186 186 keys = spec.split()
187 187 data = {}
188 188 for k in keys:
189 189 if k == '*':
190 190 star = {}
191 191 for key in vals.keys():
192 192 if key not in keys:
193 193 star[key] = vals[key]
194 194 data['*'] = star
195 195 else:
196 196 data[k] = vals[k]
197 197 result = func(repo, proto, *[data[k] for k in keys])
198 198 else:
199 199 result = func(repo, proto)
200 200 if isinstance(result, wireprototypes.ooberror):
201 201 return result
202 202
203 203 # For now, all batchable commands must return bytesresponse or
204 204 # raw bytes (for backwards compatibility).
205 205 assert isinstance(result, (wireprototypes.bytesresponse, bytes))
206 206 if isinstance(result, wireprototypes.bytesresponse):
207 207 result = result.data
208 208 res.append(wireprototypes.escapebatcharg(result))
209 209
210 210 return wireprototypes.bytesresponse(';'.join(res))
211 211
212 212 @wireprotocommand('between', 'pairs', permission='pull')
213 213 def between(repo, proto, pairs):
214 214 pairs = [wireprototypes.decodelist(p, '-') for p in pairs.split(" ")]
215 215 r = []
216 216 for b in repo.between(pairs):
217 217 r.append(wireprototypes.encodelist(b) + "\n")
218 218
219 219 return wireprototypes.bytesresponse(''.join(r))
220 220
221 221 @wireprotocommand('branchmap', permission='pull')
222 222 def branchmap(repo, proto):
223 223 branchmap = repo.branchmap()
224 224 heads = []
225 225 for branch, nodes in branchmap.iteritems():
226 226 branchname = urlreq.quote(encoding.fromlocal(branch))
227 227 branchnodes = wireprototypes.encodelist(nodes)
228 228 heads.append('%s %s' % (branchname, branchnodes))
229 229
230 230 return wireprototypes.bytesresponse('\n'.join(heads))
231 231
232 232 @wireprotocommand('branches', 'nodes', permission='pull')
233 233 def branches(repo, proto, nodes):
234 234 nodes = wireprototypes.decodelist(nodes)
235 235 r = []
236 236 for b in repo.branches(nodes):
237 237 r.append(wireprototypes.encodelist(b) + "\n")
238 238
239 239 return wireprototypes.bytesresponse(''.join(r))
240 240
241 241 @wireprotocommand('clonebundles', '', permission='pull')
242 242 def clonebundles(repo, proto):
243 243 """Server command for returning info for available bundles to seed clones.
244 244
245 245 Clients will parse this response and determine what bundle to fetch.
246 246
247 247 Extensions may wrap this command to filter or dynamically emit data
248 248 depending on the request. e.g. you could advertise URLs for the closest
249 249 data center given the client's IP address.
250 250 """
251 251 return wireprototypes.bytesresponse(
252 252 repo.vfs.tryread('clonebundles.manifest'))
253 253
254 254 wireprotocaps = ['lookup', 'branchmap', 'pushkey',
255 255 'known', 'getbundle', 'unbundlehash']
256 256
257 257 def _capabilities(repo, proto):
258 258 """return a list of capabilities for a repo
259 259
260 260 This function exists to allow extensions to easily wrap capabilities
261 261 computation
262 262
263 263 - returns a lists: easy to alter
264 264 - change done here will be propagated to both `capabilities` and `hello`
265 265 command without any other action needed.
266 266 """
267 267 # copy to prevent modification of the global list
268 268 caps = list(wireprotocaps)
269 269
270 270 # Command of same name as capability isn't exposed to version 1 of
271 271 # transports. So conditionally add it.
272 272 if commands.commandavailable('changegroupsubset', proto):
273 273 caps.append('changegroupsubset')
274 274
275 275 if streamclone.allowservergeneration(repo):
276 276 if repo.ui.configbool('server', 'preferuncompressed'):
277 277 caps.append('stream-preferred')
278 278 requiredformats = repo.requirements & repo.supportedformats
279 279 # if our local revlogs are just revlogv1, add 'stream' cap
280 280 if not requiredformats - {'revlogv1'}:
281 281 caps.append('stream')
282 282 # otherwise, add 'streamreqs' detailing our local revlog format
283 283 else:
284 284 caps.append('streamreqs=%s' % ','.join(sorted(requiredformats)))
285 285 if repo.ui.configbool('experimental', 'bundle2-advertise'):
286 286 capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo, role='server'))
287 287 caps.append('bundle2=' + urlreq.quote(capsblob))
288 288 caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority))
289 289
290 290 if repo.ui.configbool('experimental', 'narrow'):
291 291 caps.append(wireprototypes.NARROWCAP)
292 292 if repo.ui.configbool('experimental', 'narrowservebrokenellipses'):
293 293 caps.append(wireprototypes.ELLIPSESCAP)
294 294
295 295 return proto.addcapabilities(repo, caps)
296 296
297 297 # If you are writing an extension and consider wrapping this function. Wrap
298 298 # `_capabilities` instead.
299 299 @wireprotocommand('capabilities', permission='pull')
300 300 def capabilities(repo, proto):
301 301 caps = _capabilities(repo, proto)
302 302 return wireprototypes.bytesresponse(' '.join(sorted(caps)))
303 303
304 304 @wireprotocommand('changegroup', 'roots', permission='pull')
305 305 def changegroup(repo, proto, roots):
306 306 nodes = wireprototypes.decodelist(roots)
307 307 outgoing = discovery.outgoing(repo, missingroots=nodes,
308 308 missingheads=repo.heads())
309 309 cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
310 310 gen = iter(lambda: cg.read(32768), '')
311 311 return wireprototypes.streamres(gen=gen)
312 312
313 313 @wireprotocommand('changegroupsubset', 'bases heads',
314 314 permission='pull')
315 315 def changegroupsubset(repo, proto, bases, heads):
316 316 bases = wireprototypes.decodelist(bases)
317 317 heads = wireprototypes.decodelist(heads)
318 318 outgoing = discovery.outgoing(repo, missingroots=bases,
319 319 missingheads=heads)
320 320 cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
321 321 gen = iter(lambda: cg.read(32768), '')
322 322 return wireprototypes.streamres(gen=gen)
323 323
324 324 @wireprotocommand('debugwireargs', 'one two *',
325 325 permission='pull')
326 326 def debugwireargs(repo, proto, one, two, others):
327 327 # only accept optional args from the known set
328 328 opts = options('debugwireargs', ['three', 'four'], others)
329 329 return wireprototypes.bytesresponse(repo.debugwireargs(
330 330 one, two, **pycompat.strkwargs(opts)))
331 331
332 332 def find_pullbundle(repo, proto, opts, clheads, heads, common):
333 333 """Return a file object for the first matching pullbundle.
334 334
335 335 Pullbundles are specified in .hg/pullbundles.manifest similar to
336 336 clonebundles.
337 337 For each entry, the bundle specification is checked for compatibility:
338 338 - Client features vs the BUNDLESPEC.
339 339 - Revisions shared with the clients vs base revisions of the bundle.
340 340 A bundle can be applied only if all its base revisions are known by
341 341 the client.
342 342 - At least one leaf of the bundle's DAG is missing on the client.
343 343 - Every leaf of the bundle's DAG is part of node set the client wants.
344 344 E.g. do not send a bundle of all changes if the client wants only
345 345 one specific branch of many.
346 346 """
347 347 def decodehexstring(s):
348 348 return set([binascii.unhexlify(h) for h in s.split(';')])
349 349
350 350 manifest = repo.vfs.tryread('pullbundles.manifest')
351 351 if not manifest:
352 352 return None
353 353 res = exchange.parseclonebundlesmanifest(repo, manifest)
354 354 res = exchange.filterclonebundleentries(repo, res)
355 355 if not res:
356 356 return None
357 357 cl = repo.changelog
358 358 heads_anc = cl.ancestors([cl.rev(rev) for rev in heads], inclusive=True)
359 359 common_anc = cl.ancestors([cl.rev(rev) for rev in common], inclusive=True)
360 360 compformats = clientcompressionsupport(proto)
361 361 for entry in res:
362 362 comp = entry.get('COMPRESSION')
363 363 altcomp = util.compengines._bundlenames.get(comp)
364 364 if comp and comp not in compformats and altcomp not in compformats:
365 365 continue
366 366 # No test yet for VERSION, since V2 is supported by any client
367 367 # that advertises partial pulls
368 368 if 'heads' in entry:
369 369 try:
370 370 bundle_heads = decodehexstring(entry['heads'])
371 371 except TypeError:
372 372 # Bad heads entry
373 373 continue
374 374 if bundle_heads.issubset(common):
375 375 continue # Nothing new
376 376 if all(cl.rev(rev) in common_anc for rev in bundle_heads):
377 377 continue # Still nothing new
378 378 if any(cl.rev(rev) not in heads_anc and
379 379 cl.rev(rev) not in common_anc for rev in bundle_heads):
380 380 continue
381 381 if 'bases' in entry:
382 382 try:
383 383 bundle_bases = decodehexstring(entry['bases'])
384 384 except TypeError:
385 385 # Bad bases entry
386 386 continue
387 387 if not all(cl.rev(rev) in common_anc for rev in bundle_bases):
388 388 continue
389 389 path = entry['URL']
390 390 repo.ui.debug('sending pullbundle "%s"\n' % path)
391 391 try:
392 392 return repo.vfs.open(path)
393 393 except IOError:
394 394 repo.ui.debug('pullbundle "%s" not accessible\n' % path)
395 395 continue
396 396 return None
397 397
398 398 @wireprotocommand('getbundle', '*', permission='pull')
399 399 def getbundle(repo, proto, others):
400 400 opts = options('getbundle', wireprototypes.GETBUNDLE_ARGUMENTS.keys(),
401 401 others)
402 402 for k, v in opts.iteritems():
403 403 keytype = wireprototypes.GETBUNDLE_ARGUMENTS[k]
404 404 if keytype == 'nodes':
405 405 opts[k] = wireprototypes.decodelist(v)
406 406 elif keytype == 'csv':
407 407 opts[k] = list(v.split(','))
408 408 elif keytype == 'scsv':
409 409 opts[k] = set(v.split(','))
410 410 elif keytype == 'boolean':
411 411 # Client should serialize False as '0', which is a non-empty string
412 412 # so it evaluates as a True bool.
413 413 if v == '0':
414 414 opts[k] = False
415 415 else:
416 416 opts[k] = bool(v)
417 417 elif keytype != 'plain':
418 418 raise KeyError('unknown getbundle option type %s'
419 419 % keytype)
420 420
421 421 if not bundle1allowed(repo, 'pull'):
422 422 if not exchange.bundle2requested(opts.get('bundlecaps')):
423 423 if proto.name == 'http-v1':
424 424 return wireprototypes.ooberror(bundle2required)
425 425 raise error.Abort(bundle2requiredmain,
426 426 hint=bundle2requiredhint)
427 427
428 428 try:
429 429 clheads = set(repo.changelog.heads())
430 430 heads = set(opts.get('heads', set()))
431 431 common = set(opts.get('common', set()))
432 432 common.discard(nullid)
433 433 if (repo.ui.configbool('server', 'pullbundle') and
434 434 'partial-pull' in proto.getprotocaps()):
435 435 # Check if a pre-built bundle covers this request.
436 436 bundle = find_pullbundle(repo, proto, opts, clheads, heads, common)
437 437 if bundle:
438 438 return wireprototypes.streamres(gen=util.filechunkiter(bundle),
439 439 prefer_uncompressed=True)
440 440
441 441 if repo.ui.configbool('server', 'disablefullbundle'):
442 442 # Check to see if this is a full clone.
443 443 changegroup = opts.get('cg', True)
444 444 if changegroup and not common and clheads == heads:
445 445 raise error.Abort(
446 446 _('server has pull-based clones disabled'),
447 447 hint=_('remove --pull if specified or upgrade Mercurial'))
448 448
449 449 info, chunks = exchange.getbundlechunks(repo, 'serve',
450 450 **pycompat.strkwargs(opts))
451 451 prefercompressed = info.get('prefercompressed', True)
452 452 except error.Abort as exc:
453 453 # cleanly forward Abort error to the client
454 454 if not exchange.bundle2requested(opts.get('bundlecaps')):
455 455 if proto.name == 'http-v1':
456 456 return wireprototypes.ooberror(pycompat.bytestr(exc) + '\n')
457 457 raise # cannot do better for bundle1 + ssh
458 458 # bundle2 request expect a bundle2 reply
459 459 bundler = bundle2.bundle20(repo.ui)
460 460 manargs = [('message', pycompat.bytestr(exc))]
461 461 advargs = []
462 462 if exc.hint is not None:
463 463 advargs.append(('hint', exc.hint))
464 464 bundler.addpart(bundle2.bundlepart('error:abort',
465 465 manargs, advargs))
466 466 chunks = bundler.getchunks()
467 467 prefercompressed = False
468 468
469 469 return wireprototypes.streamres(
470 470 gen=chunks, prefer_uncompressed=not prefercompressed)
471 471
472 472 @wireprotocommand('heads', permission='pull')
473 473 def heads(repo, proto):
474 474 h = repo.heads()
475 475 return wireprototypes.bytesresponse(wireprototypes.encodelist(h) + '\n')
476 476
477 477 @wireprotocommand('hello', permission='pull')
478 478 def hello(repo, proto):
479 479 """Called as part of SSH handshake to obtain server info.
480 480
481 481 Returns a list of lines describing interesting things about the
482 482 server, in an RFC822-like format.
483 483
484 484 Currently, the only one defined is ``capabilities``, which consists of a
485 485 line of space separated tokens describing server abilities:
486 486
487 487 capabilities: <token0> <token1> <token2>
488 488 """
489 489 caps = capabilities(repo, proto).data
490 490 return wireprototypes.bytesresponse('capabilities: %s\n' % caps)
491 491
492 492 @wireprotocommand('listkeys', 'namespace', permission='pull')
493 493 def listkeys(repo, proto, namespace):
494 494 d = sorted(repo.listkeys(encoding.tolocal(namespace)).items())
495 495 return wireprototypes.bytesresponse(pushkeymod.encodekeys(d))
496 496
497 497 @wireprotocommand('lookup', 'key', permission='pull')
498 498 def lookup(repo, proto, key):
499 499 try:
500 500 k = encoding.tolocal(key)
501 501 n = repo.lookup(k)
502 502 r = hex(n)
503 503 success = 1
504 504 except Exception as inst:
505 505 r = stringutil.forcebytestr(inst)
506 506 success = 0
507 507 return wireprototypes.bytesresponse('%d %s\n' % (success, r))
508 508
509 509 @wireprotocommand('known', 'nodes *', permission='pull')
510 510 def known(repo, proto, nodes, others):
511 511 v = ''.join(b and '1' or '0'
512 512 for b in repo.known(wireprototypes.decodelist(nodes)))
513 513 return wireprototypes.bytesresponse(v)
514 514
515 515 @wireprotocommand('protocaps', 'caps', permission='pull')
516 516 def protocaps(repo, proto, caps):
517 517 if proto.name == wireprototypes.SSHV1:
518 518 proto._protocaps = set(caps.split(' '))
519 519 return wireprototypes.bytesresponse('OK')
520 520
521 521 @wireprotocommand('pushkey', 'namespace key old new', permission='push')
522 522 def pushkey(repo, proto, namespace, key, old, new):
523 523 # compatibility with pre-1.8 clients which were accidentally
524 524 # sending raw binary nodes rather than utf-8-encoded hex
525 525 if len(new) == 20 and stringutil.escapestr(new) != new:
526 526 # looks like it could be a binary node
527 527 try:
528 528 new.decode('utf-8')
529 529 new = encoding.tolocal(new) # but cleanly decodes as UTF-8
530 530 except UnicodeDecodeError:
531 531 pass # binary, leave unmodified
532 532 else:
533 533 new = encoding.tolocal(new) # normal path
534 534
535 535 with proto.mayberedirectstdio() as output:
536 536 r = repo.pushkey(encoding.tolocal(namespace), encoding.tolocal(key),
537 537 encoding.tolocal(old), new) or False
538 538
539 539 output = output.getvalue() if output else ''
540 540 return wireprototypes.bytesresponse('%d\n%s' % (int(r), output))
541 541
542 542 @wireprotocommand('stream_out', permission='pull')
543 543 def stream(repo, proto):
544 544 '''If the server supports streaming clone, it advertises the "stream"
545 545 capability with a value representing the version and flags of the repo
546 546 it is serving. Client checks to see if it understands the format.
547 547 '''
548 548 return wireprototypes.streamreslegacy(
549 549 streamclone.generatev1wireproto(repo))
550 550
551 551 @wireprotocommand('unbundle', 'heads', permission='push')
552 552 def unbundle(repo, proto, heads):
553 553 their_heads = wireprototypes.decodelist(heads)
554 554
555 555 with proto.mayberedirectstdio() as output:
556 556 try:
557 557 exchange.check_heads(repo, their_heads, 'preparing changes')
558 558 cleanup = lambda: None
559 559 try:
560 560 payload = proto.getpayload()
561 561 if repo.ui.configbool('server', 'streamunbundle'):
562 562 def cleanup():
563 563 # Ensure that the full payload is consumed, so
564 564 # that the connection doesn't contain trailing garbage.
565 565 for p in payload:
566 566 pass
567 567 fp = util.chunkbuffer(payload)
568 568 else:
569 569 # write bundle data to temporary file as it can be big
570 570 fp, tempname = None, None
571 571 def cleanup():
572 572 if fp:
573 573 fp.close()
574 574 if tempname:
575 575 os.unlink(tempname)
576 576 fd, tempname = pycompat.mkstemp(prefix='hg-unbundle-')
577 577 repo.ui.debug('redirecting incoming bundle to %s\n' %
578 578 tempname)
579 579 fp = os.fdopen(fd, pycompat.sysstr('wb+'))
580 580 for p in payload:
581 581 fp.write(p)
582 582 fp.seek(0)
583 583
584 584 gen = exchange.readbundle(repo.ui, fp, None)
585 585 if (isinstance(gen, changegroupmod.cg1unpacker)
586 586 and not bundle1allowed(repo, 'push')):
587 587 if proto.name == 'http-v1':
588 588 # need to special case http because stderr do not get to
589 589 # the http client on failed push so we need to abuse
590 590 # some other error type to make sure the message get to
591 591 # the user.
592 592 return wireprototypes.ooberror(bundle2required)
593 593 raise error.Abort(bundle2requiredmain,
594 594 hint=bundle2requiredhint)
595 595
596 596 r = exchange.unbundle(repo, gen, their_heads, 'serve',
597 597 proto.client())
598 598 if util.safehasattr(r, 'addpart'):
599 599 # The return looks streamable, we are in the bundle2 case
600 600 # and should return a stream.
601 601 return wireprototypes.streamreslegacy(gen=r.getchunks())
602 602 return wireprototypes.pushres(
603 603 r, output.getvalue() if output else '')
604 604
605 605 finally:
606 606 cleanup()
607 607
608 608 except (error.BundleValueError, error.Abort, error.PushRaced) as exc:
609 609 # handle non-bundle2 case first
610 610 if not getattr(exc, 'duringunbundle2', False):
611 611 try:
612 612 raise
613 613 except error.Abort:
614 614 # The old code we moved used procutil.stderr directly.
615 615 # We did not change it to minimise code change.
616 616 # This need to be moved to something proper.
617 617 # Feel free to do it.
618 618 procutil.stderr.write("abort: %s\n" % exc)
619 619 if exc.hint is not None:
620 620 procutil.stderr.write("(%s)\n" % exc.hint)
621 621 procutil.stderr.flush()
622 622 return wireprototypes.pushres(
623 623 0, output.getvalue() if output else '')
624 624 except error.PushRaced:
625 625 return wireprototypes.pusherr(
626 626 pycompat.bytestr(exc),
627 627 output.getvalue() if output else '')
628 628
629 629 bundler = bundle2.bundle20(repo.ui)
630 630 for out in getattr(exc, '_bundle2salvagedoutput', ()):
631 631 bundler.addpart(out)
632 632 try:
633 633 try:
634 634 raise
635 635 except error.PushkeyFailed as exc:
636 636 # check client caps
637 637 remotecaps = getattr(exc, '_replycaps', None)
638 638 if (remotecaps is not None
639 639 and 'pushkey' not in remotecaps.get('error', ())):
640 640 # no support remote side, fallback to Abort handler.
641 641 raise
642 642 part = bundler.newpart('error:pushkey')
643 643 part.addparam('in-reply-to', exc.partid)
644 644 if exc.namespace is not None:
645 645 part.addparam('namespace', exc.namespace,
646 646 mandatory=False)
647 647 if exc.key is not None:
648 648 part.addparam('key', exc.key, mandatory=False)
649 649 if exc.new is not None:
650 650 part.addparam('new', exc.new, mandatory=False)
651 651 if exc.old is not None:
652 652 part.addparam('old', exc.old, mandatory=False)
653 653 if exc.ret is not None:
654 654 part.addparam('ret', exc.ret, mandatory=False)
655 655 except error.BundleValueError as exc:
656 656 errpart = bundler.newpart('error:unsupportedcontent')
657 657 if exc.parttype is not None:
658 658 errpart.addparam('parttype', exc.parttype)
659 659 if exc.params:
660 660 errpart.addparam('params', '\0'.join(exc.params))
661 661 except error.Abort as exc:
662 662 manargs = [('message', stringutil.forcebytestr(exc))]
663 663 advargs = []
664 664 if exc.hint is not None:
665 665 advargs.append(('hint', exc.hint))
666 666 bundler.addpart(bundle2.bundlepart('error:abort',
667 667 manargs, advargs))
668 668 except error.PushRaced as exc:
669 669 bundler.newpart('error:pushraced',
670 670 [('message', stringutil.forcebytestr(exc))])
671 671 return wireprototypes.streamreslegacy(gen=bundler.getchunks())
@@ -1,1454 +1,1455
1 1 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2 2 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 3 #
4 4 # This software may be used and distributed according to the terms of the
5 5 # GNU General Public License version 2 or any later version.
6 6
7 7 from __future__ import absolute_import
8 8
9 9 import collections
10 10 import contextlib
11 11 import hashlib
12 12
13 13 from .i18n import _
14 14 from .node import (
15 15 hex,
16 16 nullid,
17 17 )
18 18 from . import (
19 19 discovery,
20 20 encoding,
21 21 error,
22 22 match as matchmod,
23 23 narrowspec,
24 24 pycompat,
25 25 streamclone,
26 26 templatefilters,
27 27 util,
28 28 wireprotoframing,
29 29 wireprototypes,
30 30 )
31 31 from .utils import (
32 32 cborutil,
33 33 interfaceutil,
34 34 stringutil,
35 35 )
36 36
37 37 FRAMINGTYPE = b'application/mercurial-exp-framing-0006'
38 38
39 39 HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2
40 40
41 41 COMMANDS = wireprototypes.commanddict()
42 42
43 43 # Value inserted into cache key computation function. Change the value to
44 44 # force new cache keys for every command request. This should be done when
45 45 # there is a change to how caching works, etc.
46 46 GLOBAL_CACHE_VERSION = 1
47 47
48 48 def handlehttpv2request(rctx, req, res, checkperm, urlparts):
49 49 from .hgweb import common as hgwebcommon
50 50
51 51 # URL space looks like: <permissions>/<command>, where <permission> can
52 52 # be ``ro`` or ``rw`` to signal read-only or read-write, respectively.
53 53
54 54 # Root URL does nothing meaningful... yet.
55 55 if not urlparts:
56 56 res.status = b'200 OK'
57 57 res.headers[b'Content-Type'] = b'text/plain'
58 58 res.setbodybytes(_('HTTP version 2 API handler'))
59 59 return
60 60
61 61 if len(urlparts) == 1:
62 62 res.status = b'404 Not Found'
63 63 res.headers[b'Content-Type'] = b'text/plain'
64 64 res.setbodybytes(_('do not know how to process %s\n') %
65 65 req.dispatchpath)
66 66 return
67 67
68 68 permission, command = urlparts[0:2]
69 69
70 70 if permission not in (b'ro', b'rw'):
71 71 res.status = b'404 Not Found'
72 72 res.headers[b'Content-Type'] = b'text/plain'
73 73 res.setbodybytes(_('unknown permission: %s') % permission)
74 74 return
75 75
76 76 if req.method != 'POST':
77 77 res.status = b'405 Method Not Allowed'
78 78 res.headers[b'Allow'] = b'POST'
79 79 res.setbodybytes(_('commands require POST requests'))
80 80 return
81 81
82 82 # At some point we'll want to use our own API instead of recycling the
83 83 # behavior of version 1 of the wire protocol...
84 84 # TODO return reasonable responses - not responses that overload the
85 85 # HTTP status line message for error reporting.
86 86 try:
87 87 checkperm(rctx, req, 'pull' if permission == b'ro' else 'push')
88 88 except hgwebcommon.ErrorResponse as e:
89 89 res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))
90 90 for k, v in e.headers:
91 91 res.headers[k] = v
92 92 res.setbodybytes('permission denied')
93 93 return
94 94
95 95 # We have a special endpoint to reflect the request back at the client.
96 96 if command == b'debugreflect':
97 97 _processhttpv2reflectrequest(rctx.repo.ui, rctx.repo, req, res)
98 98 return
99 99
100 100 # Extra commands that we handle that aren't really wire protocol
101 101 # commands. Think extra hard before making this hackery available to
102 102 # extension.
103 103 extracommands = {'multirequest'}
104 104
105 105 if command not in COMMANDS and command not in extracommands:
106 106 res.status = b'404 Not Found'
107 107 res.headers[b'Content-Type'] = b'text/plain'
108 108 res.setbodybytes(_('unknown wire protocol command: %s\n') % command)
109 109 return
110 110
111 111 repo = rctx.repo
112 112 ui = repo.ui
113 113
114 114 proto = httpv2protocolhandler(req, ui)
115 115
116 116 if (not COMMANDS.commandavailable(command, proto)
117 117 and command not in extracommands):
118 118 res.status = b'404 Not Found'
119 119 res.headers[b'Content-Type'] = b'text/plain'
120 120 res.setbodybytes(_('invalid wire protocol command: %s') % command)
121 121 return
122 122
123 123 # TODO consider cases where proxies may add additional Accept headers.
124 124 if req.headers.get(b'Accept') != FRAMINGTYPE:
125 125 res.status = b'406 Not Acceptable'
126 126 res.headers[b'Content-Type'] = b'text/plain'
127 127 res.setbodybytes(_('client MUST specify Accept header with value: %s\n')
128 128 % FRAMINGTYPE)
129 129 return
130 130
131 131 if req.headers.get(b'Content-Type') != FRAMINGTYPE:
132 132 res.status = b'415 Unsupported Media Type'
133 133 # TODO we should send a response with appropriate media type,
134 134 # since client does Accept it.
135 135 res.headers[b'Content-Type'] = b'text/plain'
136 136 res.setbodybytes(_('client MUST send Content-Type header with '
137 137 'value: %s\n') % FRAMINGTYPE)
138 138 return
139 139
140 140 _processhttpv2request(ui, repo, req, res, permission, command, proto)
141 141
142 142 def _processhttpv2reflectrequest(ui, repo, req, res):
143 143 """Reads unified frame protocol request and dumps out state to client.
144 144
145 145 This special endpoint can be used to help debug the wire protocol.
146 146
147 147 Instead of routing the request through the normal dispatch mechanism,
148 148 we instead read all frames, decode them, and feed them into our state
149 149 tracker. We then dump the log of all that activity back out to the
150 150 client.
151 151 """
152 152 # Reflection APIs have a history of being abused, accidentally disclosing
153 153 # sensitive data, etc. So we have a config knob.
154 154 if not ui.configbool('experimental', 'web.api.debugreflect'):
155 155 res.status = b'404 Not Found'
156 156 res.headers[b'Content-Type'] = b'text/plain'
157 157 res.setbodybytes(_('debugreflect service not available'))
158 158 return
159 159
160 160 # We assume we have a unified framing protocol request body.
161 161
162 162 reactor = wireprotoframing.serverreactor(ui)
163 163 states = []
164 164
165 165 while True:
166 166 frame = wireprotoframing.readframe(req.bodyfh)
167 167
168 168 if not frame:
169 169 states.append(b'received: <no frame>')
170 170 break
171 171
172 172 states.append(b'received: %d %d %d %s' % (frame.typeid, frame.flags,
173 173 frame.requestid,
174 174 frame.payload))
175 175
176 176 action, meta = reactor.onframerecv(frame)
177 177 states.append(templatefilters.json((action, meta)))
178 178
179 179 action, meta = reactor.oninputeof()
180 180 meta['action'] = action
181 181 states.append(templatefilters.json(meta))
182 182
183 183 res.status = b'200 OK'
184 184 res.headers[b'Content-Type'] = b'text/plain'
185 185 res.setbodybytes(b'\n'.join(states))
186 186
187 187 def _processhttpv2request(ui, repo, req, res, authedperm, reqcommand, proto):
188 188 """Post-validation handler for HTTPv2 requests.
189 189
190 190 Called when the HTTP request contains unified frame-based protocol
191 191 frames for evaluation.
192 192 """
193 193 # TODO Some HTTP clients are full duplex and can receive data before
194 194 # the entire request is transmitted. Figure out a way to indicate support
195 195 # for that so we can opt into full duplex mode.
196 196 reactor = wireprotoframing.serverreactor(ui, deferoutput=True)
197 197 seencommand = False
198 198
199 199 outstream = None
200 200
201 201 while True:
202 202 frame = wireprotoframing.readframe(req.bodyfh)
203 203 if not frame:
204 204 break
205 205
206 206 action, meta = reactor.onframerecv(frame)
207 207
208 208 if action == 'wantframe':
209 209 # Need more data before we can do anything.
210 210 continue
211 211 elif action == 'runcommand':
212 212 # Defer creating output stream because we need to wait for
213 213 # protocol settings frames so proper encoding can be applied.
214 214 if not outstream:
215 215 outstream = reactor.makeoutputstream()
216 216
217 217 sentoutput = _httpv2runcommand(ui, repo, req, res, authedperm,
218 218 reqcommand, reactor, outstream,
219 219 meta, issubsequent=seencommand)
220 220
221 221 if sentoutput:
222 222 return
223 223
224 224 seencommand = True
225 225
226 226 elif action == 'error':
227 227 # TODO define proper error mechanism.
228 228 res.status = b'200 OK'
229 229 res.headers[b'Content-Type'] = b'text/plain'
230 230 res.setbodybytes(meta['message'] + b'\n')
231 231 return
232 232 else:
233 233 raise error.ProgrammingError(
234 234 'unhandled action from frame processor: %s' % action)
235 235
236 236 action, meta = reactor.oninputeof()
237 237 if action == 'sendframes':
238 238 # We assume we haven't started sending the response yet. If we're
239 239 # wrong, the response type will raise an exception.
240 240 res.status = b'200 OK'
241 241 res.headers[b'Content-Type'] = FRAMINGTYPE
242 242 res.setbodygen(meta['framegen'])
243 243 elif action == 'noop':
244 244 pass
245 245 else:
246 246 raise error.ProgrammingError('unhandled action from frame processor: %s'
247 247 % action)
248 248
249 249 def _httpv2runcommand(ui, repo, req, res, authedperm, reqcommand, reactor,
250 250 outstream, command, issubsequent):
251 251 """Dispatch a wire protocol command made from HTTPv2 requests.
252 252
253 253 The authenticated permission (``authedperm``) along with the original
254 254 command from the URL (``reqcommand``) are passed in.
255 255 """
256 256 # We already validated that the session has permissions to perform the
257 257 # actions in ``authedperm``. In the unified frame protocol, the canonical
258 258 # command to run is expressed in a frame. However, the URL also requested
259 259 # to run a specific command. We need to be careful that the command we
260 260 # run doesn't have permissions requirements greater than what was granted
261 261 # by ``authedperm``.
262 262 #
263 263 # Our rule for this is we only allow one command per HTTP request and
264 264 # that command must match the command in the URL. However, we make
265 265 # an exception for the ``multirequest`` URL. This URL is allowed to
266 266 # execute multiple commands. We double check permissions of each command
267 267 # as it is invoked to ensure there is no privilege escalation.
268 268 # TODO consider allowing multiple commands to regular command URLs
269 269 # iff each command is the same.
270 270
271 271 proto = httpv2protocolhandler(req, ui, args=command['args'])
272 272
273 273 if reqcommand == b'multirequest':
274 274 if not COMMANDS.commandavailable(command['command'], proto):
275 275 # TODO proper error mechanism
276 276 res.status = b'200 OK'
277 277 res.headers[b'Content-Type'] = b'text/plain'
278 278 res.setbodybytes(_('wire protocol command not available: %s') %
279 279 command['command'])
280 280 return True
281 281
282 282 # TODO don't use assert here, since it may be elided by -O.
283 283 assert authedperm in (b'ro', b'rw')
284 284 wirecommand = COMMANDS[command['command']]
285 285 assert wirecommand.permission in ('push', 'pull')
286 286
287 287 if authedperm == b'ro' and wirecommand.permission != 'pull':
288 288 # TODO proper error mechanism
289 289 res.status = b'403 Forbidden'
290 290 res.headers[b'Content-Type'] = b'text/plain'
291 291 res.setbodybytes(_('insufficient permissions to execute '
292 292 'command: %s') % command['command'])
293 293 return True
294 294
295 295 # TODO should we also call checkperm() here? Maybe not if we're going
296 296 # to overhaul that API. The granted scope from the URL check should
297 297 # be good enough.
298 298
299 299 else:
300 300 # Don't allow multiple commands outside of ``multirequest`` URL.
301 301 if issubsequent:
302 302 # TODO proper error mechanism
303 303 res.status = b'200 OK'
304 304 res.headers[b'Content-Type'] = b'text/plain'
305 305 res.setbodybytes(_('multiple commands cannot be issued to this '
306 306 'URL'))
307 307 return True
308 308
309 309 if reqcommand != command['command']:
310 310 # TODO define proper error mechanism
311 311 res.status = b'200 OK'
312 312 res.headers[b'Content-Type'] = b'text/plain'
313 313 res.setbodybytes(_('command in frame must match command in URL'))
314 314 return True
315 315
316 316 res.status = b'200 OK'
317 317 res.headers[b'Content-Type'] = FRAMINGTYPE
318 318
319 319 try:
320 320 objs = dispatch(repo, proto, command['command'], command['redirect'])
321 321
322 322 action, meta = reactor.oncommandresponsereadyobjects(
323 323 outstream, command['requestid'], objs)
324 324
325 325 except error.WireprotoCommandError as e:
326 326 action, meta = reactor.oncommanderror(
327 327 outstream, command['requestid'], e.message, e.messageargs)
328 328
329 329 except Exception as e:
330 330 action, meta = reactor.onservererror(
331 331 outstream, command['requestid'],
332 332 _('exception when invoking command: %s') %
333 333 stringutil.forcebytestr(e))
334 334
335 335 if action == 'sendframes':
336 336 res.setbodygen(meta['framegen'])
337 337 return True
338 338 elif action == 'noop':
339 339 return False
340 340 else:
341 341 raise error.ProgrammingError('unhandled event from reactor: %s' %
342 342 action)
343 343
344 344 def getdispatchrepo(repo, proto, command):
345 return repo.filtered('served')
345 viewconfig = repo.ui.config('server', 'view')
346 return repo.filtered(viewconfig)
346 347
347 348 def dispatch(repo, proto, command, redirect):
348 349 """Run a wire protocol command.
349 350
350 351 Returns an iterable of objects that will be sent to the client.
351 352 """
352 353 repo = getdispatchrepo(repo, proto, command)
353 354
354 355 entry = COMMANDS[command]
355 356 func = entry.func
356 357 spec = entry.args
357 358
358 359 args = proto.getargs(spec)
359 360
360 361 # There is some duplicate boilerplate code here for calling the command and
361 362 # emitting objects. It is either that or a lot of indented code that looks
362 363 # like a pyramid (since there are a lot of code paths that result in not
363 364 # using the cacher).
364 365 callcommand = lambda: func(repo, proto, **pycompat.strkwargs(args))
365 366
366 367 # Request is not cacheable. Don't bother instantiating a cacher.
367 368 if not entry.cachekeyfn:
368 369 for o in callcommand():
369 370 yield o
370 371 return
371 372
372 373 if redirect:
373 374 redirecttargets = redirect[b'targets']
374 375 redirecthashes = redirect[b'hashes']
375 376 else:
376 377 redirecttargets = []
377 378 redirecthashes = []
378 379
379 380 cacher = makeresponsecacher(repo, proto, command, args,
380 381 cborutil.streamencode,
381 382 redirecttargets=redirecttargets,
382 383 redirecthashes=redirecthashes)
383 384
384 385 # But we have no cacher. Do default handling.
385 386 if not cacher:
386 387 for o in callcommand():
387 388 yield o
388 389 return
389 390
390 391 with cacher:
391 392 cachekey = entry.cachekeyfn(repo, proto, cacher,
392 393 **pycompat.strkwargs(args))
393 394
394 395 # No cache key or the cacher doesn't like it. Do default handling.
395 396 if cachekey is None or not cacher.setcachekey(cachekey):
396 397 for o in callcommand():
397 398 yield o
398 399 return
399 400
400 401 # Serve it from the cache, if possible.
401 402 cached = cacher.lookup()
402 403
403 404 if cached:
404 405 for o in cached['objs']:
405 406 yield o
406 407 return
407 408
408 409 # Else call the command and feed its output into the cacher, allowing
409 410 # the cacher to buffer/mutate objects as it desires.
410 411 for o in callcommand():
411 412 for o in cacher.onobject(o):
412 413 yield o
413 414
414 415 for o in cacher.onfinished():
415 416 yield o
416 417
417 418 @interfaceutil.implementer(wireprototypes.baseprotocolhandler)
418 419 class httpv2protocolhandler(object):
419 420 def __init__(self, req, ui, args=None):
420 421 self._req = req
421 422 self._ui = ui
422 423 self._args = args
423 424
424 425 @property
425 426 def name(self):
426 427 return HTTP_WIREPROTO_V2
427 428
428 429 def getargs(self, args):
429 430 # First look for args that were passed but aren't registered on this
430 431 # command.
431 432 extra = set(self._args) - set(args)
432 433 if extra:
433 434 raise error.WireprotoCommandError(
434 435 'unsupported argument to command: %s' %
435 436 ', '.join(sorted(extra)))
436 437
437 438 # And look for required arguments that are missing.
438 439 missing = {a for a in args if args[a]['required']} - set(self._args)
439 440
440 441 if missing:
441 442 raise error.WireprotoCommandError(
442 443 'missing required arguments: %s' % ', '.join(sorted(missing)))
443 444
444 445 # Now derive the arguments to pass to the command, taking into
445 446 # account the arguments specified by the client.
446 447 data = {}
447 448 for k, meta in sorted(args.items()):
448 449 # This argument wasn't passed by the client.
449 450 if k not in self._args:
450 451 data[k] = meta['default']()
451 452 continue
452 453
453 454 v = self._args[k]
454 455
455 456 # Sets may be expressed as lists. Silently normalize.
456 457 if meta['type'] == 'set' and isinstance(v, list):
457 458 v = set(v)
458 459
459 460 # TODO consider more/stronger type validation.
460 461
461 462 data[k] = v
462 463
463 464 return data
464 465
465 466 def getprotocaps(self):
466 467 # Protocol capabilities are currently not implemented for HTTP V2.
467 468 return set()
468 469
469 470 def getpayload(self):
470 471 raise NotImplementedError
471 472
472 473 @contextlib.contextmanager
473 474 def mayberedirectstdio(self):
474 475 raise NotImplementedError
475 476
476 477 def client(self):
477 478 raise NotImplementedError
478 479
479 480 def addcapabilities(self, repo, caps):
480 481 return caps
481 482
482 483 def checkperm(self, perm):
483 484 raise NotImplementedError
484 485
485 486 def httpv2apidescriptor(req, repo):
486 487 proto = httpv2protocolhandler(req, repo.ui)
487 488
488 489 return _capabilitiesv2(repo, proto)
489 490
490 491 def _capabilitiesv2(repo, proto):
491 492 """Obtain the set of capabilities for version 2 transports.
492 493
493 494 These capabilities are distinct from the capabilities for version 1
494 495 transports.
495 496 """
496 497 caps = {
497 498 'commands': {},
498 499 'framingmediatypes': [FRAMINGTYPE],
499 500 'pathfilterprefixes': set(narrowspec.VALID_PREFIXES),
500 501 }
501 502
502 503 for command, entry in COMMANDS.items():
503 504 args = {}
504 505
505 506 for arg, meta in entry.args.items():
506 507 args[arg] = {
507 508 # TODO should this be a normalized type using CBOR's
508 509 # terminology?
509 510 b'type': meta['type'],
510 511 b'required': meta['required'],
511 512 }
512 513
513 514 if not meta['required']:
514 515 args[arg][b'default'] = meta['default']()
515 516
516 517 if meta['validvalues']:
517 518 args[arg][b'validvalues'] = meta['validvalues']
518 519
519 520 # TODO this type of check should be defined in a per-command callback.
520 521 if (command == b'rawstorefiledata'
521 522 and not streamclone.allowservergeneration(repo)):
522 523 continue
523 524
524 525 caps['commands'][command] = {
525 526 'args': args,
526 527 'permissions': [entry.permission],
527 528 }
528 529
529 530 if entry.extracapabilitiesfn:
530 531 extracaps = entry.extracapabilitiesfn(repo, proto)
531 532 caps['commands'][command].update(extracaps)
532 533
533 534 caps['rawrepoformats'] = sorted(repo.requirements &
534 535 repo.supportedformats)
535 536
536 537 targets = getadvertisedredirecttargets(repo, proto)
537 538 if targets:
538 539 caps[b'redirect'] = {
539 540 b'targets': [],
540 541 b'hashes': [b'sha256', b'sha1'],
541 542 }
542 543
543 544 for target in targets:
544 545 entry = {
545 546 b'name': target['name'],
546 547 b'protocol': target['protocol'],
547 548 b'uris': target['uris'],
548 549 }
549 550
550 551 for key in ('snirequired', 'tlsversions'):
551 552 if key in target:
552 553 entry[key] = target[key]
553 554
554 555 caps[b'redirect'][b'targets'].append(entry)
555 556
556 557 return proto.addcapabilities(repo, caps)
557 558
558 559 def getadvertisedredirecttargets(repo, proto):
559 560 """Obtain a list of content redirect targets.
560 561
561 562 Returns a list containing potential redirect targets that will be
562 563 advertised in capabilities data. Each dict MUST have the following
563 564 keys:
564 565
565 566 name
566 567 The name of this redirect target. This is the identifier clients use
567 568 to refer to a target. It is transferred as part of every command
568 569 request.
569 570
570 571 protocol
571 572 Network protocol used by this target. Typically this is the string
572 573 in front of the ``://`` in a URL. e.g. ``https``.
573 574
574 575 uris
575 576 List of representative URIs for this target. Clients can use the
576 577 URIs to test parsing for compatibility or for ordering preference
577 578 for which target to use.
578 579
579 580 The following optional keys are recognized:
580 581
581 582 snirequired
582 583 Bool indicating if Server Name Indication (SNI) is required to
583 584 connect to this target.
584 585
585 586 tlsversions
586 587 List of bytes indicating which TLS versions are supported by this
587 588 target.
588 589
589 590 By default, clients reflect the target order advertised by servers
590 591 and servers will use the first client-advertised target when picking
591 592 a redirect target. So targets should be advertised in the order the
592 593 server prefers they be used.
593 594 """
594 595 return []
595 596
596 597 def wireprotocommand(name, args=None, permission='push', cachekeyfn=None,
597 598 extracapabilitiesfn=None):
598 599 """Decorator to declare a wire protocol command.
599 600
600 601 ``name`` is the name of the wire protocol command being provided.
601 602
602 603 ``args`` is a dict defining arguments accepted by the command. Keys are
603 604 the argument name. Values are dicts with the following keys:
604 605
605 606 ``type``
606 607 The argument data type. Must be one of the following string
607 608 literals: ``bytes``, ``int``, ``list``, ``dict``, ``set``,
608 609 or ``bool``.
609 610
610 611 ``default``
611 612 A callable returning the default value for this argument. If not
612 613 specified, ``None`` will be the default value.
613 614
614 615 ``example``
615 616 An example value for this argument.
616 617
617 618 ``validvalues``
618 619 Set of recognized values for this argument.
619 620
620 621 ``permission`` defines the permission type needed to run this command.
621 622 Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
622 623 respectively. Default is to assume command requires ``push`` permissions
623 624 because otherwise commands not declaring their permissions could modify
624 625 a repository that is supposed to be read-only.
625 626
626 627 ``cachekeyfn`` defines an optional callable that can derive the
627 628 cache key for this request.
628 629
629 630 ``extracapabilitiesfn`` defines an optional callable that defines extra
630 631 command capabilities/parameters that are advertised next to the command
631 632 in the capabilities data structure describing the server. The callable
632 633 receives as arguments the repository and protocol objects. It returns
633 634 a dict of extra fields to add to the command descriptor.
634 635
635 636 Wire protocol commands are generators of objects to be serialized and
636 637 sent to the client.
637 638
638 639 If a command raises an uncaught exception, this will be translated into
639 640 a command error.
640 641
641 642 All commands can opt in to being cacheable by defining a function
642 643 (``cachekeyfn``) that is called to derive a cache key. This function
643 644 receives the same arguments as the command itself plus a ``cacher``
644 645 argument containing the active cacher for the request and returns a bytes
645 646 containing the key in a cache the response to this command may be cached
646 647 under.
647 648 """
648 649 transports = {k for k, v in wireprototypes.TRANSPORTS.items()
649 650 if v['version'] == 2}
650 651
651 652 if permission not in ('push', 'pull'):
652 653 raise error.ProgrammingError('invalid wire protocol permission; '
653 654 'got %s; expected "push" or "pull"' %
654 655 permission)
655 656
656 657 if args is None:
657 658 args = {}
658 659
659 660 if not isinstance(args, dict):
660 661 raise error.ProgrammingError('arguments for version 2 commands '
661 662 'must be declared as dicts')
662 663
663 664 for arg, meta in args.items():
664 665 if arg == '*':
665 666 raise error.ProgrammingError('* argument name not allowed on '
666 667 'version 2 commands')
667 668
668 669 if not isinstance(meta, dict):
669 670 raise error.ProgrammingError('arguments for version 2 commands '
670 671 'must declare metadata as a dict')
671 672
672 673 if 'type' not in meta:
673 674 raise error.ProgrammingError('%s argument for command %s does not '
674 675 'declare type field' % (arg, name))
675 676
676 677 if meta['type'] not in ('bytes', 'int', 'list', 'dict', 'set', 'bool'):
677 678 raise error.ProgrammingError('%s argument for command %s has '
678 679 'illegal type: %s' % (arg, name,
679 680 meta['type']))
680 681
681 682 if 'example' not in meta:
682 683 raise error.ProgrammingError('%s argument for command %s does not '
683 684 'declare example field' % (arg, name))
684 685
685 686 meta['required'] = 'default' not in meta
686 687
687 688 meta.setdefault('default', lambda: None)
688 689 meta.setdefault('validvalues', None)
689 690
690 691 def register(func):
691 692 if name in COMMANDS:
692 693 raise error.ProgrammingError('%s command already registered '
693 694 'for version 2' % name)
694 695
695 696 COMMANDS[name] = wireprototypes.commandentry(
696 697 func, args=args, transports=transports, permission=permission,
697 698 cachekeyfn=cachekeyfn, extracapabilitiesfn=extracapabilitiesfn)
698 699
699 700 return func
700 701
701 702 return register
702 703
703 704 def makecommandcachekeyfn(command, localversion=None, allargs=False):
704 705 """Construct a cache key derivation function with common features.
705 706
706 707 By default, the cache key is a hash of:
707 708
708 709 * The command name.
709 710 * A global cache version number.
710 711 * A local cache version number (passed via ``localversion``).
711 712 * All the arguments passed to the command.
712 713 * The media type used.
713 714 * Wire protocol version string.
714 715 * The repository path.
715 716 """
716 717 if not allargs:
717 718 raise error.ProgrammingError('only allargs=True is currently supported')
718 719
719 720 if localversion is None:
720 721 raise error.ProgrammingError('must set localversion argument value')
721 722
722 723 def cachekeyfn(repo, proto, cacher, **args):
723 724 spec = COMMANDS[command]
724 725
725 726 # Commands that mutate the repo can not be cached.
726 727 if spec.permission == 'push':
727 728 return None
728 729
729 730 # TODO config option to disable caching.
730 731
731 732 # Our key derivation strategy is to construct a data structure
732 733 # holding everything that could influence cacheability and to hash
733 734 # the CBOR representation of that. Using CBOR seems like it might
734 735 # be overkill. However, simpler hashing mechanisms are prone to
735 736 # duplicate input issues. e.g. if you just concatenate two values,
736 737 # "foo"+"bar" is identical to "fo"+"obar". Using CBOR provides
737 738 # "padding" between values and prevents these problems.
738 739
739 740 # Seed the hash with various data.
740 741 state = {
741 742 # To invalidate all cache keys.
742 743 b'globalversion': GLOBAL_CACHE_VERSION,
743 744 # More granular cache key invalidation.
744 745 b'localversion': localversion,
745 746 # Cache keys are segmented by command.
746 747 b'command': command,
747 748 # Throw in the media type and API version strings so changes
748 749 # to exchange semantics invalid cache.
749 750 b'mediatype': FRAMINGTYPE,
750 751 b'version': HTTP_WIREPROTO_V2,
751 752 # So same requests for different repos don't share cache keys.
752 753 b'repo': repo.root,
753 754 }
754 755
755 756 # The arguments passed to us will have already been normalized.
756 757 # Default values will be set, etc. This is important because it
757 758 # means that it doesn't matter if clients send an explicit argument
758 759 # or rely on the default value: it will all normalize to the same
759 760 # set of arguments on the server and therefore the same cache key.
760 761 #
761 762 # Arguments by their very nature must support being encoded to CBOR.
762 763 # And the CBOR encoder is deterministic. So we hash the arguments
763 764 # by feeding the CBOR of their representation into the hasher.
764 765 if allargs:
765 766 state[b'args'] = pycompat.byteskwargs(args)
766 767
767 768 cacher.adjustcachekeystate(state)
768 769
769 770 hasher = hashlib.sha1()
770 771 for chunk in cborutil.streamencode(state):
771 772 hasher.update(chunk)
772 773
773 774 return pycompat.sysbytes(hasher.hexdigest())
774 775
775 776 return cachekeyfn
776 777
777 778 def makeresponsecacher(repo, proto, command, args, objencoderfn,
778 779 redirecttargets, redirecthashes):
779 780 """Construct a cacher for a cacheable command.
780 781
781 782 Returns an ``iwireprotocolcommandcacher`` instance.
782 783
783 784 Extensions can monkeypatch this function to provide custom caching
784 785 backends.
785 786 """
786 787 return None
787 788
788 789 def resolvenodes(repo, revisions):
789 790 """Resolve nodes from a revisions specifier data structure."""
790 791 cl = repo.changelog
791 792 clhasnode = cl.hasnode
792 793
793 794 seen = set()
794 795 nodes = []
795 796
796 797 if not isinstance(revisions, list):
797 798 raise error.WireprotoCommandError('revisions must be defined as an '
798 799 'array')
799 800
800 801 for spec in revisions:
801 802 if b'type' not in spec:
802 803 raise error.WireprotoCommandError(
803 804 'type key not present in revision specifier')
804 805
805 806 typ = spec[b'type']
806 807
807 808 if typ == b'changesetexplicit':
808 809 if b'nodes' not in spec:
809 810 raise error.WireprotoCommandError(
810 811 'nodes key not present in changesetexplicit revision '
811 812 'specifier')
812 813
813 814 for node in spec[b'nodes']:
814 815 if node not in seen:
815 816 nodes.append(node)
816 817 seen.add(node)
817 818
818 819 elif typ == b'changesetexplicitdepth':
819 820 for key in (b'nodes', b'depth'):
820 821 if key not in spec:
821 822 raise error.WireprotoCommandError(
822 823 '%s key not present in changesetexplicitdepth revision '
823 824 'specifier', (key,))
824 825
825 826 for rev in repo.revs(b'ancestors(%ln, %s)', spec[b'nodes'],
826 827 spec[b'depth'] - 1):
827 828 node = cl.node(rev)
828 829
829 830 if node not in seen:
830 831 nodes.append(node)
831 832 seen.add(node)
832 833
833 834 elif typ == b'changesetdagrange':
834 835 for key in (b'roots', b'heads'):
835 836 if key not in spec:
836 837 raise error.WireprotoCommandError(
837 838 '%s key not present in changesetdagrange revision '
838 839 'specifier', (key,))
839 840
840 841 if not spec[b'heads']:
841 842 raise error.WireprotoCommandError(
842 843 'heads key in changesetdagrange cannot be empty')
843 844
844 845 if spec[b'roots']:
845 846 common = [n for n in spec[b'roots'] if clhasnode(n)]
846 847 else:
847 848 common = [nullid]
848 849
849 850 for n in discovery.outgoing(repo, common, spec[b'heads']).missing:
850 851 if n not in seen:
851 852 nodes.append(n)
852 853 seen.add(n)
853 854
854 855 else:
855 856 raise error.WireprotoCommandError(
856 857 'unknown revision specifier type: %s', (typ,))
857 858
858 859 return nodes
859 860
860 861 @wireprotocommand('branchmap', permission='pull')
861 862 def branchmapv2(repo, proto):
862 863 yield {encoding.fromlocal(k): v
863 864 for k, v in repo.branchmap().iteritems()}
864 865
865 866 @wireprotocommand('capabilities', permission='pull')
866 867 def capabilitiesv2(repo, proto):
867 868 yield _capabilitiesv2(repo, proto)
868 869
869 870 @wireprotocommand(
870 871 'changesetdata',
871 872 args={
872 873 'revisions': {
873 874 'type': 'list',
874 875 'example': [{
875 876 b'type': b'changesetexplicit',
876 877 b'nodes': [b'abcdef...'],
877 878 }],
878 879 },
879 880 'fields': {
880 881 'type': 'set',
881 882 'default': set,
882 883 'example': {b'parents', b'revision'},
883 884 'validvalues': {b'bookmarks', b'parents', b'phase', b'revision'},
884 885 },
885 886 },
886 887 permission='pull')
887 888 def changesetdata(repo, proto, revisions, fields):
888 889 # TODO look for unknown fields and abort when they can't be serviced.
889 890 # This could probably be validated by dispatcher using validvalues.
890 891
891 892 cl = repo.changelog
892 893 outgoing = resolvenodes(repo, revisions)
893 894 publishing = repo.publishing()
894 895
895 896 if outgoing:
896 897 repo.hook('preoutgoing', throw=True, source='serve')
897 898
898 899 yield {
899 900 b'totalitems': len(outgoing),
900 901 }
901 902
902 903 # The phases of nodes already transferred to the client may have changed
903 904 # since the client last requested data. We send phase-only records
904 905 # for these revisions, if requested.
905 906 # TODO actually do this. We'll probably want to emit phase heads
906 907 # in the ancestry set of the outgoing revisions. This will ensure
907 908 # that phase updates within that set are seen.
908 909 if b'phase' in fields:
909 910 pass
910 911
911 912 nodebookmarks = {}
912 913 for mark, node in repo._bookmarks.items():
913 914 nodebookmarks.setdefault(node, set()).add(mark)
914 915
915 916 # It is already topologically sorted by revision number.
916 917 for node in outgoing:
917 918 d = {
918 919 b'node': node,
919 920 }
920 921
921 922 if b'parents' in fields:
922 923 d[b'parents'] = cl.parents(node)
923 924
924 925 if b'phase' in fields:
925 926 if publishing:
926 927 d[b'phase'] = b'public'
927 928 else:
928 929 ctx = repo[node]
929 930 d[b'phase'] = ctx.phasestr()
930 931
931 932 if b'bookmarks' in fields and node in nodebookmarks:
932 933 d[b'bookmarks'] = sorted(nodebookmarks[node])
933 934 del nodebookmarks[node]
934 935
935 936 followingmeta = []
936 937 followingdata = []
937 938
938 939 if b'revision' in fields:
939 940 revisiondata = cl.revision(node, raw=True)
940 941 followingmeta.append((b'revision', len(revisiondata)))
941 942 followingdata.append(revisiondata)
942 943
943 944 # TODO make it possible for extensions to wrap a function or register
944 945 # a handler to service custom fields.
945 946
946 947 if followingmeta:
947 948 d[b'fieldsfollowing'] = followingmeta
948 949
949 950 yield d
950 951
951 952 for extra in followingdata:
952 953 yield extra
953 954
954 955 # If requested, send bookmarks from nodes that didn't have revision
955 956 # data sent so receiver is aware of any bookmark updates.
956 957 if b'bookmarks' in fields:
957 958 for node, marks in sorted(nodebookmarks.iteritems()):
958 959 yield {
959 960 b'node': node,
960 961 b'bookmarks': sorted(marks),
961 962 }
962 963
963 964 class FileAccessError(Exception):
964 965 """Represents an error accessing a specific file."""
965 966
966 967 def __init__(self, path, msg, args):
967 968 self.path = path
968 969 self.msg = msg
969 970 self.args = args
970 971
971 972 def getfilestore(repo, proto, path):
972 973 """Obtain a file storage object for use with wire protocol.
973 974
974 975 Exists as a standalone function so extensions can monkeypatch to add
975 976 access control.
976 977 """
977 978 # This seems to work even if the file doesn't exist. So catch
978 979 # "empty" files and return an error.
979 980 fl = repo.file(path)
980 981
981 982 if not len(fl):
982 983 raise FileAccessError(path, 'unknown file: %s', (path,))
983 984
984 985 return fl
985 986
986 987 def emitfilerevisions(repo, path, revisions, linknodes, fields):
987 988 for revision in revisions:
988 989 d = {
989 990 b'node': revision.node,
990 991 }
991 992
992 993 if b'parents' in fields:
993 994 d[b'parents'] = [revision.p1node, revision.p2node]
994 995
995 996 if b'linknode' in fields:
996 997 d[b'linknode'] = linknodes[revision.node]
997 998
998 999 followingmeta = []
999 1000 followingdata = []
1000 1001
1001 1002 if b'revision' in fields:
1002 1003 if revision.revision is not None:
1003 1004 followingmeta.append((b'revision', len(revision.revision)))
1004 1005 followingdata.append(revision.revision)
1005 1006 else:
1006 1007 d[b'deltabasenode'] = revision.basenode
1007 1008 followingmeta.append((b'delta', len(revision.delta)))
1008 1009 followingdata.append(revision.delta)
1009 1010
1010 1011 if followingmeta:
1011 1012 d[b'fieldsfollowing'] = followingmeta
1012 1013
1013 1014 yield d
1014 1015
1015 1016 for extra in followingdata:
1016 1017 yield extra
1017 1018
1018 1019 def makefilematcher(repo, pathfilter):
1019 1020 """Construct a matcher from a path filter dict."""
1020 1021
1021 1022 # Validate values.
1022 1023 if pathfilter:
1023 1024 for key in (b'include', b'exclude'):
1024 1025 for pattern in pathfilter.get(key, []):
1025 1026 if not pattern.startswith((b'path:', b'rootfilesin:')):
1026 1027 raise error.WireprotoCommandError(
1027 1028 '%s pattern must begin with `path:` or `rootfilesin:`; '
1028 1029 'got %s', (key, pattern))
1029 1030
1030 1031 if pathfilter:
1031 1032 matcher = matchmod.match(repo.root, b'',
1032 1033 include=pathfilter.get(b'include', []),
1033 1034 exclude=pathfilter.get(b'exclude', []))
1034 1035 else:
1035 1036 matcher = matchmod.match(repo.root, b'')
1036 1037
1037 1038 # Requested patterns could include files not in the local store. So
1038 1039 # filter those out.
1039 1040 return repo.narrowmatch(matcher)
1040 1041
1041 1042 @wireprotocommand(
1042 1043 'filedata',
1043 1044 args={
1044 1045 'haveparents': {
1045 1046 'type': 'bool',
1046 1047 'default': lambda: False,
1047 1048 'example': True,
1048 1049 },
1049 1050 'nodes': {
1050 1051 'type': 'list',
1051 1052 'example': [b'0123456...'],
1052 1053 },
1053 1054 'fields': {
1054 1055 'type': 'set',
1055 1056 'default': set,
1056 1057 'example': {b'parents', b'revision'},
1057 1058 'validvalues': {b'parents', b'revision', b'linknode'},
1058 1059 },
1059 1060 'path': {
1060 1061 'type': 'bytes',
1061 1062 'example': b'foo.txt',
1062 1063 }
1063 1064 },
1064 1065 permission='pull',
1065 1066 # TODO censoring a file revision won't invalidate the cache.
1066 1067 # Figure out a way to take censoring into account when deriving
1067 1068 # the cache key.
1068 1069 cachekeyfn=makecommandcachekeyfn('filedata', 1, allargs=True))
1069 1070 def filedata(repo, proto, haveparents, nodes, fields, path):
1070 1071 # TODO this API allows access to file revisions that are attached to
1071 1072 # secret changesets. filesdata does not have this problem. Maybe this
1072 1073 # API should be deleted?
1073 1074
1074 1075 try:
1075 1076 # Extensions may wish to access the protocol handler.
1076 1077 store = getfilestore(repo, proto, path)
1077 1078 except FileAccessError as e:
1078 1079 raise error.WireprotoCommandError(e.msg, e.args)
1079 1080
1080 1081 clnode = repo.changelog.node
1081 1082 linknodes = {}
1082 1083
1083 1084 # Validate requested nodes.
1084 1085 for node in nodes:
1085 1086 try:
1086 1087 store.rev(node)
1087 1088 except error.LookupError:
1088 1089 raise error.WireprotoCommandError('unknown file node: %s',
1089 1090 (hex(node),))
1090 1091
1091 1092 # TODO by creating the filectx against a specific file revision
1092 1093 # instead of changeset, linkrev() is always used. This is wrong for
1093 1094 # cases where linkrev() may refer to a hidden changeset. But since this
1094 1095 # API doesn't know anything about changesets, we're not sure how to
1095 1096 # disambiguate the linknode. Perhaps we should delete this API?
1096 1097 fctx = repo.filectx(path, fileid=node)
1097 1098 linknodes[node] = clnode(fctx.introrev())
1098 1099
1099 1100 revisions = store.emitrevisions(nodes,
1100 1101 revisiondata=b'revision' in fields,
1101 1102 assumehaveparentrevisions=haveparents)
1102 1103
1103 1104 yield {
1104 1105 b'totalitems': len(nodes),
1105 1106 }
1106 1107
1107 1108 for o in emitfilerevisions(repo, path, revisions, linknodes, fields):
1108 1109 yield o
1109 1110
1110 1111 def filesdatacapabilities(repo, proto):
1111 1112 batchsize = repo.ui.configint(
1112 1113 b'experimental', b'server.filesdata.recommended-batch-size')
1113 1114 return {
1114 1115 b'recommendedbatchsize': batchsize,
1115 1116 }
1116 1117
1117 1118 @wireprotocommand(
1118 1119 'filesdata',
1119 1120 args={
1120 1121 'haveparents': {
1121 1122 'type': 'bool',
1122 1123 'default': lambda: False,
1123 1124 'example': True,
1124 1125 },
1125 1126 'fields': {
1126 1127 'type': 'set',
1127 1128 'default': set,
1128 1129 'example': {b'parents', b'revision'},
1129 1130 'validvalues': {b'firstchangeset', b'linknode', b'parents',
1130 1131 b'revision'},
1131 1132 },
1132 1133 'pathfilter': {
1133 1134 'type': 'dict',
1134 1135 'default': lambda: None,
1135 1136 'example': {b'include': [b'path:tests']},
1136 1137 },
1137 1138 'revisions': {
1138 1139 'type': 'list',
1139 1140 'example': [{
1140 1141 b'type': b'changesetexplicit',
1141 1142 b'nodes': [b'abcdef...'],
1142 1143 }],
1143 1144 },
1144 1145 },
1145 1146 permission='pull',
1146 1147 # TODO censoring a file revision won't invalidate the cache.
1147 1148 # Figure out a way to take censoring into account when deriving
1148 1149 # the cache key.
1149 1150 cachekeyfn=makecommandcachekeyfn('filesdata', 1, allargs=True),
1150 1151 extracapabilitiesfn=filesdatacapabilities)
1151 1152 def filesdata(repo, proto, haveparents, fields, pathfilter, revisions):
1152 1153 # TODO This should operate on a repo that exposes obsolete changesets. There
1153 1154 # is a race between a client making a push that obsoletes a changeset and
1154 1155 # another client fetching files data for that changeset. If a client has a
1155 1156 # changeset, it should probably be allowed to access files data for that
1156 1157 # changeset.
1157 1158
1158 1159 outgoing = resolvenodes(repo, revisions)
1159 1160 filematcher = makefilematcher(repo, pathfilter)
1160 1161
1161 1162 # path -> {fnode: linknode}
1162 1163 fnodes = collections.defaultdict(dict)
1163 1164
1164 1165 # We collect the set of relevant file revisions by iterating the changeset
1165 1166 # revisions and either walking the set of files recorded in the changeset
1166 1167 # or by walking the manifest at that revision. There is probably room for a
1167 1168 # storage-level API to request this data, as it can be expensive to compute
1168 1169 # and would benefit from caching or alternate storage from what revlogs
1169 1170 # provide.
1170 1171 for node in outgoing:
1171 1172 ctx = repo[node]
1172 1173 mctx = ctx.manifestctx()
1173 1174 md = mctx.read()
1174 1175
1175 1176 if haveparents:
1176 1177 checkpaths = ctx.files()
1177 1178 else:
1178 1179 checkpaths = md.keys()
1179 1180
1180 1181 for path in checkpaths:
1181 1182 fnode = md[path]
1182 1183
1183 1184 if path in fnodes and fnode in fnodes[path]:
1184 1185 continue
1185 1186
1186 1187 if not filematcher(path):
1187 1188 continue
1188 1189
1189 1190 fnodes[path].setdefault(fnode, node)
1190 1191
1191 1192 yield {
1192 1193 b'totalpaths': len(fnodes),
1193 1194 b'totalitems': sum(len(v) for v in fnodes.values())
1194 1195 }
1195 1196
1196 1197 for path, filenodes in sorted(fnodes.items()):
1197 1198 try:
1198 1199 store = getfilestore(repo, proto, path)
1199 1200 except FileAccessError as e:
1200 1201 raise error.WireprotoCommandError(e.msg, e.args)
1201 1202
1202 1203 yield {
1203 1204 b'path': path,
1204 1205 b'totalitems': len(filenodes),
1205 1206 }
1206 1207
1207 1208 revisions = store.emitrevisions(filenodes.keys(),
1208 1209 revisiondata=b'revision' in fields,
1209 1210 assumehaveparentrevisions=haveparents)
1210 1211
1211 1212 for o in emitfilerevisions(repo, path, revisions, filenodes, fields):
1212 1213 yield o
1213 1214
1214 1215 @wireprotocommand(
1215 1216 'heads',
1216 1217 args={
1217 1218 'publiconly': {
1218 1219 'type': 'bool',
1219 1220 'default': lambda: False,
1220 1221 'example': False,
1221 1222 },
1222 1223 },
1223 1224 permission='pull')
1224 1225 def headsv2(repo, proto, publiconly):
1225 1226 if publiconly:
1226 1227 repo = repo.filtered('immutable')
1227 1228
1228 1229 yield repo.heads()
1229 1230
1230 1231 @wireprotocommand(
1231 1232 'known',
1232 1233 args={
1233 1234 'nodes': {
1234 1235 'type': 'list',
1235 1236 'default': list,
1236 1237 'example': [b'deadbeef'],
1237 1238 },
1238 1239 },
1239 1240 permission='pull')
1240 1241 def knownv2(repo, proto, nodes):
1241 1242 result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
1242 1243 yield result
1243 1244
1244 1245 @wireprotocommand(
1245 1246 'listkeys',
1246 1247 args={
1247 1248 'namespace': {
1248 1249 'type': 'bytes',
1249 1250 'example': b'ns',
1250 1251 },
1251 1252 },
1252 1253 permission='pull')
1253 1254 def listkeysv2(repo, proto, namespace):
1254 1255 keys = repo.listkeys(encoding.tolocal(namespace))
1255 1256 keys = {encoding.fromlocal(k): encoding.fromlocal(v)
1256 1257 for k, v in keys.iteritems()}
1257 1258
1258 1259 yield keys
1259 1260
1260 1261 @wireprotocommand(
1261 1262 'lookup',
1262 1263 args={
1263 1264 'key': {
1264 1265 'type': 'bytes',
1265 1266 'example': b'foo',
1266 1267 },
1267 1268 },
1268 1269 permission='pull')
1269 1270 def lookupv2(repo, proto, key):
1270 1271 key = encoding.tolocal(key)
1271 1272
1272 1273 # TODO handle exception.
1273 1274 node = repo.lookup(key)
1274 1275
1275 1276 yield node
1276 1277
1277 1278 def manifestdatacapabilities(repo, proto):
1278 1279 batchsize = repo.ui.configint(
1279 1280 b'experimental', b'server.manifestdata.recommended-batch-size')
1280 1281
1281 1282 return {
1282 1283 b'recommendedbatchsize': batchsize,
1283 1284 }
1284 1285
1285 1286 @wireprotocommand(
1286 1287 'manifestdata',
1287 1288 args={
1288 1289 'nodes': {
1289 1290 'type': 'list',
1290 1291 'example': [b'0123456...'],
1291 1292 },
1292 1293 'haveparents': {
1293 1294 'type': 'bool',
1294 1295 'default': lambda: False,
1295 1296 'example': True,
1296 1297 },
1297 1298 'fields': {
1298 1299 'type': 'set',
1299 1300 'default': set,
1300 1301 'example': {b'parents', b'revision'},
1301 1302 'validvalues': {b'parents', b'revision'},
1302 1303 },
1303 1304 'tree': {
1304 1305 'type': 'bytes',
1305 1306 'example': b'',
1306 1307 },
1307 1308 },
1308 1309 permission='pull',
1309 1310 cachekeyfn=makecommandcachekeyfn('manifestdata', 1, allargs=True),
1310 1311 extracapabilitiesfn=manifestdatacapabilities)
1311 1312 def manifestdata(repo, proto, haveparents, nodes, fields, tree):
1312 1313 store = repo.manifestlog.getstorage(tree)
1313 1314
1314 1315 # Validate the node is known and abort on unknown revisions.
1315 1316 for node in nodes:
1316 1317 try:
1317 1318 store.rev(node)
1318 1319 except error.LookupError:
1319 1320 raise error.WireprotoCommandError(
1320 1321 'unknown node: %s', (node,))
1321 1322
1322 1323 revisions = store.emitrevisions(nodes,
1323 1324 revisiondata=b'revision' in fields,
1324 1325 assumehaveparentrevisions=haveparents)
1325 1326
1326 1327 yield {
1327 1328 b'totalitems': len(nodes),
1328 1329 }
1329 1330
1330 1331 for revision in revisions:
1331 1332 d = {
1332 1333 b'node': revision.node,
1333 1334 }
1334 1335
1335 1336 if b'parents' in fields:
1336 1337 d[b'parents'] = [revision.p1node, revision.p2node]
1337 1338
1338 1339 followingmeta = []
1339 1340 followingdata = []
1340 1341
1341 1342 if b'revision' in fields:
1342 1343 if revision.revision is not None:
1343 1344 followingmeta.append((b'revision', len(revision.revision)))
1344 1345 followingdata.append(revision.revision)
1345 1346 else:
1346 1347 d[b'deltabasenode'] = revision.basenode
1347 1348 followingmeta.append((b'delta', len(revision.delta)))
1348 1349 followingdata.append(revision.delta)
1349 1350
1350 1351 if followingmeta:
1351 1352 d[b'fieldsfollowing'] = followingmeta
1352 1353
1353 1354 yield d
1354 1355
1355 1356 for extra in followingdata:
1356 1357 yield extra
1357 1358
1358 1359 @wireprotocommand(
1359 1360 'pushkey',
1360 1361 args={
1361 1362 'namespace': {
1362 1363 'type': 'bytes',
1363 1364 'example': b'ns',
1364 1365 },
1365 1366 'key': {
1366 1367 'type': 'bytes',
1367 1368 'example': b'key',
1368 1369 },
1369 1370 'old': {
1370 1371 'type': 'bytes',
1371 1372 'example': b'old',
1372 1373 },
1373 1374 'new': {
1374 1375 'type': 'bytes',
1375 1376 'example': 'new',
1376 1377 },
1377 1378 },
1378 1379 permission='push')
1379 1380 def pushkeyv2(repo, proto, namespace, key, old, new):
1380 1381 # TODO handle ui output redirection
1381 1382 yield repo.pushkey(encoding.tolocal(namespace),
1382 1383 encoding.tolocal(key),
1383 1384 encoding.tolocal(old),
1384 1385 encoding.tolocal(new))
1385 1386
1386 1387
1387 1388 @wireprotocommand(
1388 1389 'rawstorefiledata',
1389 1390 args={
1390 1391 'files': {
1391 1392 'type': 'list',
1392 1393 'example': [b'changelog', b'manifestlog'],
1393 1394 },
1394 1395 'pathfilter': {
1395 1396 'type': 'list',
1396 1397 'default': lambda: None,
1397 1398 'example': {b'include': [b'path:tests']},
1398 1399 },
1399 1400 },
1400 1401 permission='pull')
1401 1402 def rawstorefiledata(repo, proto, files, pathfilter):
1402 1403 if not streamclone.allowservergeneration(repo):
1403 1404 raise error.WireprotoCommandError(b'stream clone is disabled')
1404 1405
1405 1406 # TODO support dynamically advertising what store files "sets" are
1406 1407 # available. For now, we support changelog, manifestlog, and files.
1407 1408 files = set(files)
1408 1409 allowedfiles = {b'changelog', b'manifestlog'}
1409 1410
1410 1411 unsupported = files - allowedfiles
1411 1412 if unsupported:
1412 1413 raise error.WireprotoCommandError(b'unknown file type: %s',
1413 1414 (b', '.join(sorted(unsupported)),))
1414 1415
1415 1416 with repo.lock():
1416 1417 topfiles = list(repo.store.topfiles())
1417 1418
1418 1419 sendfiles = []
1419 1420 totalsize = 0
1420 1421
1421 1422 # TODO this is a bunch of storage layer interface abstractions because
1422 1423 # it assumes revlogs.
1423 1424 for name, encodedname, size in topfiles:
1424 1425 if b'changelog' in files and name.startswith(b'00changelog'):
1425 1426 pass
1426 1427 elif b'manifestlog' in files and name.startswith(b'00manifest'):
1427 1428 pass
1428 1429 else:
1429 1430 continue
1430 1431
1431 1432 sendfiles.append((b'store', name, size))
1432 1433 totalsize += size
1433 1434
1434 1435 yield {
1435 1436 b'filecount': len(sendfiles),
1436 1437 b'totalsize': totalsize,
1437 1438 }
1438 1439
1439 1440 for location, name, size in sendfiles:
1440 1441 yield {
1441 1442 b'location': location,
1442 1443 b'path': name,
1443 1444 b'size': size,
1444 1445 }
1445 1446
1446 1447 # We have to use a closure for this to ensure the context manager is
1447 1448 # closed only after sending the final chunk.
1448 1449 def getfiledata():
1449 1450 with repo.svfs(name, 'rb', auditpath=False) as fh:
1450 1451 for chunk in util.filechunkiter(fh, limit=size):
1451 1452 yield chunk
1452 1453
1453 1454 yield wireprototypes.indefinitebytestringresponse(
1454 1455 getfiledata())
@@ -1,112 +1,115
1 1 from __future__ import absolute_import, print_function
2 2
3 3 import sys
4 4
5 5 from mercurial import (
6 6 error,
7 7 pycompat,
8 8 ui as uimod,
9 9 util,
10 10 wireprototypes,
11 11 wireprotov1peer,
12 12 wireprotov1server,
13 13 )
14 14 from mercurial.utils import (
15 15 stringutil,
16 16 )
17 17 stringio = util.stringio
18 18
19 19 class proto(object):
20 20 def __init__(self, args):
21 21 self.args = args
22 22 self.name = 'dummyproto'
23 23
24 24 def getargs(self, spec):
25 25 args = self.args
26 26 args.setdefault(b'*', {})
27 27 names = spec.split()
28 28 return [args[n] for n in names]
29 29
30 30 def checkperm(self, perm):
31 31 pass
32 32
33 33 wireprototypes.TRANSPORTS['dummyproto'] = {
34 34 'transport': 'dummy',
35 35 'version': 1,
36 36 }
37 37
38 38 class clientpeer(wireprotov1peer.wirepeer):
39 39 def __init__(self, serverrepo, ui):
40 40 self.serverrepo = serverrepo
41 41 self.ui = ui
42 42
43 43 def url(self):
44 44 return b'test'
45 45
46 46 def local(self):
47 47 return None
48 48
49 49 def peer(self):
50 50 return self
51 51
52 52 def canpush(self):
53 53 return True
54 54
55 55 def close(self):
56 56 pass
57 57
58 58 def capabilities(self):
59 59 return [b'batch']
60 60
61 61 def _call(self, cmd, **args):
62 62 args = pycompat.byteskwargs(args)
63 63 res = wireprotov1server.dispatch(self.serverrepo, proto(args), cmd)
64 64 if isinstance(res, wireprototypes.bytesresponse):
65 65 return res.data
66 66 elif isinstance(res, bytes):
67 67 return res
68 68 else:
69 69 raise error.Abort('dummy client does not support response type')
70 70
71 71 def _callstream(self, cmd, **args):
72 72 return stringio(self._call(cmd, **args))
73 73
74 74 @wireprotov1peer.batchable
75 75 def greet(self, name):
76 76 f = wireprotov1peer.future()
77 77 yield {b'name': mangle(name)}, f
78 78 yield unmangle(f.value)
79 79
80 80 class serverrepo(object):
81 def __init__(self, ui):
82 self.ui = ui
83
81 84 def greet(self, name):
82 85 return b"Hello, " + name
83 86
84 87 def filtered(self, name):
85 88 return self
86 89
87 90 def mangle(s):
88 91 return b''.join(pycompat.bytechr(ord(c) + 1) for c in pycompat.bytestr(s))
89 92 def unmangle(s):
90 93 return b''.join(pycompat.bytechr(ord(c) - 1) for c in pycompat.bytestr(s))
91 94
92 95 def greet(repo, proto, name):
93 96 return mangle(repo.greet(unmangle(name)))
94 97
95 98 wireprotov1server.commands[b'greet'] = (greet, b'name')
96 99
97 srv = serverrepo()
100 srv = serverrepo(uimod.ui())
98 101 clt = clientpeer(srv, uimod.ui())
99 102
100 103 def printb(data, end=b'\n'):
101 104 out = getattr(sys.stdout, 'buffer', sys.stdout)
102 105 out.write(data + end)
103 106 out.flush()
104 107
105 108 printb(clt.greet(b"Foobar"))
106 109
107 110 with clt.commandexecutor() as e:
108 111 fgreet1 = e.callcommand(b'greet', {b'name': b'Fo, =;:<o'})
109 112 fgreet2 = e.callcommand(b'greet', {b'name': b'Bar'})
110 113
111 114 printb(stringutil.pprint([f.result() for f in (fgreet1, fgreet2)],
112 115 bprefix=True))
General Comments 0
You need to be logged in to leave comments. Login now