##// 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 # configitems.py - centralized declaration of configuration option
1 # configitems.py - centralized declaration of configuration option
2 #
2 #
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import functools
10 import functools
11 import re
11 import re
12
12
13 from . import (
13 from . import (
14 encoding,
14 encoding,
15 error,
15 error,
16 )
16 )
17
17
18 def loadconfigtable(ui, extname, configtable):
18 def loadconfigtable(ui, extname, configtable):
19 """update config item known to the ui with the extension ones"""
19 """update config item known to the ui with the extension ones"""
20 for section, items in sorted(configtable.items()):
20 for section, items in sorted(configtable.items()):
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
22 knownkeys = set(knownitems)
22 knownkeys = set(knownitems)
23 newkeys = set(items)
23 newkeys = set(items)
24 for key in sorted(knownkeys & newkeys):
24 for key in sorted(knownkeys & newkeys):
25 msg = "extension '%s' overwrite config item '%s.%s'"
25 msg = "extension '%s' overwrite config item '%s.%s'"
26 msg %= (extname, section, key)
26 msg %= (extname, section, key)
27 ui.develwarn(msg, config='warn-config')
27 ui.develwarn(msg, config='warn-config')
28
28
29 knownitems.update(items)
29 knownitems.update(items)
30
30
31 class configitem(object):
31 class configitem(object):
32 """represent a known config item
32 """represent a known config item
33
33
34 :section: the official config section where to find this item,
34 :section: the official config section where to find this item,
35 :name: the official name within the section,
35 :name: the official name within the section,
36 :default: default value for this item,
36 :default: default value for this item,
37 :alias: optional list of tuples as alternatives,
37 :alias: optional list of tuples as alternatives,
38 :generic: this is a generic definition, match name using regular expression.
38 :generic: this is a generic definition, match name using regular expression.
39 """
39 """
40
40
41 def __init__(self, section, name, default=None, alias=(),
41 def __init__(self, section, name, default=None, alias=(),
42 generic=False, priority=0):
42 generic=False, priority=0):
43 self.section = section
43 self.section = section
44 self.name = name
44 self.name = name
45 self.default = default
45 self.default = default
46 self.alias = list(alias)
46 self.alias = list(alias)
47 self.generic = generic
47 self.generic = generic
48 self.priority = priority
48 self.priority = priority
49 self._re = None
49 self._re = None
50 if generic:
50 if generic:
51 self._re = re.compile(self.name)
51 self._re = re.compile(self.name)
52
52
53 class itemregister(dict):
53 class itemregister(dict):
54 """A specialized dictionary that can handle wild-card selection"""
54 """A specialized dictionary that can handle wild-card selection"""
55
55
56 def __init__(self):
56 def __init__(self):
57 super(itemregister, self).__init__()
57 super(itemregister, self).__init__()
58 self._generics = set()
58 self._generics = set()
59
59
60 def update(self, other):
60 def update(self, other):
61 super(itemregister, self).update(other)
61 super(itemregister, self).update(other)
62 self._generics.update(other._generics)
62 self._generics.update(other._generics)
63
63
64 def __setitem__(self, key, item):
64 def __setitem__(self, key, item):
65 super(itemregister, self).__setitem__(key, item)
65 super(itemregister, self).__setitem__(key, item)
66 if item.generic:
66 if item.generic:
67 self._generics.add(item)
67 self._generics.add(item)
68
68
69 def get(self, key):
69 def get(self, key):
70 baseitem = super(itemregister, self).get(key)
70 baseitem = super(itemregister, self).get(key)
71 if baseitem is not None and not baseitem.generic:
71 if baseitem is not None and not baseitem.generic:
72 return baseitem
72 return baseitem
73
73
74 # search for a matching generic item
74 # search for a matching generic item
75 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
75 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
76 for item in generics:
76 for item in generics:
77 # we use 'match' instead of 'search' to make the matching simpler
77 # we use 'match' instead of 'search' to make the matching simpler
78 # for people unfamiliar with regular expression. Having the match
78 # for people unfamiliar with regular expression. Having the match
79 # rooted to the start of the string will produce less surprising
79 # rooted to the start of the string will produce less surprising
80 # result for user writing simple regex for sub-attribute.
80 # result for user writing simple regex for sub-attribute.
81 #
81 #
82 # For example using "color\..*" match produces an unsurprising
82 # For example using "color\..*" match produces an unsurprising
83 # result, while using search could suddenly match apparently
83 # result, while using search could suddenly match apparently
84 # unrelated configuration that happens to contains "color."
84 # unrelated configuration that happens to contains "color."
85 # anywhere. This is a tradeoff where we favor requiring ".*" on
85 # anywhere. This is a tradeoff where we favor requiring ".*" on
86 # some match to avoid the need to prefix most pattern with "^".
86 # some match to avoid the need to prefix most pattern with "^".
87 # The "^" seems more error prone.
87 # The "^" seems more error prone.
88 if item._re.match(key):
88 if item._re.match(key):
89 return item
89 return item
90
90
91 return None
91 return None
92
92
93 coreitems = {}
93 coreitems = {}
94
94
95 def _register(configtable, *args, **kwargs):
95 def _register(configtable, *args, **kwargs):
96 item = configitem(*args, **kwargs)
96 item = configitem(*args, **kwargs)
97 section = configtable.setdefault(item.section, itemregister())
97 section = configtable.setdefault(item.section, itemregister())
98 if item.name in section:
98 if item.name in section:
99 msg = "duplicated config item registration for '%s.%s'"
99 msg = "duplicated config item registration for '%s.%s'"
100 raise error.ProgrammingError(msg % (item.section, item.name))
100 raise error.ProgrammingError(msg % (item.section, item.name))
101 section[item.name] = item
101 section[item.name] = item
102
102
103 # special value for case where the default is derived from other values
103 # special value for case where the default is derived from other values
104 dynamicdefault = object()
104 dynamicdefault = object()
105
105
106 # Registering actual config items
106 # Registering actual config items
107
107
108 def getitemregister(configtable):
108 def getitemregister(configtable):
109 f = functools.partial(_register, configtable)
109 f = functools.partial(_register, configtable)
110 # export pseudo enum as configitem.*
110 # export pseudo enum as configitem.*
111 f.dynamicdefault = dynamicdefault
111 f.dynamicdefault = dynamicdefault
112 return f
112 return f
113
113
114 coreconfigitem = getitemregister(coreitems)
114 coreconfigitem = getitemregister(coreitems)
115
115
116 def _registerdiffopts(section, configprefix=''):
116 def _registerdiffopts(section, configprefix=''):
117 coreconfigitem(section, configprefix + 'nodates',
117 coreconfigitem(section, configprefix + 'nodates',
118 default=False,
118 default=False,
119 )
119 )
120 coreconfigitem(section, configprefix + 'showfunc',
120 coreconfigitem(section, configprefix + 'showfunc',
121 default=False,
121 default=False,
122 )
122 )
123 coreconfigitem(section, configprefix + 'unified',
123 coreconfigitem(section, configprefix + 'unified',
124 default=None,
124 default=None,
125 )
125 )
126 coreconfigitem(section, configprefix + 'git',
126 coreconfigitem(section, configprefix + 'git',
127 default=False,
127 default=False,
128 )
128 )
129 coreconfigitem(section, configprefix + 'ignorews',
129 coreconfigitem(section, configprefix + 'ignorews',
130 default=False,
130 default=False,
131 )
131 )
132 coreconfigitem(section, configprefix + 'ignorewsamount',
132 coreconfigitem(section, configprefix + 'ignorewsamount',
133 default=False,
133 default=False,
134 )
134 )
135 coreconfigitem(section, configprefix + 'ignoreblanklines',
135 coreconfigitem(section, configprefix + 'ignoreblanklines',
136 default=False,
136 default=False,
137 )
137 )
138 coreconfigitem(section, configprefix + 'ignorewseol',
138 coreconfigitem(section, configprefix + 'ignorewseol',
139 default=False,
139 default=False,
140 )
140 )
141 coreconfigitem(section, configprefix + 'nobinary',
141 coreconfigitem(section, configprefix + 'nobinary',
142 default=False,
142 default=False,
143 )
143 )
144 coreconfigitem(section, configprefix + 'noprefix',
144 coreconfigitem(section, configprefix + 'noprefix',
145 default=False,
145 default=False,
146 )
146 )
147 coreconfigitem(section, configprefix + 'word-diff',
147 coreconfigitem(section, configprefix + 'word-diff',
148 default=False,
148 default=False,
149 )
149 )
150
150
151 coreconfigitem('alias', '.*',
151 coreconfigitem('alias', '.*',
152 default=dynamicdefault,
152 default=dynamicdefault,
153 generic=True,
153 generic=True,
154 )
154 )
155 coreconfigitem('auth', 'cookiefile',
155 coreconfigitem('auth', 'cookiefile',
156 default=None,
156 default=None,
157 )
157 )
158 _registerdiffopts(section='annotate')
158 _registerdiffopts(section='annotate')
159 # bookmarks.pushing: internal hack for discovery
159 # bookmarks.pushing: internal hack for discovery
160 coreconfigitem('bookmarks', 'pushing',
160 coreconfigitem('bookmarks', 'pushing',
161 default=list,
161 default=list,
162 )
162 )
163 # bundle.mainreporoot: internal hack for bundlerepo
163 # bundle.mainreporoot: internal hack for bundlerepo
164 coreconfigitem('bundle', 'mainreporoot',
164 coreconfigitem('bundle', 'mainreporoot',
165 default='',
165 default='',
166 )
166 )
167 coreconfigitem('censor', 'policy',
167 coreconfigitem('censor', 'policy',
168 default='abort',
168 default='abort',
169 )
169 )
170 coreconfigitem('chgserver', 'idletimeout',
170 coreconfigitem('chgserver', 'idletimeout',
171 default=3600,
171 default=3600,
172 )
172 )
173 coreconfigitem('chgserver', 'skiphash',
173 coreconfigitem('chgserver', 'skiphash',
174 default=False,
174 default=False,
175 )
175 )
176 coreconfigitem('cmdserver', 'log',
176 coreconfigitem('cmdserver', 'log',
177 default=None,
177 default=None,
178 )
178 )
179 coreconfigitem('cmdserver', 'max-log-files',
179 coreconfigitem('cmdserver', 'max-log-files',
180 default=7,
180 default=7,
181 )
181 )
182 coreconfigitem('cmdserver', 'max-log-size',
182 coreconfigitem('cmdserver', 'max-log-size',
183 default='1 MB',
183 default='1 MB',
184 )
184 )
185 coreconfigitem('cmdserver', 'max-repo-cache',
185 coreconfigitem('cmdserver', 'max-repo-cache',
186 default=0,
186 default=0,
187 )
187 )
188 coreconfigitem('cmdserver', 'message-encodings',
188 coreconfigitem('cmdserver', 'message-encodings',
189 default=list,
189 default=list,
190 )
190 )
191 coreconfigitem('cmdserver', 'track-log',
191 coreconfigitem('cmdserver', 'track-log',
192 default=lambda: ['chgserver', 'cmdserver', 'repocache'],
192 default=lambda: ['chgserver', 'cmdserver', 'repocache'],
193 )
193 )
194 coreconfigitem('color', '.*',
194 coreconfigitem('color', '.*',
195 default=None,
195 default=None,
196 generic=True,
196 generic=True,
197 )
197 )
198 coreconfigitem('color', 'mode',
198 coreconfigitem('color', 'mode',
199 default='auto',
199 default='auto',
200 )
200 )
201 coreconfigitem('color', 'pagermode',
201 coreconfigitem('color', 'pagermode',
202 default=dynamicdefault,
202 default=dynamicdefault,
203 )
203 )
204 _registerdiffopts(section='commands', configprefix='commit.interactive.')
204 _registerdiffopts(section='commands', configprefix='commit.interactive.')
205 coreconfigitem('commands', 'grep.all-files',
205 coreconfigitem('commands', 'grep.all-files',
206 default=False,
206 default=False,
207 )
207 )
208 coreconfigitem('commands', 'resolve.confirm',
208 coreconfigitem('commands', 'resolve.confirm',
209 default=False,
209 default=False,
210 )
210 )
211 coreconfigitem('commands', 'resolve.explicit-re-merge',
211 coreconfigitem('commands', 'resolve.explicit-re-merge',
212 default=False,
212 default=False,
213 )
213 )
214 coreconfigitem('commands', 'resolve.mark-check',
214 coreconfigitem('commands', 'resolve.mark-check',
215 default='none',
215 default='none',
216 )
216 )
217 _registerdiffopts(section='commands', configprefix='revert.interactive.')
217 _registerdiffopts(section='commands', configprefix='revert.interactive.')
218 coreconfigitem('commands', 'show.aliasprefix',
218 coreconfigitem('commands', 'show.aliasprefix',
219 default=list,
219 default=list,
220 )
220 )
221 coreconfigitem('commands', 'status.relative',
221 coreconfigitem('commands', 'status.relative',
222 default=False,
222 default=False,
223 )
223 )
224 coreconfigitem('commands', 'status.skipstates',
224 coreconfigitem('commands', 'status.skipstates',
225 default=[],
225 default=[],
226 )
226 )
227 coreconfigitem('commands', 'status.terse',
227 coreconfigitem('commands', 'status.terse',
228 default='',
228 default='',
229 )
229 )
230 coreconfigitem('commands', 'status.verbose',
230 coreconfigitem('commands', 'status.verbose',
231 default=False,
231 default=False,
232 )
232 )
233 coreconfigitem('commands', 'update.check',
233 coreconfigitem('commands', 'update.check',
234 default=None,
234 default=None,
235 )
235 )
236 coreconfigitem('commands', 'update.requiredest',
236 coreconfigitem('commands', 'update.requiredest',
237 default=False,
237 default=False,
238 )
238 )
239 coreconfigitem('committemplate', '.*',
239 coreconfigitem('committemplate', '.*',
240 default=None,
240 default=None,
241 generic=True,
241 generic=True,
242 )
242 )
243 coreconfigitem('convert', 'bzr.saverev',
243 coreconfigitem('convert', 'bzr.saverev',
244 default=True,
244 default=True,
245 )
245 )
246 coreconfigitem('convert', 'cvsps.cache',
246 coreconfigitem('convert', 'cvsps.cache',
247 default=True,
247 default=True,
248 )
248 )
249 coreconfigitem('convert', 'cvsps.fuzz',
249 coreconfigitem('convert', 'cvsps.fuzz',
250 default=60,
250 default=60,
251 )
251 )
252 coreconfigitem('convert', 'cvsps.logencoding',
252 coreconfigitem('convert', 'cvsps.logencoding',
253 default=None,
253 default=None,
254 )
254 )
255 coreconfigitem('convert', 'cvsps.mergefrom',
255 coreconfigitem('convert', 'cvsps.mergefrom',
256 default=None,
256 default=None,
257 )
257 )
258 coreconfigitem('convert', 'cvsps.mergeto',
258 coreconfigitem('convert', 'cvsps.mergeto',
259 default=None,
259 default=None,
260 )
260 )
261 coreconfigitem('convert', 'git.committeractions',
261 coreconfigitem('convert', 'git.committeractions',
262 default=lambda: ['messagedifferent'],
262 default=lambda: ['messagedifferent'],
263 )
263 )
264 coreconfigitem('convert', 'git.extrakeys',
264 coreconfigitem('convert', 'git.extrakeys',
265 default=list,
265 default=list,
266 )
266 )
267 coreconfigitem('convert', 'git.findcopiesharder',
267 coreconfigitem('convert', 'git.findcopiesharder',
268 default=False,
268 default=False,
269 )
269 )
270 coreconfigitem('convert', 'git.remoteprefix',
270 coreconfigitem('convert', 'git.remoteprefix',
271 default='remote',
271 default='remote',
272 )
272 )
273 coreconfigitem('convert', 'git.renamelimit',
273 coreconfigitem('convert', 'git.renamelimit',
274 default=400,
274 default=400,
275 )
275 )
276 coreconfigitem('convert', 'git.saverev',
276 coreconfigitem('convert', 'git.saverev',
277 default=True,
277 default=True,
278 )
278 )
279 coreconfigitem('convert', 'git.similarity',
279 coreconfigitem('convert', 'git.similarity',
280 default=50,
280 default=50,
281 )
281 )
282 coreconfigitem('convert', 'git.skipsubmodules',
282 coreconfigitem('convert', 'git.skipsubmodules',
283 default=False,
283 default=False,
284 )
284 )
285 coreconfigitem('convert', 'hg.clonebranches',
285 coreconfigitem('convert', 'hg.clonebranches',
286 default=False,
286 default=False,
287 )
287 )
288 coreconfigitem('convert', 'hg.ignoreerrors',
288 coreconfigitem('convert', 'hg.ignoreerrors',
289 default=False,
289 default=False,
290 )
290 )
291 coreconfigitem('convert', 'hg.revs',
291 coreconfigitem('convert', 'hg.revs',
292 default=None,
292 default=None,
293 )
293 )
294 coreconfigitem('convert', 'hg.saverev',
294 coreconfigitem('convert', 'hg.saverev',
295 default=False,
295 default=False,
296 )
296 )
297 coreconfigitem('convert', 'hg.sourcename',
297 coreconfigitem('convert', 'hg.sourcename',
298 default=None,
298 default=None,
299 )
299 )
300 coreconfigitem('convert', 'hg.startrev',
300 coreconfigitem('convert', 'hg.startrev',
301 default=None,
301 default=None,
302 )
302 )
303 coreconfigitem('convert', 'hg.tagsbranch',
303 coreconfigitem('convert', 'hg.tagsbranch',
304 default='default',
304 default='default',
305 )
305 )
306 coreconfigitem('convert', 'hg.usebranchnames',
306 coreconfigitem('convert', 'hg.usebranchnames',
307 default=True,
307 default=True,
308 )
308 )
309 coreconfigitem('convert', 'ignoreancestorcheck',
309 coreconfigitem('convert', 'ignoreancestorcheck',
310 default=False,
310 default=False,
311 )
311 )
312 coreconfigitem('convert', 'localtimezone',
312 coreconfigitem('convert', 'localtimezone',
313 default=False,
313 default=False,
314 )
314 )
315 coreconfigitem('convert', 'p4.encoding',
315 coreconfigitem('convert', 'p4.encoding',
316 default=dynamicdefault,
316 default=dynamicdefault,
317 )
317 )
318 coreconfigitem('convert', 'p4.startrev',
318 coreconfigitem('convert', 'p4.startrev',
319 default=0,
319 default=0,
320 )
320 )
321 coreconfigitem('convert', 'skiptags',
321 coreconfigitem('convert', 'skiptags',
322 default=False,
322 default=False,
323 )
323 )
324 coreconfigitem('convert', 'svn.debugsvnlog',
324 coreconfigitem('convert', 'svn.debugsvnlog',
325 default=True,
325 default=True,
326 )
326 )
327 coreconfigitem('convert', 'svn.trunk',
327 coreconfigitem('convert', 'svn.trunk',
328 default=None,
328 default=None,
329 )
329 )
330 coreconfigitem('convert', 'svn.tags',
330 coreconfigitem('convert', 'svn.tags',
331 default=None,
331 default=None,
332 )
332 )
333 coreconfigitem('convert', 'svn.branches',
333 coreconfigitem('convert', 'svn.branches',
334 default=None,
334 default=None,
335 )
335 )
336 coreconfigitem('convert', 'svn.startrev',
336 coreconfigitem('convert', 'svn.startrev',
337 default=0,
337 default=0,
338 )
338 )
339 coreconfigitem('debug', 'dirstate.delaywrite',
339 coreconfigitem('debug', 'dirstate.delaywrite',
340 default=0,
340 default=0,
341 )
341 )
342 coreconfigitem('defaults', '.*',
342 coreconfigitem('defaults', '.*',
343 default=None,
343 default=None,
344 generic=True,
344 generic=True,
345 )
345 )
346 coreconfigitem('devel', 'all-warnings',
346 coreconfigitem('devel', 'all-warnings',
347 default=False,
347 default=False,
348 )
348 )
349 coreconfigitem('devel', 'bundle2.debug',
349 coreconfigitem('devel', 'bundle2.debug',
350 default=False,
350 default=False,
351 )
351 )
352 coreconfigitem('devel', 'bundle.delta',
352 coreconfigitem('devel', 'bundle.delta',
353 default='',
353 default='',
354 )
354 )
355 coreconfigitem('devel', 'cache-vfs',
355 coreconfigitem('devel', 'cache-vfs',
356 default=None,
356 default=None,
357 )
357 )
358 coreconfigitem('devel', 'check-locks',
358 coreconfigitem('devel', 'check-locks',
359 default=False,
359 default=False,
360 )
360 )
361 coreconfigitem('devel', 'check-relroot',
361 coreconfigitem('devel', 'check-relroot',
362 default=False,
362 default=False,
363 )
363 )
364 coreconfigitem('devel', 'default-date',
364 coreconfigitem('devel', 'default-date',
365 default=None,
365 default=None,
366 )
366 )
367 coreconfigitem('devel', 'deprec-warn',
367 coreconfigitem('devel', 'deprec-warn',
368 default=False,
368 default=False,
369 )
369 )
370 coreconfigitem('devel', 'disableloaddefaultcerts',
370 coreconfigitem('devel', 'disableloaddefaultcerts',
371 default=False,
371 default=False,
372 )
372 )
373 coreconfigitem('devel', 'warn-empty-changegroup',
373 coreconfigitem('devel', 'warn-empty-changegroup',
374 default=False,
374 default=False,
375 )
375 )
376 coreconfigitem('devel', 'legacy.exchange',
376 coreconfigitem('devel', 'legacy.exchange',
377 default=list,
377 default=list,
378 )
378 )
379 coreconfigitem('devel', 'servercafile',
379 coreconfigitem('devel', 'servercafile',
380 default='',
380 default='',
381 )
381 )
382 coreconfigitem('devel', 'serverexactprotocol',
382 coreconfigitem('devel', 'serverexactprotocol',
383 default='',
383 default='',
384 )
384 )
385 coreconfigitem('devel', 'serverrequirecert',
385 coreconfigitem('devel', 'serverrequirecert',
386 default=False,
386 default=False,
387 )
387 )
388 coreconfigitem('devel', 'strip-obsmarkers',
388 coreconfigitem('devel', 'strip-obsmarkers',
389 default=True,
389 default=True,
390 )
390 )
391 coreconfigitem('devel', 'warn-config',
391 coreconfigitem('devel', 'warn-config',
392 default=None,
392 default=None,
393 )
393 )
394 coreconfigitem('devel', 'warn-config-default',
394 coreconfigitem('devel', 'warn-config-default',
395 default=None,
395 default=None,
396 )
396 )
397 coreconfigitem('devel', 'user.obsmarker',
397 coreconfigitem('devel', 'user.obsmarker',
398 default=None,
398 default=None,
399 )
399 )
400 coreconfigitem('devel', 'warn-config-unknown',
400 coreconfigitem('devel', 'warn-config-unknown',
401 default=None,
401 default=None,
402 )
402 )
403 coreconfigitem('devel', 'debug.copies',
403 coreconfigitem('devel', 'debug.copies',
404 default=False,
404 default=False,
405 )
405 )
406 coreconfigitem('devel', 'debug.extensions',
406 coreconfigitem('devel', 'debug.extensions',
407 default=False,
407 default=False,
408 )
408 )
409 coreconfigitem('devel', 'debug.peer-request',
409 coreconfigitem('devel', 'debug.peer-request',
410 default=False,
410 default=False,
411 )
411 )
412 _registerdiffopts(section='diff')
412 _registerdiffopts(section='diff')
413 coreconfigitem('email', 'bcc',
413 coreconfigitem('email', 'bcc',
414 default=None,
414 default=None,
415 )
415 )
416 coreconfigitem('email', 'cc',
416 coreconfigitem('email', 'cc',
417 default=None,
417 default=None,
418 )
418 )
419 coreconfigitem('email', 'charsets',
419 coreconfigitem('email', 'charsets',
420 default=list,
420 default=list,
421 )
421 )
422 coreconfigitem('email', 'from',
422 coreconfigitem('email', 'from',
423 default=None,
423 default=None,
424 )
424 )
425 coreconfigitem('email', 'method',
425 coreconfigitem('email', 'method',
426 default='smtp',
426 default='smtp',
427 )
427 )
428 coreconfigitem('email', 'reply-to',
428 coreconfigitem('email', 'reply-to',
429 default=None,
429 default=None,
430 )
430 )
431 coreconfigitem('email', 'to',
431 coreconfigitem('email', 'to',
432 default=None,
432 default=None,
433 )
433 )
434 coreconfigitem('experimental', 'archivemetatemplate',
434 coreconfigitem('experimental', 'archivemetatemplate',
435 default=dynamicdefault,
435 default=dynamicdefault,
436 )
436 )
437 coreconfigitem('experimental', 'auto-publish',
437 coreconfigitem('experimental', 'auto-publish',
438 default='publish',
438 default='publish',
439 )
439 )
440 coreconfigitem('experimental', 'bundle-phases',
440 coreconfigitem('experimental', 'bundle-phases',
441 default=False,
441 default=False,
442 )
442 )
443 coreconfigitem('experimental', 'bundle2-advertise',
443 coreconfigitem('experimental', 'bundle2-advertise',
444 default=True,
444 default=True,
445 )
445 )
446 coreconfigitem('experimental', 'bundle2-output-capture',
446 coreconfigitem('experimental', 'bundle2-output-capture',
447 default=False,
447 default=False,
448 )
448 )
449 coreconfigitem('experimental', 'bundle2.pushback',
449 coreconfigitem('experimental', 'bundle2.pushback',
450 default=False,
450 default=False,
451 )
451 )
452 coreconfigitem('experimental', 'bundle2lazylocking',
452 coreconfigitem('experimental', 'bundle2lazylocking',
453 default=False,
453 default=False,
454 )
454 )
455 coreconfigitem('experimental', 'bundlecomplevel',
455 coreconfigitem('experimental', 'bundlecomplevel',
456 default=None,
456 default=None,
457 )
457 )
458 coreconfigitem('experimental', 'bundlecomplevel.bzip2',
458 coreconfigitem('experimental', 'bundlecomplevel.bzip2',
459 default=None,
459 default=None,
460 )
460 )
461 coreconfigitem('experimental', 'bundlecomplevel.gzip',
461 coreconfigitem('experimental', 'bundlecomplevel.gzip',
462 default=None,
462 default=None,
463 )
463 )
464 coreconfigitem('experimental', 'bundlecomplevel.none',
464 coreconfigitem('experimental', 'bundlecomplevel.none',
465 default=None,
465 default=None,
466 )
466 )
467 coreconfigitem('experimental', 'bundlecomplevel.zstd',
467 coreconfigitem('experimental', 'bundlecomplevel.zstd',
468 default=None,
468 default=None,
469 )
469 )
470 coreconfigitem('experimental', 'changegroup3',
470 coreconfigitem('experimental', 'changegroup3',
471 default=False,
471 default=False,
472 )
472 )
473 coreconfigitem('experimental', 'cleanup-as-archived',
473 coreconfigitem('experimental', 'cleanup-as-archived',
474 default=False,
474 default=False,
475 )
475 )
476 coreconfigitem('experimental', 'clientcompressionengines',
476 coreconfigitem('experimental', 'clientcompressionengines',
477 default=list,
477 default=list,
478 )
478 )
479 coreconfigitem('experimental', 'copytrace',
479 coreconfigitem('experimental', 'copytrace',
480 default='on',
480 default='on',
481 )
481 )
482 coreconfigitem('experimental', 'copytrace.movecandidateslimit',
482 coreconfigitem('experimental', 'copytrace.movecandidateslimit',
483 default=100,
483 default=100,
484 )
484 )
485 coreconfigitem('experimental', 'copytrace.sourcecommitlimit',
485 coreconfigitem('experimental', 'copytrace.sourcecommitlimit',
486 default=100,
486 default=100,
487 )
487 )
488 coreconfigitem('experimental', 'copies.read-from',
488 coreconfigitem('experimental', 'copies.read-from',
489 default="filelog-only",
489 default="filelog-only",
490 )
490 )
491 coreconfigitem('experimental', 'crecordtest',
491 coreconfigitem('experimental', 'crecordtest',
492 default=None,
492 default=None,
493 )
493 )
494 coreconfigitem('experimental', 'directaccess',
494 coreconfigitem('experimental', 'directaccess',
495 default=False,
495 default=False,
496 )
496 )
497 coreconfigitem('experimental', 'directaccess.revnums',
497 coreconfigitem('experimental', 'directaccess.revnums',
498 default=False,
498 default=False,
499 )
499 )
500 coreconfigitem('experimental', 'editortmpinhg',
500 coreconfigitem('experimental', 'editortmpinhg',
501 default=False,
501 default=False,
502 )
502 )
503 coreconfigitem('experimental', 'evolution',
503 coreconfigitem('experimental', 'evolution',
504 default=list,
504 default=list,
505 )
505 )
506 coreconfigitem('experimental', 'evolution.allowdivergence',
506 coreconfigitem('experimental', 'evolution.allowdivergence',
507 default=False,
507 default=False,
508 alias=[('experimental', 'allowdivergence')]
508 alias=[('experimental', 'allowdivergence')]
509 )
509 )
510 coreconfigitem('experimental', 'evolution.allowunstable',
510 coreconfigitem('experimental', 'evolution.allowunstable',
511 default=None,
511 default=None,
512 )
512 )
513 coreconfigitem('experimental', 'evolution.createmarkers',
513 coreconfigitem('experimental', 'evolution.createmarkers',
514 default=None,
514 default=None,
515 )
515 )
516 coreconfigitem('experimental', 'evolution.effect-flags',
516 coreconfigitem('experimental', 'evolution.effect-flags',
517 default=True,
517 default=True,
518 alias=[('experimental', 'effect-flags')]
518 alias=[('experimental', 'effect-flags')]
519 )
519 )
520 coreconfigitem('experimental', 'evolution.exchange',
520 coreconfigitem('experimental', 'evolution.exchange',
521 default=None,
521 default=None,
522 )
522 )
523 coreconfigitem('experimental', 'evolution.bundle-obsmarker',
523 coreconfigitem('experimental', 'evolution.bundle-obsmarker',
524 default=False,
524 default=False,
525 )
525 )
526 coreconfigitem('experimental', 'evolution.report-instabilities',
526 coreconfigitem('experimental', 'evolution.report-instabilities',
527 default=True,
527 default=True,
528 )
528 )
529 coreconfigitem('experimental', 'evolution.track-operation',
529 coreconfigitem('experimental', 'evolution.track-operation',
530 default=True,
530 default=True,
531 )
531 )
532 coreconfigitem('experimental', 'maxdeltachainspan',
532 coreconfigitem('experimental', 'maxdeltachainspan',
533 default=-1,
533 default=-1,
534 )
534 )
535 coreconfigitem('experimental', 'mergetempdirprefix',
535 coreconfigitem('experimental', 'mergetempdirprefix',
536 default=None,
536 default=None,
537 )
537 )
538 coreconfigitem('experimental', 'mmapindexthreshold',
538 coreconfigitem('experimental', 'mmapindexthreshold',
539 default=None,
539 default=None,
540 )
540 )
541 coreconfigitem('experimental', 'narrow',
541 coreconfigitem('experimental', 'narrow',
542 default=False,
542 default=False,
543 )
543 )
544 coreconfigitem('experimental', 'nonnormalparanoidcheck',
544 coreconfigitem('experimental', 'nonnormalparanoidcheck',
545 default=False,
545 default=False,
546 )
546 )
547 coreconfigitem('experimental', 'exportableenviron',
547 coreconfigitem('experimental', 'exportableenviron',
548 default=list,
548 default=list,
549 )
549 )
550 coreconfigitem('experimental', 'extendedheader.index',
550 coreconfigitem('experimental', 'extendedheader.index',
551 default=None,
551 default=None,
552 )
552 )
553 coreconfigitem('experimental', 'extendedheader.similarity',
553 coreconfigitem('experimental', 'extendedheader.similarity',
554 default=False,
554 default=False,
555 )
555 )
556 coreconfigitem('experimental', 'format.compression',
556 coreconfigitem('experimental', 'format.compression',
557 default='zlib',
557 default='zlib',
558 )
558 )
559 coreconfigitem('experimental', 'graphshorten',
559 coreconfigitem('experimental', 'graphshorten',
560 default=False,
560 default=False,
561 )
561 )
562 coreconfigitem('experimental', 'graphstyle.parent',
562 coreconfigitem('experimental', 'graphstyle.parent',
563 default=dynamicdefault,
563 default=dynamicdefault,
564 )
564 )
565 coreconfigitem('experimental', 'graphstyle.missing',
565 coreconfigitem('experimental', 'graphstyle.missing',
566 default=dynamicdefault,
566 default=dynamicdefault,
567 )
567 )
568 coreconfigitem('experimental', 'graphstyle.grandparent',
568 coreconfigitem('experimental', 'graphstyle.grandparent',
569 default=dynamicdefault,
569 default=dynamicdefault,
570 )
570 )
571 coreconfigitem('experimental', 'hook-track-tags',
571 coreconfigitem('experimental', 'hook-track-tags',
572 default=False,
572 default=False,
573 )
573 )
574 coreconfigitem('experimental', 'httppeer.advertise-v2',
574 coreconfigitem('experimental', 'httppeer.advertise-v2',
575 default=False,
575 default=False,
576 )
576 )
577 coreconfigitem('experimental', 'httppeer.v2-encoder-order',
577 coreconfigitem('experimental', 'httppeer.v2-encoder-order',
578 default=None,
578 default=None,
579 )
579 )
580 coreconfigitem('experimental', 'httppostargs',
580 coreconfigitem('experimental', 'httppostargs',
581 default=False,
581 default=False,
582 )
582 )
583 coreconfigitem('experimental', 'mergedriver',
583 coreconfigitem('experimental', 'mergedriver',
584 default=None,
584 default=None,
585 )
585 )
586 coreconfigitem('experimental', 'nointerrupt', default=False)
586 coreconfigitem('experimental', 'nointerrupt', default=False)
587 coreconfigitem('experimental', 'nointerrupt-interactiveonly', default=True)
587 coreconfigitem('experimental', 'nointerrupt-interactiveonly', default=True)
588
588
589 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
589 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
590 default=False,
590 default=False,
591 )
591 )
592 coreconfigitem('experimental', 'remotenames',
592 coreconfigitem('experimental', 'remotenames',
593 default=False,
593 default=False,
594 )
594 )
595 coreconfigitem('experimental', 'removeemptydirs',
595 coreconfigitem('experimental', 'removeemptydirs',
596 default=True,
596 default=True,
597 )
597 )
598 coreconfigitem('experimental', 'revisions.prefixhexnode',
598 coreconfigitem('experimental', 'revisions.prefixhexnode',
599 default=False,
599 default=False,
600 )
600 )
601 coreconfigitem('experimental', 'revlogv2',
601 coreconfigitem('experimental', 'revlogv2',
602 default=None,
602 default=None,
603 )
603 )
604 coreconfigitem('experimental', 'revisions.disambiguatewithin',
604 coreconfigitem('experimental', 'revisions.disambiguatewithin',
605 default=None,
605 default=None,
606 )
606 )
607 coreconfigitem('experimental', 'server.filesdata.recommended-batch-size',
607 coreconfigitem('experimental', 'server.filesdata.recommended-batch-size',
608 default=50000,
608 default=50000,
609 )
609 )
610 coreconfigitem('experimental', 'server.manifestdata.recommended-batch-size',
610 coreconfigitem('experimental', 'server.manifestdata.recommended-batch-size',
611 default=100000,
611 default=100000,
612 )
612 )
613 coreconfigitem('experimental', 'server.stream-narrow-clones',
613 coreconfigitem('experimental', 'server.stream-narrow-clones',
614 default=False,
614 default=False,
615 )
615 )
616 coreconfigitem('experimental', 'single-head-per-branch',
616 coreconfigitem('experimental', 'single-head-per-branch',
617 default=False,
617 default=False,
618 )
618 )
619 coreconfigitem('experimental', 'sshserver.support-v2',
619 coreconfigitem('experimental', 'sshserver.support-v2',
620 default=False,
620 default=False,
621 )
621 )
622 coreconfigitem('experimental', 'sparse-read',
622 coreconfigitem('experimental', 'sparse-read',
623 default=False,
623 default=False,
624 )
624 )
625 coreconfigitem('experimental', 'sparse-read.density-threshold',
625 coreconfigitem('experimental', 'sparse-read.density-threshold',
626 default=0.50,
626 default=0.50,
627 )
627 )
628 coreconfigitem('experimental', 'sparse-read.min-gap-size',
628 coreconfigitem('experimental', 'sparse-read.min-gap-size',
629 default='65K',
629 default='65K',
630 )
630 )
631 coreconfigitem('experimental', 'treemanifest',
631 coreconfigitem('experimental', 'treemanifest',
632 default=False,
632 default=False,
633 )
633 )
634 coreconfigitem('experimental', 'update.atomic-file',
634 coreconfigitem('experimental', 'update.atomic-file',
635 default=False,
635 default=False,
636 )
636 )
637 coreconfigitem('experimental', 'sshpeer.advertise-v2',
637 coreconfigitem('experimental', 'sshpeer.advertise-v2',
638 default=False,
638 default=False,
639 )
639 )
640 coreconfigitem('experimental', 'web.apiserver',
640 coreconfigitem('experimental', 'web.apiserver',
641 default=False,
641 default=False,
642 )
642 )
643 coreconfigitem('experimental', 'web.api.http-v2',
643 coreconfigitem('experimental', 'web.api.http-v2',
644 default=False,
644 default=False,
645 )
645 )
646 coreconfigitem('experimental', 'web.api.debugreflect',
646 coreconfigitem('experimental', 'web.api.debugreflect',
647 default=False,
647 default=False,
648 )
648 )
649 coreconfigitem('experimental', 'worker.wdir-get-thread-safe',
649 coreconfigitem('experimental', 'worker.wdir-get-thread-safe',
650 default=False,
650 default=False,
651 )
651 )
652 coreconfigitem('experimental', 'xdiff',
652 coreconfigitem('experimental', 'xdiff',
653 default=False,
653 default=False,
654 )
654 )
655 coreconfigitem('extensions', '.*',
655 coreconfigitem('extensions', '.*',
656 default=None,
656 default=None,
657 generic=True,
657 generic=True,
658 )
658 )
659 coreconfigitem('extdata', '.*',
659 coreconfigitem('extdata', '.*',
660 default=None,
660 default=None,
661 generic=True,
661 generic=True,
662 )
662 )
663 coreconfigitem('format', 'chunkcachesize',
663 coreconfigitem('format', 'chunkcachesize',
664 default=None,
664 default=None,
665 )
665 )
666 coreconfigitem('format', 'dotencode',
666 coreconfigitem('format', 'dotencode',
667 default=True,
667 default=True,
668 )
668 )
669 coreconfigitem('format', 'generaldelta',
669 coreconfigitem('format', 'generaldelta',
670 default=False,
670 default=False,
671 )
671 )
672 coreconfigitem('format', 'manifestcachesize',
672 coreconfigitem('format', 'manifestcachesize',
673 default=None,
673 default=None,
674 )
674 )
675 coreconfigitem('format', 'maxchainlen',
675 coreconfigitem('format', 'maxchainlen',
676 default=dynamicdefault,
676 default=dynamicdefault,
677 )
677 )
678 coreconfigitem('format', 'obsstore-version',
678 coreconfigitem('format', 'obsstore-version',
679 default=None,
679 default=None,
680 )
680 )
681 coreconfigitem('format', 'sparse-revlog',
681 coreconfigitem('format', 'sparse-revlog',
682 default=True,
682 default=True,
683 )
683 )
684 coreconfigitem('format', 'usefncache',
684 coreconfigitem('format', 'usefncache',
685 default=True,
685 default=True,
686 )
686 )
687 coreconfigitem('format', 'usegeneraldelta',
687 coreconfigitem('format', 'usegeneraldelta',
688 default=True,
688 default=True,
689 )
689 )
690 coreconfigitem('format', 'usestore',
690 coreconfigitem('format', 'usestore',
691 default=True,
691 default=True,
692 )
692 )
693 coreconfigitem('format', 'internal-phase',
693 coreconfigitem('format', 'internal-phase',
694 default=False,
694 default=False,
695 )
695 )
696 coreconfigitem('fsmonitor', 'warn_when_unused',
696 coreconfigitem('fsmonitor', 'warn_when_unused',
697 default=True,
697 default=True,
698 )
698 )
699 coreconfigitem('fsmonitor', 'warn_update_file_count',
699 coreconfigitem('fsmonitor', 'warn_update_file_count',
700 default=50000,
700 default=50000,
701 )
701 )
702 coreconfigitem('help', br'hidden-command\..*',
702 coreconfigitem('help', br'hidden-command\..*',
703 default=False,
703 default=False,
704 generic=True,
704 generic=True,
705 )
705 )
706 coreconfigitem('help', br'hidden-topic\..*',
706 coreconfigitem('help', br'hidden-topic\..*',
707 default=False,
707 default=False,
708 generic=True,
708 generic=True,
709 )
709 )
710 coreconfigitem('hooks', '.*',
710 coreconfigitem('hooks', '.*',
711 default=dynamicdefault,
711 default=dynamicdefault,
712 generic=True,
712 generic=True,
713 )
713 )
714 coreconfigitem('hgweb-paths', '.*',
714 coreconfigitem('hgweb-paths', '.*',
715 default=list,
715 default=list,
716 generic=True,
716 generic=True,
717 )
717 )
718 coreconfigitem('hostfingerprints', '.*',
718 coreconfigitem('hostfingerprints', '.*',
719 default=list,
719 default=list,
720 generic=True,
720 generic=True,
721 )
721 )
722 coreconfigitem('hostsecurity', 'ciphers',
722 coreconfigitem('hostsecurity', 'ciphers',
723 default=None,
723 default=None,
724 )
724 )
725 coreconfigitem('hostsecurity', 'disabletls10warning',
725 coreconfigitem('hostsecurity', 'disabletls10warning',
726 default=False,
726 default=False,
727 )
727 )
728 coreconfigitem('hostsecurity', 'minimumprotocol',
728 coreconfigitem('hostsecurity', 'minimumprotocol',
729 default=dynamicdefault,
729 default=dynamicdefault,
730 )
730 )
731 coreconfigitem('hostsecurity', '.*:minimumprotocol$',
731 coreconfigitem('hostsecurity', '.*:minimumprotocol$',
732 default=dynamicdefault,
732 default=dynamicdefault,
733 generic=True,
733 generic=True,
734 )
734 )
735 coreconfigitem('hostsecurity', '.*:ciphers$',
735 coreconfigitem('hostsecurity', '.*:ciphers$',
736 default=dynamicdefault,
736 default=dynamicdefault,
737 generic=True,
737 generic=True,
738 )
738 )
739 coreconfigitem('hostsecurity', '.*:fingerprints$',
739 coreconfigitem('hostsecurity', '.*:fingerprints$',
740 default=list,
740 default=list,
741 generic=True,
741 generic=True,
742 )
742 )
743 coreconfigitem('hostsecurity', '.*:verifycertsfile$',
743 coreconfigitem('hostsecurity', '.*:verifycertsfile$',
744 default=None,
744 default=None,
745 generic=True,
745 generic=True,
746 )
746 )
747
747
748 coreconfigitem('http_proxy', 'always',
748 coreconfigitem('http_proxy', 'always',
749 default=False,
749 default=False,
750 )
750 )
751 coreconfigitem('http_proxy', 'host',
751 coreconfigitem('http_proxy', 'host',
752 default=None,
752 default=None,
753 )
753 )
754 coreconfigitem('http_proxy', 'no',
754 coreconfigitem('http_proxy', 'no',
755 default=list,
755 default=list,
756 )
756 )
757 coreconfigitem('http_proxy', 'passwd',
757 coreconfigitem('http_proxy', 'passwd',
758 default=None,
758 default=None,
759 )
759 )
760 coreconfigitem('http_proxy', 'user',
760 coreconfigitem('http_proxy', 'user',
761 default=None,
761 default=None,
762 )
762 )
763
763
764 coreconfigitem('http', 'timeout',
764 coreconfigitem('http', 'timeout',
765 default=None,
765 default=None,
766 )
766 )
767
767
768 coreconfigitem('logtoprocess', 'commandexception',
768 coreconfigitem('logtoprocess', 'commandexception',
769 default=None,
769 default=None,
770 )
770 )
771 coreconfigitem('logtoprocess', 'commandfinish',
771 coreconfigitem('logtoprocess', 'commandfinish',
772 default=None,
772 default=None,
773 )
773 )
774 coreconfigitem('logtoprocess', 'command',
774 coreconfigitem('logtoprocess', 'command',
775 default=None,
775 default=None,
776 )
776 )
777 coreconfigitem('logtoprocess', 'develwarn',
777 coreconfigitem('logtoprocess', 'develwarn',
778 default=None,
778 default=None,
779 )
779 )
780 coreconfigitem('logtoprocess', 'uiblocked',
780 coreconfigitem('logtoprocess', 'uiblocked',
781 default=None,
781 default=None,
782 )
782 )
783 coreconfigitem('merge', 'checkunknown',
783 coreconfigitem('merge', 'checkunknown',
784 default='abort',
784 default='abort',
785 )
785 )
786 coreconfigitem('merge', 'checkignored',
786 coreconfigitem('merge', 'checkignored',
787 default='abort',
787 default='abort',
788 )
788 )
789 coreconfigitem('experimental', 'merge.checkpathconflicts',
789 coreconfigitem('experimental', 'merge.checkpathconflicts',
790 default=False,
790 default=False,
791 )
791 )
792 coreconfigitem('merge', 'followcopies',
792 coreconfigitem('merge', 'followcopies',
793 default=True,
793 default=True,
794 )
794 )
795 coreconfigitem('merge', 'on-failure',
795 coreconfigitem('merge', 'on-failure',
796 default='continue',
796 default='continue',
797 )
797 )
798 coreconfigitem('merge', 'preferancestor',
798 coreconfigitem('merge', 'preferancestor',
799 default=lambda: ['*'],
799 default=lambda: ['*'],
800 )
800 )
801 coreconfigitem('merge', 'strict-capability-check',
801 coreconfigitem('merge', 'strict-capability-check',
802 default=False,
802 default=False,
803 )
803 )
804 coreconfigitem('merge-tools', '.*',
804 coreconfigitem('merge-tools', '.*',
805 default=None,
805 default=None,
806 generic=True,
806 generic=True,
807 )
807 )
808 coreconfigitem('merge-tools', br'.*\.args$',
808 coreconfigitem('merge-tools', br'.*\.args$',
809 default="$local $base $other",
809 default="$local $base $other",
810 generic=True,
810 generic=True,
811 priority=-1,
811 priority=-1,
812 )
812 )
813 coreconfigitem('merge-tools', br'.*\.binary$',
813 coreconfigitem('merge-tools', br'.*\.binary$',
814 default=False,
814 default=False,
815 generic=True,
815 generic=True,
816 priority=-1,
816 priority=-1,
817 )
817 )
818 coreconfigitem('merge-tools', br'.*\.check$',
818 coreconfigitem('merge-tools', br'.*\.check$',
819 default=list,
819 default=list,
820 generic=True,
820 generic=True,
821 priority=-1,
821 priority=-1,
822 )
822 )
823 coreconfigitem('merge-tools', br'.*\.checkchanged$',
823 coreconfigitem('merge-tools', br'.*\.checkchanged$',
824 default=False,
824 default=False,
825 generic=True,
825 generic=True,
826 priority=-1,
826 priority=-1,
827 )
827 )
828 coreconfigitem('merge-tools', br'.*\.executable$',
828 coreconfigitem('merge-tools', br'.*\.executable$',
829 default=dynamicdefault,
829 default=dynamicdefault,
830 generic=True,
830 generic=True,
831 priority=-1,
831 priority=-1,
832 )
832 )
833 coreconfigitem('merge-tools', br'.*\.fixeol$',
833 coreconfigitem('merge-tools', br'.*\.fixeol$',
834 default=False,
834 default=False,
835 generic=True,
835 generic=True,
836 priority=-1,
836 priority=-1,
837 )
837 )
838 coreconfigitem('merge-tools', br'.*\.gui$',
838 coreconfigitem('merge-tools', br'.*\.gui$',
839 default=False,
839 default=False,
840 generic=True,
840 generic=True,
841 priority=-1,
841 priority=-1,
842 )
842 )
843 coreconfigitem('merge-tools', br'.*\.mergemarkers$',
843 coreconfigitem('merge-tools', br'.*\.mergemarkers$',
844 default='basic',
844 default='basic',
845 generic=True,
845 generic=True,
846 priority=-1,
846 priority=-1,
847 )
847 )
848 coreconfigitem('merge-tools', br'.*\.mergemarkertemplate$',
848 coreconfigitem('merge-tools', br'.*\.mergemarkertemplate$',
849 default=dynamicdefault, # take from ui.mergemarkertemplate
849 default=dynamicdefault, # take from ui.mergemarkertemplate
850 generic=True,
850 generic=True,
851 priority=-1,
851 priority=-1,
852 )
852 )
853 coreconfigitem('merge-tools', br'.*\.priority$',
853 coreconfigitem('merge-tools', br'.*\.priority$',
854 default=0,
854 default=0,
855 generic=True,
855 generic=True,
856 priority=-1,
856 priority=-1,
857 )
857 )
858 coreconfigitem('merge-tools', br'.*\.premerge$',
858 coreconfigitem('merge-tools', br'.*\.premerge$',
859 default=dynamicdefault,
859 default=dynamicdefault,
860 generic=True,
860 generic=True,
861 priority=-1,
861 priority=-1,
862 )
862 )
863 coreconfigitem('merge-tools', br'.*\.symlink$',
863 coreconfigitem('merge-tools', br'.*\.symlink$',
864 default=False,
864 default=False,
865 generic=True,
865 generic=True,
866 priority=-1,
866 priority=-1,
867 )
867 )
868 coreconfigitem('pager', 'attend-.*',
868 coreconfigitem('pager', 'attend-.*',
869 default=dynamicdefault,
869 default=dynamicdefault,
870 generic=True,
870 generic=True,
871 )
871 )
872 coreconfigitem('pager', 'ignore',
872 coreconfigitem('pager', 'ignore',
873 default=list,
873 default=list,
874 )
874 )
875 coreconfigitem('pager', 'pager',
875 coreconfigitem('pager', 'pager',
876 default=dynamicdefault,
876 default=dynamicdefault,
877 )
877 )
878 coreconfigitem('patch', 'eol',
878 coreconfigitem('patch', 'eol',
879 default='strict',
879 default='strict',
880 )
880 )
881 coreconfigitem('patch', 'fuzz',
881 coreconfigitem('patch', 'fuzz',
882 default=2,
882 default=2,
883 )
883 )
884 coreconfigitem('paths', 'default',
884 coreconfigitem('paths', 'default',
885 default=None,
885 default=None,
886 )
886 )
887 coreconfigitem('paths', 'default-push',
887 coreconfigitem('paths', 'default-push',
888 default=None,
888 default=None,
889 )
889 )
890 coreconfigitem('paths', '.*',
890 coreconfigitem('paths', '.*',
891 default=None,
891 default=None,
892 generic=True,
892 generic=True,
893 )
893 )
894 coreconfigitem('phases', 'checksubrepos',
894 coreconfigitem('phases', 'checksubrepos',
895 default='follow',
895 default='follow',
896 )
896 )
897 coreconfigitem('phases', 'new-commit',
897 coreconfigitem('phases', 'new-commit',
898 default='draft',
898 default='draft',
899 )
899 )
900 coreconfigitem('phases', 'publish',
900 coreconfigitem('phases', 'publish',
901 default=True,
901 default=True,
902 )
902 )
903 coreconfigitem('profiling', 'enabled',
903 coreconfigitem('profiling', 'enabled',
904 default=False,
904 default=False,
905 )
905 )
906 coreconfigitem('profiling', 'format',
906 coreconfigitem('profiling', 'format',
907 default='text',
907 default='text',
908 )
908 )
909 coreconfigitem('profiling', 'freq',
909 coreconfigitem('profiling', 'freq',
910 default=1000,
910 default=1000,
911 )
911 )
912 coreconfigitem('profiling', 'limit',
912 coreconfigitem('profiling', 'limit',
913 default=30,
913 default=30,
914 )
914 )
915 coreconfigitem('profiling', 'nested',
915 coreconfigitem('profiling', 'nested',
916 default=0,
916 default=0,
917 )
917 )
918 coreconfigitem('profiling', 'output',
918 coreconfigitem('profiling', 'output',
919 default=None,
919 default=None,
920 )
920 )
921 coreconfigitem('profiling', 'showmax',
921 coreconfigitem('profiling', 'showmax',
922 default=0.999,
922 default=0.999,
923 )
923 )
924 coreconfigitem('profiling', 'showmin',
924 coreconfigitem('profiling', 'showmin',
925 default=dynamicdefault,
925 default=dynamicdefault,
926 )
926 )
927 coreconfigitem('profiling', 'sort',
927 coreconfigitem('profiling', 'sort',
928 default='inlinetime',
928 default='inlinetime',
929 )
929 )
930 coreconfigitem('profiling', 'statformat',
930 coreconfigitem('profiling', 'statformat',
931 default='hotpath',
931 default='hotpath',
932 )
932 )
933 coreconfigitem('profiling', 'time-track',
933 coreconfigitem('profiling', 'time-track',
934 default=dynamicdefault,
934 default=dynamicdefault,
935 )
935 )
936 coreconfigitem('profiling', 'type',
936 coreconfigitem('profiling', 'type',
937 default='stat',
937 default='stat',
938 )
938 )
939 coreconfigitem('progress', 'assume-tty',
939 coreconfigitem('progress', 'assume-tty',
940 default=False,
940 default=False,
941 )
941 )
942 coreconfigitem('progress', 'changedelay',
942 coreconfigitem('progress', 'changedelay',
943 default=1,
943 default=1,
944 )
944 )
945 coreconfigitem('progress', 'clear-complete',
945 coreconfigitem('progress', 'clear-complete',
946 default=True,
946 default=True,
947 )
947 )
948 coreconfigitem('progress', 'debug',
948 coreconfigitem('progress', 'debug',
949 default=False,
949 default=False,
950 )
950 )
951 coreconfigitem('progress', 'delay',
951 coreconfigitem('progress', 'delay',
952 default=3,
952 default=3,
953 )
953 )
954 coreconfigitem('progress', 'disable',
954 coreconfigitem('progress', 'disable',
955 default=False,
955 default=False,
956 )
956 )
957 coreconfigitem('progress', 'estimateinterval',
957 coreconfigitem('progress', 'estimateinterval',
958 default=60.0,
958 default=60.0,
959 )
959 )
960 coreconfigitem('progress', 'format',
960 coreconfigitem('progress', 'format',
961 default=lambda: ['topic', 'bar', 'number', 'estimate'],
961 default=lambda: ['topic', 'bar', 'number', 'estimate'],
962 )
962 )
963 coreconfigitem('progress', 'refresh',
963 coreconfigitem('progress', 'refresh',
964 default=0.1,
964 default=0.1,
965 )
965 )
966 coreconfigitem('progress', 'width',
966 coreconfigitem('progress', 'width',
967 default=dynamicdefault,
967 default=dynamicdefault,
968 )
968 )
969 coreconfigitem('push', 'pushvars.server',
969 coreconfigitem('push', 'pushvars.server',
970 default=False,
970 default=False,
971 )
971 )
972 coreconfigitem('rewrite', 'backup-bundle',
972 coreconfigitem('rewrite', 'backup-bundle',
973 default=True,
973 default=True,
974 alias=[('ui', 'history-editing-backup')],
974 alias=[('ui', 'history-editing-backup')],
975 )
975 )
976 coreconfigitem('rewrite', 'update-timestamp',
976 coreconfigitem('rewrite', 'update-timestamp',
977 default=False,
977 default=False,
978 )
978 )
979 coreconfigitem('storage', 'new-repo-backend',
979 coreconfigitem('storage', 'new-repo-backend',
980 default='revlogv1',
980 default='revlogv1',
981 )
981 )
982 coreconfigitem('storage', 'revlog.optimize-delta-parent-choice',
982 coreconfigitem('storage', 'revlog.optimize-delta-parent-choice',
983 default=True,
983 default=True,
984 alias=[('format', 'aggressivemergedeltas')],
984 alias=[('format', 'aggressivemergedeltas')],
985 )
985 )
986 coreconfigitem('storage', 'revlog.reuse-external-delta',
986 coreconfigitem('storage', 'revlog.reuse-external-delta',
987 default=True,
987 default=True,
988 )
988 )
989 coreconfigitem('storage', 'revlog.reuse-external-delta-parent',
989 coreconfigitem('storage', 'revlog.reuse-external-delta-parent',
990 default=None,
990 default=None,
991 )
991 )
992 coreconfigitem('server', 'bookmarks-pushkey-compat',
992 coreconfigitem('server', 'bookmarks-pushkey-compat',
993 default=True,
993 default=True,
994 )
994 )
995 coreconfigitem('server', 'bundle1',
995 coreconfigitem('server', 'bundle1',
996 default=True,
996 default=True,
997 )
997 )
998 coreconfigitem('server', 'bundle1gd',
998 coreconfigitem('server', 'bundle1gd',
999 default=None,
999 default=None,
1000 )
1000 )
1001 coreconfigitem('server', 'bundle1.pull',
1001 coreconfigitem('server', 'bundle1.pull',
1002 default=None,
1002 default=None,
1003 )
1003 )
1004 coreconfigitem('server', 'bundle1gd.pull',
1004 coreconfigitem('server', 'bundle1gd.pull',
1005 default=None,
1005 default=None,
1006 )
1006 )
1007 coreconfigitem('server', 'bundle1.push',
1007 coreconfigitem('server', 'bundle1.push',
1008 default=None,
1008 default=None,
1009 )
1009 )
1010 coreconfigitem('server', 'bundle1gd.push',
1010 coreconfigitem('server', 'bundle1gd.push',
1011 default=None,
1011 default=None,
1012 )
1012 )
1013 coreconfigitem('server', 'bundle2.stream',
1013 coreconfigitem('server', 'bundle2.stream',
1014 default=True,
1014 default=True,
1015 alias=[('experimental', 'bundle2.stream')]
1015 alias=[('experimental', 'bundle2.stream')]
1016 )
1016 )
1017 coreconfigitem('server', 'compressionengines',
1017 coreconfigitem('server', 'compressionengines',
1018 default=list,
1018 default=list,
1019 )
1019 )
1020 coreconfigitem('server', 'concurrent-push-mode',
1020 coreconfigitem('server', 'concurrent-push-mode',
1021 default='strict',
1021 default='strict',
1022 )
1022 )
1023 coreconfigitem('server', 'disablefullbundle',
1023 coreconfigitem('server', 'disablefullbundle',
1024 default=False,
1024 default=False,
1025 )
1025 )
1026 coreconfigitem('server', 'maxhttpheaderlen',
1026 coreconfigitem('server', 'maxhttpheaderlen',
1027 default=1024,
1027 default=1024,
1028 )
1028 )
1029 coreconfigitem('server', 'pullbundle',
1029 coreconfigitem('server', 'pullbundle',
1030 default=False,
1030 default=False,
1031 )
1031 )
1032 coreconfigitem('server', 'preferuncompressed',
1032 coreconfigitem('server', 'preferuncompressed',
1033 default=False,
1033 default=False,
1034 )
1034 )
1035 coreconfigitem('server', 'streamunbundle',
1035 coreconfigitem('server', 'streamunbundle',
1036 default=False,
1036 default=False,
1037 )
1037 )
1038 coreconfigitem('server', 'uncompressed',
1038 coreconfigitem('server', 'uncompressed',
1039 default=True,
1039 default=True,
1040 )
1040 )
1041 coreconfigitem('server', 'uncompressedallowsecret',
1041 coreconfigitem('server', 'uncompressedallowsecret',
1042 default=False,
1042 default=False,
1043 )
1043 )
1044 coreconfigitem('server', 'view',
1045 default='served',
1046 )
1044 coreconfigitem('server', 'validate',
1047 coreconfigitem('server', 'validate',
1045 default=False,
1048 default=False,
1046 )
1049 )
1047 coreconfigitem('server', 'zliblevel',
1050 coreconfigitem('server', 'zliblevel',
1048 default=-1,
1051 default=-1,
1049 )
1052 )
1050 coreconfigitem('server', 'zstdlevel',
1053 coreconfigitem('server', 'zstdlevel',
1051 default=3,
1054 default=3,
1052 )
1055 )
1053 coreconfigitem('share', 'pool',
1056 coreconfigitem('share', 'pool',
1054 default=None,
1057 default=None,
1055 )
1058 )
1056 coreconfigitem('share', 'poolnaming',
1059 coreconfigitem('share', 'poolnaming',
1057 default='identity',
1060 default='identity',
1058 )
1061 )
1059 coreconfigitem('smtp', 'host',
1062 coreconfigitem('smtp', 'host',
1060 default=None,
1063 default=None,
1061 )
1064 )
1062 coreconfigitem('smtp', 'local_hostname',
1065 coreconfigitem('smtp', 'local_hostname',
1063 default=None,
1066 default=None,
1064 )
1067 )
1065 coreconfigitem('smtp', 'password',
1068 coreconfigitem('smtp', 'password',
1066 default=None,
1069 default=None,
1067 )
1070 )
1068 coreconfigitem('smtp', 'port',
1071 coreconfigitem('smtp', 'port',
1069 default=dynamicdefault,
1072 default=dynamicdefault,
1070 )
1073 )
1071 coreconfigitem('smtp', 'tls',
1074 coreconfigitem('smtp', 'tls',
1072 default='none',
1075 default='none',
1073 )
1076 )
1074 coreconfigitem('smtp', 'username',
1077 coreconfigitem('smtp', 'username',
1075 default=None,
1078 default=None,
1076 )
1079 )
1077 coreconfigitem('sparse', 'missingwarning',
1080 coreconfigitem('sparse', 'missingwarning',
1078 default=True,
1081 default=True,
1079 )
1082 )
1080 coreconfigitem('subrepos', 'allowed',
1083 coreconfigitem('subrepos', 'allowed',
1081 default=dynamicdefault, # to make backporting simpler
1084 default=dynamicdefault, # to make backporting simpler
1082 )
1085 )
1083 coreconfigitem('subrepos', 'hg:allowed',
1086 coreconfigitem('subrepos', 'hg:allowed',
1084 default=dynamicdefault,
1087 default=dynamicdefault,
1085 )
1088 )
1086 coreconfigitem('subrepos', 'git:allowed',
1089 coreconfigitem('subrepos', 'git:allowed',
1087 default=dynamicdefault,
1090 default=dynamicdefault,
1088 )
1091 )
1089 coreconfigitem('subrepos', 'svn:allowed',
1092 coreconfigitem('subrepos', 'svn:allowed',
1090 default=dynamicdefault,
1093 default=dynamicdefault,
1091 )
1094 )
1092 coreconfigitem('templates', '.*',
1095 coreconfigitem('templates', '.*',
1093 default=None,
1096 default=None,
1094 generic=True,
1097 generic=True,
1095 )
1098 )
1096 coreconfigitem('templateconfig', '.*',
1099 coreconfigitem('templateconfig', '.*',
1097 default=dynamicdefault,
1100 default=dynamicdefault,
1098 generic=True,
1101 generic=True,
1099 )
1102 )
1100 coreconfigitem('trusted', 'groups',
1103 coreconfigitem('trusted', 'groups',
1101 default=list,
1104 default=list,
1102 )
1105 )
1103 coreconfigitem('trusted', 'users',
1106 coreconfigitem('trusted', 'users',
1104 default=list,
1107 default=list,
1105 )
1108 )
1106 coreconfigitem('ui', '_usedassubrepo',
1109 coreconfigitem('ui', '_usedassubrepo',
1107 default=False,
1110 default=False,
1108 )
1111 )
1109 coreconfigitem('ui', 'allowemptycommit',
1112 coreconfigitem('ui', 'allowemptycommit',
1110 default=False,
1113 default=False,
1111 )
1114 )
1112 coreconfigitem('ui', 'archivemeta',
1115 coreconfigitem('ui', 'archivemeta',
1113 default=True,
1116 default=True,
1114 )
1117 )
1115 coreconfigitem('ui', 'askusername',
1118 coreconfigitem('ui', 'askusername',
1116 default=False,
1119 default=False,
1117 )
1120 )
1118 coreconfigitem('ui', 'clonebundlefallback',
1121 coreconfigitem('ui', 'clonebundlefallback',
1119 default=False,
1122 default=False,
1120 )
1123 )
1121 coreconfigitem('ui', 'clonebundleprefers',
1124 coreconfigitem('ui', 'clonebundleprefers',
1122 default=list,
1125 default=list,
1123 )
1126 )
1124 coreconfigitem('ui', 'clonebundles',
1127 coreconfigitem('ui', 'clonebundles',
1125 default=True,
1128 default=True,
1126 )
1129 )
1127 coreconfigitem('ui', 'color',
1130 coreconfigitem('ui', 'color',
1128 default='auto',
1131 default='auto',
1129 )
1132 )
1130 coreconfigitem('ui', 'commitsubrepos',
1133 coreconfigitem('ui', 'commitsubrepos',
1131 default=False,
1134 default=False,
1132 )
1135 )
1133 coreconfigitem('ui', 'debug',
1136 coreconfigitem('ui', 'debug',
1134 default=False,
1137 default=False,
1135 )
1138 )
1136 coreconfigitem('ui', 'debugger',
1139 coreconfigitem('ui', 'debugger',
1137 default=None,
1140 default=None,
1138 )
1141 )
1139 coreconfigitem('ui', 'editor',
1142 coreconfigitem('ui', 'editor',
1140 default=dynamicdefault,
1143 default=dynamicdefault,
1141 )
1144 )
1142 coreconfigitem('ui', 'fallbackencoding',
1145 coreconfigitem('ui', 'fallbackencoding',
1143 default=None,
1146 default=None,
1144 )
1147 )
1145 coreconfigitem('ui', 'forcecwd',
1148 coreconfigitem('ui', 'forcecwd',
1146 default=None,
1149 default=None,
1147 )
1150 )
1148 coreconfigitem('ui', 'forcemerge',
1151 coreconfigitem('ui', 'forcemerge',
1149 default=None,
1152 default=None,
1150 )
1153 )
1151 coreconfigitem('ui', 'formatdebug',
1154 coreconfigitem('ui', 'formatdebug',
1152 default=False,
1155 default=False,
1153 )
1156 )
1154 coreconfigitem('ui', 'formatjson',
1157 coreconfigitem('ui', 'formatjson',
1155 default=False,
1158 default=False,
1156 )
1159 )
1157 coreconfigitem('ui', 'formatted',
1160 coreconfigitem('ui', 'formatted',
1158 default=None,
1161 default=None,
1159 )
1162 )
1160 coreconfigitem('ui', 'graphnodetemplate',
1163 coreconfigitem('ui', 'graphnodetemplate',
1161 default=None,
1164 default=None,
1162 )
1165 )
1163 coreconfigitem('ui', 'interactive',
1166 coreconfigitem('ui', 'interactive',
1164 default=None,
1167 default=None,
1165 )
1168 )
1166 coreconfigitem('ui', 'interface',
1169 coreconfigitem('ui', 'interface',
1167 default=None,
1170 default=None,
1168 )
1171 )
1169 coreconfigitem('ui', 'interface.chunkselector',
1172 coreconfigitem('ui', 'interface.chunkselector',
1170 default=None,
1173 default=None,
1171 )
1174 )
1172 coreconfigitem('ui', 'large-file-limit',
1175 coreconfigitem('ui', 'large-file-limit',
1173 default=10000000,
1176 default=10000000,
1174 )
1177 )
1175 coreconfigitem('ui', 'logblockedtimes',
1178 coreconfigitem('ui', 'logblockedtimes',
1176 default=False,
1179 default=False,
1177 )
1180 )
1178 coreconfigitem('ui', 'logtemplate',
1181 coreconfigitem('ui', 'logtemplate',
1179 default=None,
1182 default=None,
1180 )
1183 )
1181 coreconfigitem('ui', 'merge',
1184 coreconfigitem('ui', 'merge',
1182 default=None,
1185 default=None,
1183 )
1186 )
1184 coreconfigitem('ui', 'mergemarkers',
1187 coreconfigitem('ui', 'mergemarkers',
1185 default='basic',
1188 default='basic',
1186 )
1189 )
1187 coreconfigitem('ui', 'mergemarkertemplate',
1190 coreconfigitem('ui', 'mergemarkertemplate',
1188 default=('{node|short} '
1191 default=('{node|short} '
1189 '{ifeq(tags, "tip", "", '
1192 '{ifeq(tags, "tip", "", '
1190 'ifeq(tags, "", "", "{tags} "))}'
1193 'ifeq(tags, "", "", "{tags} "))}'
1191 '{if(bookmarks, "{bookmarks} ")}'
1194 '{if(bookmarks, "{bookmarks} ")}'
1192 '{ifeq(branch, "default", "", "{branch} ")}'
1195 '{ifeq(branch, "default", "", "{branch} ")}'
1193 '- {author|user}: {desc|firstline}')
1196 '- {author|user}: {desc|firstline}')
1194 )
1197 )
1195 coreconfigitem('ui', 'message-output',
1198 coreconfigitem('ui', 'message-output',
1196 default='stdio',
1199 default='stdio',
1197 )
1200 )
1198 coreconfigitem('ui', 'nontty',
1201 coreconfigitem('ui', 'nontty',
1199 default=False,
1202 default=False,
1200 )
1203 )
1201 coreconfigitem('ui', 'origbackuppath',
1204 coreconfigitem('ui', 'origbackuppath',
1202 default=None,
1205 default=None,
1203 )
1206 )
1204 coreconfigitem('ui', 'paginate',
1207 coreconfigitem('ui', 'paginate',
1205 default=True,
1208 default=True,
1206 )
1209 )
1207 coreconfigitem('ui', 'patch',
1210 coreconfigitem('ui', 'patch',
1208 default=None,
1211 default=None,
1209 )
1212 )
1210 coreconfigitem('ui', 'pre-merge-tool-output-template',
1213 coreconfigitem('ui', 'pre-merge-tool-output-template',
1211 default=None,
1214 default=None,
1212 )
1215 )
1213 coreconfigitem('ui', 'portablefilenames',
1216 coreconfigitem('ui', 'portablefilenames',
1214 default='warn',
1217 default='warn',
1215 )
1218 )
1216 coreconfigitem('ui', 'promptecho',
1219 coreconfigitem('ui', 'promptecho',
1217 default=False,
1220 default=False,
1218 )
1221 )
1219 coreconfigitem('ui', 'quiet',
1222 coreconfigitem('ui', 'quiet',
1220 default=False,
1223 default=False,
1221 )
1224 )
1222 coreconfigitem('ui', 'quietbookmarkmove',
1225 coreconfigitem('ui', 'quietbookmarkmove',
1223 default=False,
1226 default=False,
1224 )
1227 )
1225 coreconfigitem('ui', 'relative-paths',
1228 coreconfigitem('ui', 'relative-paths',
1226 default='legacy',
1229 default='legacy',
1227 )
1230 )
1228 coreconfigitem('ui', 'remotecmd',
1231 coreconfigitem('ui', 'remotecmd',
1229 default='hg',
1232 default='hg',
1230 )
1233 )
1231 coreconfigitem('ui', 'report_untrusted',
1234 coreconfigitem('ui', 'report_untrusted',
1232 default=True,
1235 default=True,
1233 )
1236 )
1234 coreconfigitem('ui', 'rollback',
1237 coreconfigitem('ui', 'rollback',
1235 default=True,
1238 default=True,
1236 )
1239 )
1237 coreconfigitem('ui', 'signal-safe-lock',
1240 coreconfigitem('ui', 'signal-safe-lock',
1238 default=True,
1241 default=True,
1239 )
1242 )
1240 coreconfigitem('ui', 'slash',
1243 coreconfigitem('ui', 'slash',
1241 default=False,
1244 default=False,
1242 )
1245 )
1243 coreconfigitem('ui', 'ssh',
1246 coreconfigitem('ui', 'ssh',
1244 default='ssh',
1247 default='ssh',
1245 )
1248 )
1246 coreconfigitem('ui', 'ssherrorhint',
1249 coreconfigitem('ui', 'ssherrorhint',
1247 default=None,
1250 default=None,
1248 )
1251 )
1249 coreconfigitem('ui', 'statuscopies',
1252 coreconfigitem('ui', 'statuscopies',
1250 default=False,
1253 default=False,
1251 )
1254 )
1252 coreconfigitem('ui', 'strict',
1255 coreconfigitem('ui', 'strict',
1253 default=False,
1256 default=False,
1254 )
1257 )
1255 coreconfigitem('ui', 'style',
1258 coreconfigitem('ui', 'style',
1256 default='',
1259 default='',
1257 )
1260 )
1258 coreconfigitem('ui', 'supportcontact',
1261 coreconfigitem('ui', 'supportcontact',
1259 default=None,
1262 default=None,
1260 )
1263 )
1261 coreconfigitem('ui', 'textwidth',
1264 coreconfigitem('ui', 'textwidth',
1262 default=78,
1265 default=78,
1263 )
1266 )
1264 coreconfigitem('ui', 'timeout',
1267 coreconfigitem('ui', 'timeout',
1265 default='600',
1268 default='600',
1266 )
1269 )
1267 coreconfigitem('ui', 'timeout.warn',
1270 coreconfigitem('ui', 'timeout.warn',
1268 default=0,
1271 default=0,
1269 )
1272 )
1270 coreconfigitem('ui', 'traceback',
1273 coreconfigitem('ui', 'traceback',
1271 default=False,
1274 default=False,
1272 )
1275 )
1273 coreconfigitem('ui', 'tweakdefaults',
1276 coreconfigitem('ui', 'tweakdefaults',
1274 default=False,
1277 default=False,
1275 )
1278 )
1276 coreconfigitem('ui', 'username',
1279 coreconfigitem('ui', 'username',
1277 alias=[('ui', 'user')]
1280 alias=[('ui', 'user')]
1278 )
1281 )
1279 coreconfigitem('ui', 'verbose',
1282 coreconfigitem('ui', 'verbose',
1280 default=False,
1283 default=False,
1281 )
1284 )
1282 coreconfigitem('verify', 'skipflags',
1285 coreconfigitem('verify', 'skipflags',
1283 default=None,
1286 default=None,
1284 )
1287 )
1285 coreconfigitem('web', 'allowbz2',
1288 coreconfigitem('web', 'allowbz2',
1286 default=False,
1289 default=False,
1287 )
1290 )
1288 coreconfigitem('web', 'allowgz',
1291 coreconfigitem('web', 'allowgz',
1289 default=False,
1292 default=False,
1290 )
1293 )
1291 coreconfigitem('web', 'allow-pull',
1294 coreconfigitem('web', 'allow-pull',
1292 alias=[('web', 'allowpull')],
1295 alias=[('web', 'allowpull')],
1293 default=True,
1296 default=True,
1294 )
1297 )
1295 coreconfigitem('web', 'allow-push',
1298 coreconfigitem('web', 'allow-push',
1296 alias=[('web', 'allow_push')],
1299 alias=[('web', 'allow_push')],
1297 default=list,
1300 default=list,
1298 )
1301 )
1299 coreconfigitem('web', 'allowzip',
1302 coreconfigitem('web', 'allowzip',
1300 default=False,
1303 default=False,
1301 )
1304 )
1302 coreconfigitem('web', 'archivesubrepos',
1305 coreconfigitem('web', 'archivesubrepos',
1303 default=False,
1306 default=False,
1304 )
1307 )
1305 coreconfigitem('web', 'cache',
1308 coreconfigitem('web', 'cache',
1306 default=True,
1309 default=True,
1307 )
1310 )
1308 coreconfigitem('web', 'comparisoncontext',
1311 coreconfigitem('web', 'comparisoncontext',
1309 default=5,
1312 default=5,
1310 )
1313 )
1311 coreconfigitem('web', 'contact',
1314 coreconfigitem('web', 'contact',
1312 default=None,
1315 default=None,
1313 )
1316 )
1314 coreconfigitem('web', 'deny_push',
1317 coreconfigitem('web', 'deny_push',
1315 default=list,
1318 default=list,
1316 )
1319 )
1317 coreconfigitem('web', 'guessmime',
1320 coreconfigitem('web', 'guessmime',
1318 default=False,
1321 default=False,
1319 )
1322 )
1320 coreconfigitem('web', 'hidden',
1323 coreconfigitem('web', 'hidden',
1321 default=False,
1324 default=False,
1322 )
1325 )
1323 coreconfigitem('web', 'labels',
1326 coreconfigitem('web', 'labels',
1324 default=list,
1327 default=list,
1325 )
1328 )
1326 coreconfigitem('web', 'logoimg',
1329 coreconfigitem('web', 'logoimg',
1327 default='hglogo.png',
1330 default='hglogo.png',
1328 )
1331 )
1329 coreconfigitem('web', 'logourl',
1332 coreconfigitem('web', 'logourl',
1330 default='https://mercurial-scm.org/',
1333 default='https://mercurial-scm.org/',
1331 )
1334 )
1332 coreconfigitem('web', 'accesslog',
1335 coreconfigitem('web', 'accesslog',
1333 default='-',
1336 default='-',
1334 )
1337 )
1335 coreconfigitem('web', 'address',
1338 coreconfigitem('web', 'address',
1336 default='',
1339 default='',
1337 )
1340 )
1338 coreconfigitem('web', 'allow-archive',
1341 coreconfigitem('web', 'allow-archive',
1339 alias=[('web', 'allow_archive')],
1342 alias=[('web', 'allow_archive')],
1340 default=list,
1343 default=list,
1341 )
1344 )
1342 coreconfigitem('web', 'allow_read',
1345 coreconfigitem('web', 'allow_read',
1343 default=list,
1346 default=list,
1344 )
1347 )
1345 coreconfigitem('web', 'baseurl',
1348 coreconfigitem('web', 'baseurl',
1346 default=None,
1349 default=None,
1347 )
1350 )
1348 coreconfigitem('web', 'cacerts',
1351 coreconfigitem('web', 'cacerts',
1349 default=None,
1352 default=None,
1350 )
1353 )
1351 coreconfigitem('web', 'certificate',
1354 coreconfigitem('web', 'certificate',
1352 default=None,
1355 default=None,
1353 )
1356 )
1354 coreconfigitem('web', 'collapse',
1357 coreconfigitem('web', 'collapse',
1355 default=False,
1358 default=False,
1356 )
1359 )
1357 coreconfigitem('web', 'csp',
1360 coreconfigitem('web', 'csp',
1358 default=None,
1361 default=None,
1359 )
1362 )
1360 coreconfigitem('web', 'deny_read',
1363 coreconfigitem('web', 'deny_read',
1361 default=list,
1364 default=list,
1362 )
1365 )
1363 coreconfigitem('web', 'descend',
1366 coreconfigitem('web', 'descend',
1364 default=True,
1367 default=True,
1365 )
1368 )
1366 coreconfigitem('web', 'description',
1369 coreconfigitem('web', 'description',
1367 default="",
1370 default="",
1368 )
1371 )
1369 coreconfigitem('web', 'encoding',
1372 coreconfigitem('web', 'encoding',
1370 default=lambda: encoding.encoding,
1373 default=lambda: encoding.encoding,
1371 )
1374 )
1372 coreconfigitem('web', 'errorlog',
1375 coreconfigitem('web', 'errorlog',
1373 default='-',
1376 default='-',
1374 )
1377 )
1375 coreconfigitem('web', 'ipv6',
1378 coreconfigitem('web', 'ipv6',
1376 default=False,
1379 default=False,
1377 )
1380 )
1378 coreconfigitem('web', 'maxchanges',
1381 coreconfigitem('web', 'maxchanges',
1379 default=10,
1382 default=10,
1380 )
1383 )
1381 coreconfigitem('web', 'maxfiles',
1384 coreconfigitem('web', 'maxfiles',
1382 default=10,
1385 default=10,
1383 )
1386 )
1384 coreconfigitem('web', 'maxshortchanges',
1387 coreconfigitem('web', 'maxshortchanges',
1385 default=60,
1388 default=60,
1386 )
1389 )
1387 coreconfigitem('web', 'motd',
1390 coreconfigitem('web', 'motd',
1388 default='',
1391 default='',
1389 )
1392 )
1390 coreconfigitem('web', 'name',
1393 coreconfigitem('web', 'name',
1391 default=dynamicdefault,
1394 default=dynamicdefault,
1392 )
1395 )
1393 coreconfigitem('web', 'port',
1396 coreconfigitem('web', 'port',
1394 default=8000,
1397 default=8000,
1395 )
1398 )
1396 coreconfigitem('web', 'prefix',
1399 coreconfigitem('web', 'prefix',
1397 default='',
1400 default='',
1398 )
1401 )
1399 coreconfigitem('web', 'push_ssl',
1402 coreconfigitem('web', 'push_ssl',
1400 default=True,
1403 default=True,
1401 )
1404 )
1402 coreconfigitem('web', 'refreshinterval',
1405 coreconfigitem('web', 'refreshinterval',
1403 default=20,
1406 default=20,
1404 )
1407 )
1405 coreconfigitem('web', 'server-header',
1408 coreconfigitem('web', 'server-header',
1406 default=None,
1409 default=None,
1407 )
1410 )
1408 coreconfigitem('web', 'static',
1411 coreconfigitem('web', 'static',
1409 default=None,
1412 default=None,
1410 )
1413 )
1411 coreconfigitem('web', 'staticurl',
1414 coreconfigitem('web', 'staticurl',
1412 default=None,
1415 default=None,
1413 )
1416 )
1414 coreconfigitem('web', 'stripes',
1417 coreconfigitem('web', 'stripes',
1415 default=1,
1418 default=1,
1416 )
1419 )
1417 coreconfigitem('web', 'style',
1420 coreconfigitem('web', 'style',
1418 default='paper',
1421 default='paper',
1419 )
1422 )
1420 coreconfigitem('web', 'templates',
1423 coreconfigitem('web', 'templates',
1421 default=None,
1424 default=None,
1422 )
1425 )
1423 coreconfigitem('web', 'view',
1426 coreconfigitem('web', 'view',
1424 default='served',
1427 default='served',
1425 )
1428 )
1426 coreconfigitem('worker', 'backgroundclose',
1429 coreconfigitem('worker', 'backgroundclose',
1427 default=dynamicdefault,
1430 default=dynamicdefault,
1428 )
1431 )
1429 # Windows defaults to a limit of 512 open files. A buffer of 128
1432 # Windows defaults to a limit of 512 open files. A buffer of 128
1430 # should give us enough headway.
1433 # should give us enough headway.
1431 coreconfigitem('worker', 'backgroundclosemaxqueue',
1434 coreconfigitem('worker', 'backgroundclosemaxqueue',
1432 default=384,
1435 default=384,
1433 )
1436 )
1434 coreconfigitem('worker', 'backgroundcloseminfilecount',
1437 coreconfigitem('worker', 'backgroundcloseminfilecount',
1435 default=2048,
1438 default=2048,
1436 )
1439 )
1437 coreconfigitem('worker', 'backgroundclosethreadcount',
1440 coreconfigitem('worker', 'backgroundclosethreadcount',
1438 default=4,
1441 default=4,
1439 )
1442 )
1440 coreconfigitem('worker', 'enabled',
1443 coreconfigitem('worker', 'enabled',
1441 default=True,
1444 default=True,
1442 )
1445 )
1443 coreconfigitem('worker', 'numcpus',
1446 coreconfigitem('worker', 'numcpus',
1444 default=None,
1447 default=None,
1445 )
1448 )
1446
1449
1447 # Rebase related configuration moved to core because other extension are doing
1450 # Rebase related configuration moved to core because other extension are doing
1448 # strange things. For example, shelve import the extensions to reuse some bit
1451 # strange things. For example, shelve import the extensions to reuse some bit
1449 # without formally loading it.
1452 # without formally loading it.
1450 coreconfigitem('commands', 'rebase.requiredest',
1453 coreconfigitem('commands', 'rebase.requiredest',
1451 default=False,
1454 default=False,
1452 )
1455 )
1453 coreconfigitem('experimental', 'rebaseskipobsolete',
1456 coreconfigitem('experimental', 'rebaseskipobsolete',
1454 default=True,
1457 default=True,
1455 )
1458 )
1456 coreconfigitem('rebase', 'singletransaction',
1459 coreconfigitem('rebase', 'singletransaction',
1457 default=False,
1460 default=False,
1458 )
1461 )
1459 coreconfigitem('rebase', 'experimental.inmemory',
1462 coreconfigitem('rebase', 'experimental.inmemory',
1460 default=False,
1463 default=False,
1461 )
1464 )
@@ -1,2817 +1,2823
1 The Mercurial system uses a set of configuration files to control
1 The Mercurial system uses a set of configuration files to control
2 aspects of its behavior.
2 aspects of its behavior.
3
3
4 Troubleshooting
4 Troubleshooting
5 ===============
5 ===============
6
6
7 If you're having problems with your configuration,
7 If you're having problems with your configuration,
8 :hg:`config --debug` can help you understand what is introducing
8 :hg:`config --debug` can help you understand what is introducing
9 a setting into your environment.
9 a setting into your environment.
10
10
11 See :hg:`help config.syntax` and :hg:`help config.files`
11 See :hg:`help config.syntax` and :hg:`help config.files`
12 for information about how and where to override things.
12 for information about how and where to override things.
13
13
14 Structure
14 Structure
15 =========
15 =========
16
16
17 The configuration files use a simple ini-file format. A configuration
17 The configuration files use a simple ini-file format. A configuration
18 file consists of sections, led by a ``[section]`` header and followed
18 file consists of sections, led by a ``[section]`` header and followed
19 by ``name = value`` entries::
19 by ``name = value`` entries::
20
20
21 [ui]
21 [ui]
22 username = Firstname Lastname <firstname.lastname@example.net>
22 username = Firstname Lastname <firstname.lastname@example.net>
23 verbose = True
23 verbose = True
24
24
25 The above entries will be referred to as ``ui.username`` and
25 The above entries will be referred to as ``ui.username`` and
26 ``ui.verbose``, respectively. See :hg:`help config.syntax`.
26 ``ui.verbose``, respectively. See :hg:`help config.syntax`.
27
27
28 Files
28 Files
29 =====
29 =====
30
30
31 Mercurial reads configuration data from several files, if they exist.
31 Mercurial reads configuration data from several files, if they exist.
32 These files do not exist by default and you will have to create the
32 These files do not exist by default and you will have to create the
33 appropriate configuration files yourself:
33 appropriate configuration files yourself:
34
34
35 Local configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
35 Local configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
36
36
37 Global configuration like the username setting is typically put into:
37 Global configuration like the username setting is typically put into:
38
38
39 .. container:: windows
39 .. container:: windows
40
40
41 - ``%USERPROFILE%\mercurial.ini`` (on Windows)
41 - ``%USERPROFILE%\mercurial.ini`` (on Windows)
42
42
43 .. container:: unix.plan9
43 .. container:: unix.plan9
44
44
45 - ``$HOME/.hgrc`` (on Unix, Plan9)
45 - ``$HOME/.hgrc`` (on Unix, Plan9)
46
46
47 The names of these files depend on the system on which Mercurial is
47 The names of these files depend on the system on which Mercurial is
48 installed. ``*.rc`` files from a single directory are read in
48 installed. ``*.rc`` files from a single directory are read in
49 alphabetical order, later ones overriding earlier ones. Where multiple
49 alphabetical order, later ones overriding earlier ones. Where multiple
50 paths are given below, settings from earlier paths override later
50 paths are given below, settings from earlier paths override later
51 ones.
51 ones.
52
52
53 .. container:: verbose.unix
53 .. container:: verbose.unix
54
54
55 On Unix, the following files are consulted:
55 On Unix, the following files are consulted:
56
56
57 - ``<repo>/.hg/hgrc`` (per-repository)
57 - ``<repo>/.hg/hgrc`` (per-repository)
58 - ``$HOME/.hgrc`` (per-user)
58 - ``$HOME/.hgrc`` (per-user)
59 - ``${XDG_CONFIG_HOME:-$HOME/.config}/hg/hgrc`` (per-user)
59 - ``${XDG_CONFIG_HOME:-$HOME/.config}/hg/hgrc`` (per-user)
60 - ``<install-root>/etc/mercurial/hgrc`` (per-installation)
60 - ``<install-root>/etc/mercurial/hgrc`` (per-installation)
61 - ``<install-root>/etc/mercurial/hgrc.d/*.rc`` (per-installation)
61 - ``<install-root>/etc/mercurial/hgrc.d/*.rc`` (per-installation)
62 - ``/etc/mercurial/hgrc`` (per-system)
62 - ``/etc/mercurial/hgrc`` (per-system)
63 - ``/etc/mercurial/hgrc.d/*.rc`` (per-system)
63 - ``/etc/mercurial/hgrc.d/*.rc`` (per-system)
64 - ``<internal>/default.d/*.rc`` (defaults)
64 - ``<internal>/default.d/*.rc`` (defaults)
65
65
66 .. container:: verbose.windows
66 .. container:: verbose.windows
67
67
68 On Windows, the following files are consulted:
68 On Windows, the following files are consulted:
69
69
70 - ``<repo>/.hg/hgrc`` (per-repository)
70 - ``<repo>/.hg/hgrc`` (per-repository)
71 - ``%USERPROFILE%\.hgrc`` (per-user)
71 - ``%USERPROFILE%\.hgrc`` (per-user)
72 - ``%USERPROFILE%\Mercurial.ini`` (per-user)
72 - ``%USERPROFILE%\Mercurial.ini`` (per-user)
73 - ``%HOME%\.hgrc`` (per-user)
73 - ``%HOME%\.hgrc`` (per-user)
74 - ``%HOME%\Mercurial.ini`` (per-user)
74 - ``%HOME%\Mercurial.ini`` (per-user)
75 - ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` (per-installation)
75 - ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` (per-installation)
76 - ``<install-dir>\hgrc.d\*.rc`` (per-installation)
76 - ``<install-dir>\hgrc.d\*.rc`` (per-installation)
77 - ``<install-dir>\Mercurial.ini`` (per-installation)
77 - ``<install-dir>\Mercurial.ini`` (per-installation)
78 - ``<internal>/default.d/*.rc`` (defaults)
78 - ``<internal>/default.d/*.rc`` (defaults)
79
79
80 .. note::
80 .. note::
81
81
82 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
82 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
83 is used when running 32-bit Python on 64-bit Windows.
83 is used when running 32-bit Python on 64-bit Windows.
84
84
85 .. container:: windows
85 .. container:: windows
86
86
87 On Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``.
87 On Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``.
88
88
89 .. container:: verbose.plan9
89 .. container:: verbose.plan9
90
90
91 On Plan9, the following files are consulted:
91 On Plan9, the following files are consulted:
92
92
93 - ``<repo>/.hg/hgrc`` (per-repository)
93 - ``<repo>/.hg/hgrc`` (per-repository)
94 - ``$home/lib/hgrc`` (per-user)
94 - ``$home/lib/hgrc`` (per-user)
95 - ``<install-root>/lib/mercurial/hgrc`` (per-installation)
95 - ``<install-root>/lib/mercurial/hgrc`` (per-installation)
96 - ``<install-root>/lib/mercurial/hgrc.d/*.rc`` (per-installation)
96 - ``<install-root>/lib/mercurial/hgrc.d/*.rc`` (per-installation)
97 - ``/lib/mercurial/hgrc`` (per-system)
97 - ``/lib/mercurial/hgrc`` (per-system)
98 - ``/lib/mercurial/hgrc.d/*.rc`` (per-system)
98 - ``/lib/mercurial/hgrc.d/*.rc`` (per-system)
99 - ``<internal>/default.d/*.rc`` (defaults)
99 - ``<internal>/default.d/*.rc`` (defaults)
100
100
101 Per-repository configuration options only apply in a
101 Per-repository configuration options only apply in a
102 particular repository. This file is not version-controlled, and
102 particular repository. This file is not version-controlled, and
103 will not get transferred during a "clone" operation. Options in
103 will not get transferred during a "clone" operation. Options in
104 this file override options in all other configuration files.
104 this file override options in all other configuration files.
105
105
106 .. container:: unix.plan9
106 .. container:: unix.plan9
107
107
108 On Plan 9 and Unix, most of this file will be ignored if it doesn't
108 On Plan 9 and Unix, most of this file will be ignored if it doesn't
109 belong to a trusted user or to a trusted group. See
109 belong to a trusted user or to a trusted group. See
110 :hg:`help config.trusted` for more details.
110 :hg:`help config.trusted` for more details.
111
111
112 Per-user configuration file(s) are for the user running Mercurial. Options
112 Per-user configuration file(s) are for the user running Mercurial. Options
113 in these files apply to all Mercurial commands executed by this user in any
113 in these files apply to all Mercurial commands executed by this user in any
114 directory. Options in these files override per-system and per-installation
114 directory. Options in these files override per-system and per-installation
115 options.
115 options.
116
116
117 Per-installation configuration files are searched for in the
117 Per-installation configuration files are searched for in the
118 directory where Mercurial is installed. ``<install-root>`` is the
118 directory where Mercurial is installed. ``<install-root>`` is the
119 parent directory of the **hg** executable (or symlink) being run.
119 parent directory of the **hg** executable (or symlink) being run.
120
120
121 .. container:: unix.plan9
121 .. container:: unix.plan9
122
122
123 For example, if installed in ``/shared/tools/bin/hg``, Mercurial
123 For example, if installed in ``/shared/tools/bin/hg``, Mercurial
124 will look in ``/shared/tools/etc/mercurial/hgrc``. Options in these
124 will look in ``/shared/tools/etc/mercurial/hgrc``. Options in these
125 files apply to all Mercurial commands executed by any user in any
125 files apply to all Mercurial commands executed by any user in any
126 directory.
126 directory.
127
127
128 Per-installation configuration files are for the system on
128 Per-installation configuration files are for the system on
129 which Mercurial is running. Options in these files apply to all
129 which Mercurial is running. Options in these files apply to all
130 Mercurial commands executed by any user in any directory. Registry
130 Mercurial commands executed by any user in any directory. Registry
131 keys contain PATH-like strings, every part of which must reference
131 keys contain PATH-like strings, every part of which must reference
132 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
132 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
133 be read. Mercurial checks each of these locations in the specified
133 be read. Mercurial checks each of these locations in the specified
134 order until one or more configuration files are detected.
134 order until one or more configuration files are detected.
135
135
136 Per-system configuration files are for the system on which Mercurial
136 Per-system configuration files are for the system on which Mercurial
137 is running. Options in these files apply to all Mercurial commands
137 is running. Options in these files apply to all Mercurial commands
138 executed by any user in any directory. Options in these files
138 executed by any user in any directory. Options in these files
139 override per-installation options.
139 override per-installation options.
140
140
141 Mercurial comes with some default configuration. The default configuration
141 Mercurial comes with some default configuration. The default configuration
142 files are installed with Mercurial and will be overwritten on upgrades. Default
142 files are installed with Mercurial and will be overwritten on upgrades. Default
143 configuration files should never be edited by users or administrators but can
143 configuration files should never be edited by users or administrators but can
144 be overridden in other configuration files. So far the directory only contains
144 be overridden in other configuration files. So far the directory only contains
145 merge tool configuration but packagers can also put other default configuration
145 merge tool configuration but packagers can also put other default configuration
146 there.
146 there.
147
147
148 Syntax
148 Syntax
149 ======
149 ======
150
150
151 A configuration file consists of sections, led by a ``[section]`` header
151 A configuration file consists of sections, led by a ``[section]`` header
152 and followed by ``name = value`` entries (sometimes called
152 and followed by ``name = value`` entries (sometimes called
153 ``configuration keys``)::
153 ``configuration keys``)::
154
154
155 [spam]
155 [spam]
156 eggs=ham
156 eggs=ham
157 green=
157 green=
158 eggs
158 eggs
159
159
160 Each line contains one entry. If the lines that follow are indented,
160 Each line contains one entry. If the lines that follow are indented,
161 they are treated as continuations of that entry. Leading whitespace is
161 they are treated as continuations of that entry. Leading whitespace is
162 removed from values. Empty lines are skipped. Lines beginning with
162 removed from values. Empty lines are skipped. Lines beginning with
163 ``#`` or ``;`` are ignored and may be used to provide comments.
163 ``#`` or ``;`` are ignored and may be used to provide comments.
164
164
165 Configuration keys can be set multiple times, in which case Mercurial
165 Configuration keys can be set multiple times, in which case Mercurial
166 will use the value that was configured last. As an example::
166 will use the value that was configured last. As an example::
167
167
168 [spam]
168 [spam]
169 eggs=large
169 eggs=large
170 ham=serrano
170 ham=serrano
171 eggs=small
171 eggs=small
172
172
173 This would set the configuration key named ``eggs`` to ``small``.
173 This would set the configuration key named ``eggs`` to ``small``.
174
174
175 It is also possible to define a section multiple times. A section can
175 It is also possible to define a section multiple times. A section can
176 be redefined on the same and/or on different configuration files. For
176 be redefined on the same and/or on different configuration files. For
177 example::
177 example::
178
178
179 [foo]
179 [foo]
180 eggs=large
180 eggs=large
181 ham=serrano
181 ham=serrano
182 eggs=small
182 eggs=small
183
183
184 [bar]
184 [bar]
185 eggs=ham
185 eggs=ham
186 green=
186 green=
187 eggs
187 eggs
188
188
189 [foo]
189 [foo]
190 ham=prosciutto
190 ham=prosciutto
191 eggs=medium
191 eggs=medium
192 bread=toasted
192 bread=toasted
193
193
194 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
194 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
195 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
195 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
196 respectively. As you can see there only thing that matters is the last
196 respectively. As you can see there only thing that matters is the last
197 value that was set for each of the configuration keys.
197 value that was set for each of the configuration keys.
198
198
199 If a configuration key is set multiple times in different
199 If a configuration key is set multiple times in different
200 configuration files the final value will depend on the order in which
200 configuration files the final value will depend on the order in which
201 the different configuration files are read, with settings from earlier
201 the different configuration files are read, with settings from earlier
202 paths overriding later ones as described on the ``Files`` section
202 paths overriding later ones as described on the ``Files`` section
203 above.
203 above.
204
204
205 A line of the form ``%include file`` will include ``file`` into the
205 A line of the form ``%include file`` will include ``file`` into the
206 current configuration file. The inclusion is recursive, which means
206 current configuration file. The inclusion is recursive, which means
207 that included files can include other files. Filenames are relative to
207 that included files can include other files. Filenames are relative to
208 the configuration file in which the ``%include`` directive is found.
208 the configuration file in which the ``%include`` directive is found.
209 Environment variables and ``~user`` constructs are expanded in
209 Environment variables and ``~user`` constructs are expanded in
210 ``file``. This lets you do something like::
210 ``file``. This lets you do something like::
211
211
212 %include ~/.hgrc.d/$HOST.rc
212 %include ~/.hgrc.d/$HOST.rc
213
213
214 to include a different configuration file on each computer you use.
214 to include a different configuration file on each computer you use.
215
215
216 A line with ``%unset name`` will remove ``name`` from the current
216 A line with ``%unset name`` will remove ``name`` from the current
217 section, if it has been set previously.
217 section, if it has been set previously.
218
218
219 The values are either free-form text strings, lists of text strings,
219 The values are either free-form text strings, lists of text strings,
220 or Boolean values. Boolean values can be set to true using any of "1",
220 or Boolean values. Boolean values can be set to true using any of "1",
221 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
221 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
222 (all case insensitive).
222 (all case insensitive).
223
223
224 List values are separated by whitespace or comma, except when values are
224 List values are separated by whitespace or comma, except when values are
225 placed in double quotation marks::
225 placed in double quotation marks::
226
226
227 allow_read = "John Doe, PhD", brian, betty
227 allow_read = "John Doe, PhD", brian, betty
228
228
229 Quotation marks can be escaped by prefixing them with a backslash. Only
229 Quotation marks can be escaped by prefixing them with a backslash. Only
230 quotation marks at the beginning of a word is counted as a quotation
230 quotation marks at the beginning of a word is counted as a quotation
231 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
231 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
232
232
233 Sections
233 Sections
234 ========
234 ========
235
235
236 This section describes the different sections that may appear in a
236 This section describes the different sections that may appear in a
237 Mercurial configuration file, the purpose of each section, its possible
237 Mercurial configuration file, the purpose of each section, its possible
238 keys, and their possible values.
238 keys, and their possible values.
239
239
240 ``alias``
240 ``alias``
241 ---------
241 ---------
242
242
243 Defines command aliases.
243 Defines command aliases.
244
244
245 Aliases allow you to define your own commands in terms of other
245 Aliases allow you to define your own commands in terms of other
246 commands (or aliases), optionally including arguments. Positional
246 commands (or aliases), optionally including arguments. Positional
247 arguments in the form of ``$1``, ``$2``, etc. in the alias definition
247 arguments in the form of ``$1``, ``$2``, etc. in the alias definition
248 are expanded by Mercurial before execution. Positional arguments not
248 are expanded by Mercurial before execution. Positional arguments not
249 already used by ``$N`` in the definition are put at the end of the
249 already used by ``$N`` in the definition are put at the end of the
250 command to be executed.
250 command to be executed.
251
251
252 Alias definitions consist of lines of the form::
252 Alias definitions consist of lines of the form::
253
253
254 <alias> = <command> [<argument>]...
254 <alias> = <command> [<argument>]...
255
255
256 For example, this definition::
256 For example, this definition::
257
257
258 latest = log --limit 5
258 latest = log --limit 5
259
259
260 creates a new command ``latest`` that shows only the five most recent
260 creates a new command ``latest`` that shows only the five most recent
261 changesets. You can define subsequent aliases using earlier ones::
261 changesets. You can define subsequent aliases using earlier ones::
262
262
263 stable5 = latest -b stable
263 stable5 = latest -b stable
264
264
265 .. note::
265 .. note::
266
266
267 It is possible to create aliases with the same names as
267 It is possible to create aliases with the same names as
268 existing commands, which will then override the original
268 existing commands, which will then override the original
269 definitions. This is almost always a bad idea!
269 definitions. This is almost always a bad idea!
270
270
271 An alias can start with an exclamation point (``!``) to make it a
271 An alias can start with an exclamation point (``!``) to make it a
272 shell alias. A shell alias is executed with the shell and will let you
272 shell alias. A shell alias is executed with the shell and will let you
273 run arbitrary commands. As an example, ::
273 run arbitrary commands. As an example, ::
274
274
275 echo = !echo $@
275 echo = !echo $@
276
276
277 will let you do ``hg echo foo`` to have ``foo`` printed in your
277 will let you do ``hg echo foo`` to have ``foo`` printed in your
278 terminal. A better example might be::
278 terminal. A better example might be::
279
279
280 purge = !$HG status --no-status --unknown -0 re: | xargs -0 rm -f
280 purge = !$HG status --no-status --unknown -0 re: | xargs -0 rm -f
281
281
282 which will make ``hg purge`` delete all unknown files in the
282 which will make ``hg purge`` delete all unknown files in the
283 repository in the same manner as the purge extension.
283 repository in the same manner as the purge extension.
284
284
285 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
285 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
286 expand to the command arguments. Unmatched arguments are
286 expand to the command arguments. Unmatched arguments are
287 removed. ``$0`` expands to the alias name and ``$@`` expands to all
287 removed. ``$0`` expands to the alias name and ``$@`` expands to all
288 arguments separated by a space. ``"$@"`` (with quotes) expands to all
288 arguments separated by a space. ``"$@"`` (with quotes) expands to all
289 arguments quoted individually and separated by a space. These expansions
289 arguments quoted individually and separated by a space. These expansions
290 happen before the command is passed to the shell.
290 happen before the command is passed to the shell.
291
291
292 Shell aliases are executed in an environment where ``$HG`` expands to
292 Shell aliases are executed in an environment where ``$HG`` expands to
293 the path of the Mercurial that was used to execute the alias. This is
293 the path of the Mercurial that was used to execute the alias. This is
294 useful when you want to call further Mercurial commands in a shell
294 useful when you want to call further Mercurial commands in a shell
295 alias, as was done above for the purge alias. In addition,
295 alias, as was done above for the purge alias. In addition,
296 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
296 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
297 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
297 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
298
298
299 .. note::
299 .. note::
300
300
301 Some global configuration options such as ``-R`` are
301 Some global configuration options such as ``-R`` are
302 processed before shell aliases and will thus not be passed to
302 processed before shell aliases and will thus not be passed to
303 aliases.
303 aliases.
304
304
305
305
306 ``annotate``
306 ``annotate``
307 ------------
307 ------------
308
308
309 Settings used when displaying file annotations. All values are
309 Settings used when displaying file annotations. All values are
310 Booleans and default to False. See :hg:`help config.diff` for
310 Booleans and default to False. See :hg:`help config.diff` for
311 related options for the diff command.
311 related options for the diff command.
312
312
313 ``ignorews``
313 ``ignorews``
314 Ignore white space when comparing lines.
314 Ignore white space when comparing lines.
315
315
316 ``ignorewseol``
316 ``ignorewseol``
317 Ignore white space at the end of a line when comparing lines.
317 Ignore white space at the end of a line when comparing lines.
318
318
319 ``ignorewsamount``
319 ``ignorewsamount``
320 Ignore changes in the amount of white space.
320 Ignore changes in the amount of white space.
321
321
322 ``ignoreblanklines``
322 ``ignoreblanklines``
323 Ignore changes whose lines are all blank.
323 Ignore changes whose lines are all blank.
324
324
325
325
326 ``auth``
326 ``auth``
327 --------
327 --------
328
328
329 Authentication credentials and other authentication-like configuration
329 Authentication credentials and other authentication-like configuration
330 for HTTP connections. This section allows you to store usernames and
330 for HTTP connections. This section allows you to store usernames and
331 passwords for use when logging *into* HTTP servers. See
331 passwords for use when logging *into* HTTP servers. See
332 :hg:`help config.web` if you want to configure *who* can login to
332 :hg:`help config.web` if you want to configure *who* can login to
333 your HTTP server.
333 your HTTP server.
334
334
335 The following options apply to all hosts.
335 The following options apply to all hosts.
336
336
337 ``cookiefile``
337 ``cookiefile``
338 Path to a file containing HTTP cookie lines. Cookies matching a
338 Path to a file containing HTTP cookie lines. Cookies matching a
339 host will be sent automatically.
339 host will be sent automatically.
340
340
341 The file format uses the Mozilla cookies.txt format, which defines cookies
341 The file format uses the Mozilla cookies.txt format, which defines cookies
342 on their own lines. Each line contains 7 fields delimited by the tab
342 on their own lines. Each line contains 7 fields delimited by the tab
343 character (domain, is_domain_cookie, path, is_secure, expires, name,
343 character (domain, is_domain_cookie, path, is_secure, expires, name,
344 value). For more info, do an Internet search for "Netscape cookies.txt
344 value). For more info, do an Internet search for "Netscape cookies.txt
345 format."
345 format."
346
346
347 Note: the cookies parser does not handle port numbers on domains. You
347 Note: the cookies parser does not handle port numbers on domains. You
348 will need to remove ports from the domain for the cookie to be recognized.
348 will need to remove ports from the domain for the cookie to be recognized.
349 This could result in a cookie being disclosed to an unwanted server.
349 This could result in a cookie being disclosed to an unwanted server.
350
350
351 The cookies file is read-only.
351 The cookies file is read-only.
352
352
353 Other options in this section are grouped by name and have the following
353 Other options in this section are grouped by name and have the following
354 format::
354 format::
355
355
356 <name>.<argument> = <value>
356 <name>.<argument> = <value>
357
357
358 where ``<name>`` is used to group arguments into authentication
358 where ``<name>`` is used to group arguments into authentication
359 entries. Example::
359 entries. Example::
360
360
361 foo.prefix = hg.intevation.de/mercurial
361 foo.prefix = hg.intevation.de/mercurial
362 foo.username = foo
362 foo.username = foo
363 foo.password = bar
363 foo.password = bar
364 foo.schemes = http https
364 foo.schemes = http https
365
365
366 bar.prefix = secure.example.org
366 bar.prefix = secure.example.org
367 bar.key = path/to/file.key
367 bar.key = path/to/file.key
368 bar.cert = path/to/file.cert
368 bar.cert = path/to/file.cert
369 bar.schemes = https
369 bar.schemes = https
370
370
371 Supported arguments:
371 Supported arguments:
372
372
373 ``prefix``
373 ``prefix``
374 Either ``*`` or a URI prefix with or without the scheme part.
374 Either ``*`` or a URI prefix with or without the scheme part.
375 The authentication entry with the longest matching prefix is used
375 The authentication entry with the longest matching prefix is used
376 (where ``*`` matches everything and counts as a match of length
376 (where ``*`` matches everything and counts as a match of length
377 1). If the prefix doesn't include a scheme, the match is performed
377 1). If the prefix doesn't include a scheme, the match is performed
378 against the URI with its scheme stripped as well, and the schemes
378 against the URI with its scheme stripped as well, and the schemes
379 argument, q.v., is then subsequently consulted.
379 argument, q.v., is then subsequently consulted.
380
380
381 ``username``
381 ``username``
382 Optional. Username to authenticate with. If not given, and the
382 Optional. Username to authenticate with. If not given, and the
383 remote site requires basic or digest authentication, the user will
383 remote site requires basic or digest authentication, the user will
384 be prompted for it. Environment variables are expanded in the
384 be prompted for it. Environment variables are expanded in the
385 username letting you do ``foo.username = $USER``. If the URI
385 username letting you do ``foo.username = $USER``. If the URI
386 includes a username, only ``[auth]`` entries with a matching
386 includes a username, only ``[auth]`` entries with a matching
387 username or without a username will be considered.
387 username or without a username will be considered.
388
388
389 ``password``
389 ``password``
390 Optional. Password to authenticate with. If not given, and the
390 Optional. Password to authenticate with. If not given, and the
391 remote site requires basic or digest authentication, the user
391 remote site requires basic or digest authentication, the user
392 will be prompted for it.
392 will be prompted for it.
393
393
394 ``key``
394 ``key``
395 Optional. PEM encoded client certificate key file. Environment
395 Optional. PEM encoded client certificate key file. Environment
396 variables are expanded in the filename.
396 variables are expanded in the filename.
397
397
398 ``cert``
398 ``cert``
399 Optional. PEM encoded client certificate chain file. Environment
399 Optional. PEM encoded client certificate chain file. Environment
400 variables are expanded in the filename.
400 variables are expanded in the filename.
401
401
402 ``schemes``
402 ``schemes``
403 Optional. Space separated list of URI schemes to use this
403 Optional. Space separated list of URI schemes to use this
404 authentication entry with. Only used if the prefix doesn't include
404 authentication entry with. Only used if the prefix doesn't include
405 a scheme. Supported schemes are http and https. They will match
405 a scheme. Supported schemes are http and https. They will match
406 static-http and static-https respectively, as well.
406 static-http and static-https respectively, as well.
407 (default: https)
407 (default: https)
408
408
409 If no suitable authentication entry is found, the user is prompted
409 If no suitable authentication entry is found, the user is prompted
410 for credentials as usual if required by the remote.
410 for credentials as usual if required by the remote.
411
411
412 ``color``
412 ``color``
413 ---------
413 ---------
414
414
415 Configure the Mercurial color mode. For details about how to define your custom
415 Configure the Mercurial color mode. For details about how to define your custom
416 effect and style see :hg:`help color`.
416 effect and style see :hg:`help color`.
417
417
418 ``mode``
418 ``mode``
419 String: control the method used to output color. One of ``auto``, ``ansi``,
419 String: control the method used to output color. One of ``auto``, ``ansi``,
420 ``win32``, ``terminfo`` or ``debug``. In auto mode, Mercurial will
420 ``win32``, ``terminfo`` or ``debug``. In auto mode, Mercurial will
421 use ANSI mode by default (or win32 mode prior to Windows 10) if it detects a
421 use ANSI mode by default (or win32 mode prior to Windows 10) if it detects a
422 terminal. Any invalid value will disable color.
422 terminal. Any invalid value will disable color.
423
423
424 ``pagermode``
424 ``pagermode``
425 String: optional override of ``color.mode`` used with pager.
425 String: optional override of ``color.mode`` used with pager.
426
426
427 On some systems, terminfo mode may cause problems when using
427 On some systems, terminfo mode may cause problems when using
428 color with ``less -R`` as a pager program. less with the -R option
428 color with ``less -R`` as a pager program. less with the -R option
429 will only display ECMA-48 color codes, and terminfo mode may sometimes
429 will only display ECMA-48 color codes, and terminfo mode may sometimes
430 emit codes that less doesn't understand. You can work around this by
430 emit codes that less doesn't understand. You can work around this by
431 either using ansi mode (or auto mode), or by using less -r (which will
431 either using ansi mode (or auto mode), or by using less -r (which will
432 pass through all terminal control codes, not just color control
432 pass through all terminal control codes, not just color control
433 codes).
433 codes).
434
434
435 On some systems (such as MSYS in Windows), the terminal may support
435 On some systems (such as MSYS in Windows), the terminal may support
436 a different color mode than the pager program.
436 a different color mode than the pager program.
437
437
438 ``commands``
438 ``commands``
439 ------------
439 ------------
440
440
441 ``resolve.confirm``
441 ``resolve.confirm``
442 Confirm before performing action if no filename is passed.
442 Confirm before performing action if no filename is passed.
443 (default: False)
443 (default: False)
444
444
445 ``resolve.explicit-re-merge``
445 ``resolve.explicit-re-merge``
446 Require uses of ``hg resolve`` to specify which action it should perform,
446 Require uses of ``hg resolve`` to specify which action it should perform,
447 instead of re-merging files by default.
447 instead of re-merging files by default.
448 (default: False)
448 (default: False)
449
449
450 ``resolve.mark-check``
450 ``resolve.mark-check``
451 Determines what level of checking :hg:`resolve --mark` will perform before
451 Determines what level of checking :hg:`resolve --mark` will perform before
452 marking files as resolved. Valid values are ``none`, ``warn``, and
452 marking files as resolved. Valid values are ``none`, ``warn``, and
453 ``abort``. ``warn`` will output a warning listing the file(s) that still
453 ``abort``. ``warn`` will output a warning listing the file(s) that still
454 have conflict markers in them, but will still mark everything resolved.
454 have conflict markers in them, but will still mark everything resolved.
455 ``abort`` will output the same warning but will not mark things as resolved.
455 ``abort`` will output the same warning but will not mark things as resolved.
456 If --all is passed and this is set to ``abort``, only a warning will be
456 If --all is passed and this is set to ``abort``, only a warning will be
457 shown (an error will not be raised).
457 shown (an error will not be raised).
458 (default: ``none``)
458 (default: ``none``)
459
459
460 ``status.relative``
460 ``status.relative``
461 Make paths in :hg:`status` output relative to the current directory.
461 Make paths in :hg:`status` output relative to the current directory.
462 (default: False)
462 (default: False)
463
463
464 ``status.terse``
464 ``status.terse``
465 Default value for the --terse flag, which condenses status output.
465 Default value for the --terse flag, which condenses status output.
466 (default: empty)
466 (default: empty)
467
467
468 ``update.check``
468 ``update.check``
469 Determines what level of checking :hg:`update` will perform before moving
469 Determines what level of checking :hg:`update` will perform before moving
470 to a destination revision. Valid values are ``abort``, ``none``,
470 to a destination revision. Valid values are ``abort``, ``none``,
471 ``linear``, and ``noconflict``. ``abort`` always fails if the working
471 ``linear``, and ``noconflict``. ``abort`` always fails if the working
472 directory has uncommitted changes. ``none`` performs no checking, and may
472 directory has uncommitted changes. ``none`` performs no checking, and may
473 result in a merge with uncommitted changes. ``linear`` allows any update
473 result in a merge with uncommitted changes. ``linear`` allows any update
474 as long as it follows a straight line in the revision history, and may
474 as long as it follows a straight line in the revision history, and may
475 trigger a merge with uncommitted changes. ``noconflict`` will allow any
475 trigger a merge with uncommitted changes. ``noconflict`` will allow any
476 update which would not trigger a merge with uncommitted changes, if any
476 update which would not trigger a merge with uncommitted changes, if any
477 are present.
477 are present.
478 (default: ``linear``)
478 (default: ``linear``)
479
479
480 ``update.requiredest``
480 ``update.requiredest``
481 Require that the user pass a destination when running :hg:`update`.
481 Require that the user pass a destination when running :hg:`update`.
482 For example, :hg:`update .::` will be allowed, but a plain :hg:`update`
482 For example, :hg:`update .::` will be allowed, but a plain :hg:`update`
483 will be disallowed.
483 will be disallowed.
484 (default: False)
484 (default: False)
485
485
486 ``committemplate``
486 ``committemplate``
487 ------------------
487 ------------------
488
488
489 ``changeset``
489 ``changeset``
490 String: configuration in this section is used as the template to
490 String: configuration in this section is used as the template to
491 customize the text shown in the editor when committing.
491 customize the text shown in the editor when committing.
492
492
493 In addition to pre-defined template keywords, commit log specific one
493 In addition to pre-defined template keywords, commit log specific one
494 below can be used for customization:
494 below can be used for customization:
495
495
496 ``extramsg``
496 ``extramsg``
497 String: Extra message (typically 'Leave message empty to abort
497 String: Extra message (typically 'Leave message empty to abort
498 commit.'). This may be changed by some commands or extensions.
498 commit.'). This may be changed by some commands or extensions.
499
499
500 For example, the template configuration below shows as same text as
500 For example, the template configuration below shows as same text as
501 one shown by default::
501 one shown by default::
502
502
503 [committemplate]
503 [committemplate]
504 changeset = {desc}\n\n
504 changeset = {desc}\n\n
505 HG: Enter commit message. Lines beginning with 'HG:' are removed.
505 HG: Enter commit message. Lines beginning with 'HG:' are removed.
506 HG: {extramsg}
506 HG: {extramsg}
507 HG: --
507 HG: --
508 HG: user: {author}\n{ifeq(p2rev, "-1", "",
508 HG: user: {author}\n{ifeq(p2rev, "-1", "",
509 "HG: branch merge\n")
509 "HG: branch merge\n")
510 }HG: branch '{branch}'\n{if(activebookmark,
510 }HG: branch '{branch}'\n{if(activebookmark,
511 "HG: bookmark '{activebookmark}'\n") }{subrepos %
511 "HG: bookmark '{activebookmark}'\n") }{subrepos %
512 "HG: subrepo {subrepo}\n" }{file_adds %
512 "HG: subrepo {subrepo}\n" }{file_adds %
513 "HG: added {file}\n" }{file_mods %
513 "HG: added {file}\n" }{file_mods %
514 "HG: changed {file}\n" }{file_dels %
514 "HG: changed {file}\n" }{file_dels %
515 "HG: removed {file}\n" }{if(files, "",
515 "HG: removed {file}\n" }{if(files, "",
516 "HG: no files changed\n")}
516 "HG: no files changed\n")}
517
517
518 ``diff()``
518 ``diff()``
519 String: show the diff (see :hg:`help templates` for detail)
519 String: show the diff (see :hg:`help templates` for detail)
520
520
521 Sometimes it is helpful to show the diff of the changeset in the editor without
521 Sometimes it is helpful to show the diff of the changeset in the editor without
522 having to prefix 'HG: ' to each line so that highlighting works correctly. For
522 having to prefix 'HG: ' to each line so that highlighting works correctly. For
523 this, Mercurial provides a special string which will ignore everything below
523 this, Mercurial provides a special string which will ignore everything below
524 it::
524 it::
525
525
526 HG: ------------------------ >8 ------------------------
526 HG: ------------------------ >8 ------------------------
527
527
528 For example, the template configuration below will show the diff below the
528 For example, the template configuration below will show the diff below the
529 extra message::
529 extra message::
530
530
531 [committemplate]
531 [committemplate]
532 changeset = {desc}\n\n
532 changeset = {desc}\n\n
533 HG: Enter commit message. Lines beginning with 'HG:' are removed.
533 HG: Enter commit message. Lines beginning with 'HG:' are removed.
534 HG: {extramsg}
534 HG: {extramsg}
535 HG: ------------------------ >8 ------------------------
535 HG: ------------------------ >8 ------------------------
536 HG: Do not touch the line above.
536 HG: Do not touch the line above.
537 HG: Everything below will be removed.
537 HG: Everything below will be removed.
538 {diff()}
538 {diff()}
539
539
540 .. note::
540 .. note::
541
541
542 For some problematic encodings (see :hg:`help win32mbcs` for
542 For some problematic encodings (see :hg:`help win32mbcs` for
543 detail), this customization should be configured carefully, to
543 detail), this customization should be configured carefully, to
544 avoid showing broken characters.
544 avoid showing broken characters.
545
545
546 For example, if a multibyte character ending with backslash (0x5c) is
546 For example, if a multibyte character ending with backslash (0x5c) is
547 followed by the ASCII character 'n' in the customized template,
547 followed by the ASCII character 'n' in the customized template,
548 the sequence of backslash and 'n' is treated as line-feed unexpectedly
548 the sequence of backslash and 'n' is treated as line-feed unexpectedly
549 (and the multibyte character is broken, too).
549 (and the multibyte character is broken, too).
550
550
551 Customized template is used for commands below (``--edit`` may be
551 Customized template is used for commands below (``--edit`` may be
552 required):
552 required):
553
553
554 - :hg:`backout`
554 - :hg:`backout`
555 - :hg:`commit`
555 - :hg:`commit`
556 - :hg:`fetch` (for merge commit only)
556 - :hg:`fetch` (for merge commit only)
557 - :hg:`graft`
557 - :hg:`graft`
558 - :hg:`histedit`
558 - :hg:`histedit`
559 - :hg:`import`
559 - :hg:`import`
560 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
560 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
561 - :hg:`rebase`
561 - :hg:`rebase`
562 - :hg:`shelve`
562 - :hg:`shelve`
563 - :hg:`sign`
563 - :hg:`sign`
564 - :hg:`tag`
564 - :hg:`tag`
565 - :hg:`transplant`
565 - :hg:`transplant`
566
566
567 Configuring items below instead of ``changeset`` allows showing
567 Configuring items below instead of ``changeset`` allows showing
568 customized message only for specific actions, or showing different
568 customized message only for specific actions, or showing different
569 messages for each action.
569 messages for each action.
570
570
571 - ``changeset.backout`` for :hg:`backout`
571 - ``changeset.backout`` for :hg:`backout`
572 - ``changeset.commit.amend.merge`` for :hg:`commit --amend` on merges
572 - ``changeset.commit.amend.merge`` for :hg:`commit --amend` on merges
573 - ``changeset.commit.amend.normal`` for :hg:`commit --amend` on other
573 - ``changeset.commit.amend.normal`` for :hg:`commit --amend` on other
574 - ``changeset.commit.normal.merge`` for :hg:`commit` on merges
574 - ``changeset.commit.normal.merge`` for :hg:`commit` on merges
575 - ``changeset.commit.normal.normal`` for :hg:`commit` on other
575 - ``changeset.commit.normal.normal`` for :hg:`commit` on other
576 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
576 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
577 - ``changeset.gpg.sign`` for :hg:`sign`
577 - ``changeset.gpg.sign`` for :hg:`sign`
578 - ``changeset.graft`` for :hg:`graft`
578 - ``changeset.graft`` for :hg:`graft`
579 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
579 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
580 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
580 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
581 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
581 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
582 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
582 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
583 - ``changeset.import.bypass`` for :hg:`import --bypass`
583 - ``changeset.import.bypass`` for :hg:`import --bypass`
584 - ``changeset.import.normal.merge`` for :hg:`import` on merges
584 - ``changeset.import.normal.merge`` for :hg:`import` on merges
585 - ``changeset.import.normal.normal`` for :hg:`import` on other
585 - ``changeset.import.normal.normal`` for :hg:`import` on other
586 - ``changeset.mq.qnew`` for :hg:`qnew`
586 - ``changeset.mq.qnew`` for :hg:`qnew`
587 - ``changeset.mq.qfold`` for :hg:`qfold`
587 - ``changeset.mq.qfold`` for :hg:`qfold`
588 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
588 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
589 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
589 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
590 - ``changeset.rebase.merge`` for :hg:`rebase` on merges
590 - ``changeset.rebase.merge`` for :hg:`rebase` on merges
591 - ``changeset.rebase.normal`` for :hg:`rebase` on other
591 - ``changeset.rebase.normal`` for :hg:`rebase` on other
592 - ``changeset.shelve.shelve`` for :hg:`shelve`
592 - ``changeset.shelve.shelve`` for :hg:`shelve`
593 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
593 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
594 - ``changeset.tag.remove`` for :hg:`tag --remove`
594 - ``changeset.tag.remove`` for :hg:`tag --remove`
595 - ``changeset.transplant.merge`` for :hg:`transplant` on merges
595 - ``changeset.transplant.merge`` for :hg:`transplant` on merges
596 - ``changeset.transplant.normal`` for :hg:`transplant` on other
596 - ``changeset.transplant.normal`` for :hg:`transplant` on other
597
597
598 These dot-separated lists of names are treated as hierarchical ones.
598 These dot-separated lists of names are treated as hierarchical ones.
599 For example, ``changeset.tag.remove`` customizes the commit message
599 For example, ``changeset.tag.remove`` customizes the commit message
600 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
600 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
601 commit message for :hg:`tag` regardless of ``--remove`` option.
601 commit message for :hg:`tag` regardless of ``--remove`` option.
602
602
603 When the external editor is invoked for a commit, the corresponding
603 When the external editor is invoked for a commit, the corresponding
604 dot-separated list of names without the ``changeset.`` prefix
604 dot-separated list of names without the ``changeset.`` prefix
605 (e.g. ``commit.normal.normal``) is in the ``HGEDITFORM`` environment
605 (e.g. ``commit.normal.normal``) is in the ``HGEDITFORM`` environment
606 variable.
606 variable.
607
607
608 In this section, items other than ``changeset`` can be referred from
608 In this section, items other than ``changeset`` can be referred from
609 others. For example, the configuration to list committed files up
609 others. For example, the configuration to list committed files up
610 below can be referred as ``{listupfiles}``::
610 below can be referred as ``{listupfiles}``::
611
611
612 [committemplate]
612 [committemplate]
613 listupfiles = {file_adds %
613 listupfiles = {file_adds %
614 "HG: added {file}\n" }{file_mods %
614 "HG: added {file}\n" }{file_mods %
615 "HG: changed {file}\n" }{file_dels %
615 "HG: changed {file}\n" }{file_dels %
616 "HG: removed {file}\n" }{if(files, "",
616 "HG: removed {file}\n" }{if(files, "",
617 "HG: no files changed\n")}
617 "HG: no files changed\n")}
618
618
619 ``decode/encode``
619 ``decode/encode``
620 -----------------
620 -----------------
621
621
622 Filters for transforming files on checkout/checkin. This would
622 Filters for transforming files on checkout/checkin. This would
623 typically be used for newline processing or other
623 typically be used for newline processing or other
624 localization/canonicalization of files.
624 localization/canonicalization of files.
625
625
626 Filters consist of a filter pattern followed by a filter command.
626 Filters consist of a filter pattern followed by a filter command.
627 Filter patterns are globs by default, rooted at the repository root.
627 Filter patterns are globs by default, rooted at the repository root.
628 For example, to match any file ending in ``.txt`` in the root
628 For example, to match any file ending in ``.txt`` in the root
629 directory only, use the pattern ``*.txt``. To match any file ending
629 directory only, use the pattern ``*.txt``. To match any file ending
630 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
630 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
631 For each file only the first matching filter applies.
631 For each file only the first matching filter applies.
632
632
633 The filter command can start with a specifier, either ``pipe:`` or
633 The filter command can start with a specifier, either ``pipe:`` or
634 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
634 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
635
635
636 A ``pipe:`` command must accept data on stdin and return the transformed
636 A ``pipe:`` command must accept data on stdin and return the transformed
637 data on stdout.
637 data on stdout.
638
638
639 Pipe example::
639 Pipe example::
640
640
641 [encode]
641 [encode]
642 # uncompress gzip files on checkin to improve delta compression
642 # uncompress gzip files on checkin to improve delta compression
643 # note: not necessarily a good idea, just an example
643 # note: not necessarily a good idea, just an example
644 *.gz = pipe: gunzip
644 *.gz = pipe: gunzip
645
645
646 [decode]
646 [decode]
647 # recompress gzip files when writing them to the working dir (we
647 # recompress gzip files when writing them to the working dir (we
648 # can safely omit "pipe:", because it's the default)
648 # can safely omit "pipe:", because it's the default)
649 *.gz = gzip
649 *.gz = gzip
650
650
651 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
651 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
652 with the name of a temporary file that contains the data to be
652 with the name of a temporary file that contains the data to be
653 filtered by the command. The string ``OUTFILE`` is replaced with the name
653 filtered by the command. The string ``OUTFILE`` is replaced with the name
654 of an empty temporary file, where the filtered data must be written by
654 of an empty temporary file, where the filtered data must be written by
655 the command.
655 the command.
656
656
657 .. container:: windows
657 .. container:: windows
658
658
659 .. note::
659 .. note::
660
660
661 The tempfile mechanism is recommended for Windows systems,
661 The tempfile mechanism is recommended for Windows systems,
662 where the standard shell I/O redirection operators often have
662 where the standard shell I/O redirection operators often have
663 strange effects and may corrupt the contents of your files.
663 strange effects and may corrupt the contents of your files.
664
664
665 This filter mechanism is used internally by the ``eol`` extension to
665 This filter mechanism is used internally by the ``eol`` extension to
666 translate line ending characters between Windows (CRLF) and Unix (LF)
666 translate line ending characters between Windows (CRLF) and Unix (LF)
667 format. We suggest you use the ``eol`` extension for convenience.
667 format. We suggest you use the ``eol`` extension for convenience.
668
668
669
669
670 ``defaults``
670 ``defaults``
671 ------------
671 ------------
672
672
673 (defaults are deprecated. Don't use them. Use aliases instead.)
673 (defaults are deprecated. Don't use them. Use aliases instead.)
674
674
675 Use the ``[defaults]`` section to define command defaults, i.e. the
675 Use the ``[defaults]`` section to define command defaults, i.e. the
676 default options/arguments to pass to the specified commands.
676 default options/arguments to pass to the specified commands.
677
677
678 The following example makes :hg:`log` run in verbose mode, and
678 The following example makes :hg:`log` run in verbose mode, and
679 :hg:`status` show only the modified files, by default::
679 :hg:`status` show only the modified files, by default::
680
680
681 [defaults]
681 [defaults]
682 log = -v
682 log = -v
683 status = -m
683 status = -m
684
684
685 The actual commands, instead of their aliases, must be used when
685 The actual commands, instead of their aliases, must be used when
686 defining command defaults. The command defaults will also be applied
686 defining command defaults. The command defaults will also be applied
687 to the aliases of the commands defined.
687 to the aliases of the commands defined.
688
688
689
689
690 ``diff``
690 ``diff``
691 --------
691 --------
692
692
693 Settings used when displaying diffs. Everything except for ``unified``
693 Settings used when displaying diffs. Everything except for ``unified``
694 is a Boolean and defaults to False. See :hg:`help config.annotate`
694 is a Boolean and defaults to False. See :hg:`help config.annotate`
695 for related options for the annotate command.
695 for related options for the annotate command.
696
696
697 ``git``
697 ``git``
698 Use git extended diff format.
698 Use git extended diff format.
699
699
700 ``nobinary``
700 ``nobinary``
701 Omit git binary patches.
701 Omit git binary patches.
702
702
703 ``nodates``
703 ``nodates``
704 Don't include dates in diff headers.
704 Don't include dates in diff headers.
705
705
706 ``noprefix``
706 ``noprefix``
707 Omit 'a/' and 'b/' prefixes from filenames. Ignored in plain mode.
707 Omit 'a/' and 'b/' prefixes from filenames. Ignored in plain mode.
708
708
709 ``showfunc``
709 ``showfunc``
710 Show which function each change is in.
710 Show which function each change is in.
711
711
712 ``ignorews``
712 ``ignorews``
713 Ignore white space when comparing lines.
713 Ignore white space when comparing lines.
714
714
715 ``ignorewsamount``
715 ``ignorewsamount``
716 Ignore changes in the amount of white space.
716 Ignore changes in the amount of white space.
717
717
718 ``ignoreblanklines``
718 ``ignoreblanklines``
719 Ignore changes whose lines are all blank.
719 Ignore changes whose lines are all blank.
720
720
721 ``unified``
721 ``unified``
722 Number of lines of context to show.
722 Number of lines of context to show.
723
723
724 ``word-diff``
724 ``word-diff``
725 Highlight changed words.
725 Highlight changed words.
726
726
727 ``email``
727 ``email``
728 ---------
728 ---------
729
729
730 Settings for extensions that send email messages.
730 Settings for extensions that send email messages.
731
731
732 ``from``
732 ``from``
733 Optional. Email address to use in "From" header and SMTP envelope
733 Optional. Email address to use in "From" header and SMTP envelope
734 of outgoing messages.
734 of outgoing messages.
735
735
736 ``to``
736 ``to``
737 Optional. Comma-separated list of recipients' email addresses.
737 Optional. Comma-separated list of recipients' email addresses.
738
738
739 ``cc``
739 ``cc``
740 Optional. Comma-separated list of carbon copy recipients'
740 Optional. Comma-separated list of carbon copy recipients'
741 email addresses.
741 email addresses.
742
742
743 ``bcc``
743 ``bcc``
744 Optional. Comma-separated list of blind carbon copy recipients'
744 Optional. Comma-separated list of blind carbon copy recipients'
745 email addresses.
745 email addresses.
746
746
747 ``method``
747 ``method``
748 Optional. Method to use to send email messages. If value is ``smtp``
748 Optional. Method to use to send email messages. If value is ``smtp``
749 (default), use SMTP (see the ``[smtp]`` section for configuration).
749 (default), use SMTP (see the ``[smtp]`` section for configuration).
750 Otherwise, use as name of program to run that acts like sendmail
750 Otherwise, use as name of program to run that acts like sendmail
751 (takes ``-f`` option for sender, list of recipients on command line,
751 (takes ``-f`` option for sender, list of recipients on command line,
752 message on stdin). Normally, setting this to ``sendmail`` or
752 message on stdin). Normally, setting this to ``sendmail`` or
753 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
753 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
754
754
755 ``charsets``
755 ``charsets``
756 Optional. Comma-separated list of character sets considered
756 Optional. Comma-separated list of character sets considered
757 convenient for recipients. Addresses, headers, and parts not
757 convenient for recipients. Addresses, headers, and parts not
758 containing patches of outgoing messages will be encoded in the
758 containing patches of outgoing messages will be encoded in the
759 first character set to which conversion from local encoding
759 first character set to which conversion from local encoding
760 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
760 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
761 conversion fails, the text in question is sent as is.
761 conversion fails, the text in question is sent as is.
762 (default: '')
762 (default: '')
763
763
764 Order of outgoing email character sets:
764 Order of outgoing email character sets:
765
765
766 1. ``us-ascii``: always first, regardless of settings
766 1. ``us-ascii``: always first, regardless of settings
767 2. ``email.charsets``: in order given by user
767 2. ``email.charsets``: in order given by user
768 3. ``ui.fallbackencoding``: if not in email.charsets
768 3. ``ui.fallbackencoding``: if not in email.charsets
769 4. ``$HGENCODING``: if not in email.charsets
769 4. ``$HGENCODING``: if not in email.charsets
770 5. ``utf-8``: always last, regardless of settings
770 5. ``utf-8``: always last, regardless of settings
771
771
772 Email example::
772 Email example::
773
773
774 [email]
774 [email]
775 from = Joseph User <joe.user@example.com>
775 from = Joseph User <joe.user@example.com>
776 method = /usr/sbin/sendmail
776 method = /usr/sbin/sendmail
777 # charsets for western Europeans
777 # charsets for western Europeans
778 # us-ascii, utf-8 omitted, as they are tried first and last
778 # us-ascii, utf-8 omitted, as they are tried first and last
779 charsets = iso-8859-1, iso-8859-15, windows-1252
779 charsets = iso-8859-1, iso-8859-15, windows-1252
780
780
781
781
782 ``extensions``
782 ``extensions``
783 --------------
783 --------------
784
784
785 Mercurial has an extension mechanism for adding new features. To
785 Mercurial has an extension mechanism for adding new features. To
786 enable an extension, create an entry for it in this section.
786 enable an extension, create an entry for it in this section.
787
787
788 If you know that the extension is already in Python's search path,
788 If you know that the extension is already in Python's search path,
789 you can give the name of the module, followed by ``=``, with nothing
789 you can give the name of the module, followed by ``=``, with nothing
790 after the ``=``.
790 after the ``=``.
791
791
792 Otherwise, give a name that you choose, followed by ``=``, followed by
792 Otherwise, give a name that you choose, followed by ``=``, followed by
793 the path to the ``.py`` file (including the file name extension) that
793 the path to the ``.py`` file (including the file name extension) that
794 defines the extension.
794 defines the extension.
795
795
796 To explicitly disable an extension that is enabled in an hgrc of
796 To explicitly disable an extension that is enabled in an hgrc of
797 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
797 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
798 or ``foo = !`` when path is not supplied.
798 or ``foo = !`` when path is not supplied.
799
799
800 Example for ``~/.hgrc``::
800 Example for ``~/.hgrc``::
801
801
802 [extensions]
802 [extensions]
803 # (the churn extension will get loaded from Mercurial's path)
803 # (the churn extension will get loaded from Mercurial's path)
804 churn =
804 churn =
805 # (this extension will get loaded from the file specified)
805 # (this extension will get loaded from the file specified)
806 myfeature = ~/.hgext/myfeature.py
806 myfeature = ~/.hgext/myfeature.py
807
807
808
808
809 ``format``
809 ``format``
810 ----------
810 ----------
811
811
812 Configuration that controls the repository format. Newer format options are more
812 Configuration that controls the repository format. Newer format options are more
813 powerful but incompatible with some older versions of Mercurial. Format options
813 powerful but incompatible with some older versions of Mercurial. Format options
814 are considered at repository initialization only. You need to make a new clone
814 are considered at repository initialization only. You need to make a new clone
815 for config change to be taken into account.
815 for config change to be taken into account.
816
816
817 For more details about repository format and version compatibility, see
817 For more details about repository format and version compatibility, see
818 https://www.mercurial-scm.org/wiki/MissingRequirement
818 https://www.mercurial-scm.org/wiki/MissingRequirement
819
819
820 ``usegeneraldelta``
820 ``usegeneraldelta``
821 Enable or disable the "generaldelta" repository format which improves
821 Enable or disable the "generaldelta" repository format which improves
822 repository compression by allowing "revlog" to store delta against arbitrary
822 repository compression by allowing "revlog" to store delta against arbitrary
823 revision instead of the previous stored one. This provides significant
823 revision instead of the previous stored one. This provides significant
824 improvement for repositories with branches.
824 improvement for repositories with branches.
825
825
826 Repositories with this on-disk format require Mercurial version 1.9.
826 Repositories with this on-disk format require Mercurial version 1.9.
827
827
828 Enabled by default.
828 Enabled by default.
829
829
830 ``dotencode``
830 ``dotencode``
831 Enable or disable the "dotencode" repository format which enhances
831 Enable or disable the "dotencode" repository format which enhances
832 the "fncache" repository format (which has to be enabled to use
832 the "fncache" repository format (which has to be enabled to use
833 dotencode) to avoid issues with filenames starting with ._ on
833 dotencode) to avoid issues with filenames starting with ._ on
834 Mac OS X and spaces on Windows.
834 Mac OS X and spaces on Windows.
835
835
836 Repositories with this on-disk format require Mercurial version 1.7.
836 Repositories with this on-disk format require Mercurial version 1.7.
837
837
838 Enabled by default.
838 Enabled by default.
839
839
840 ``usefncache``
840 ``usefncache``
841 Enable or disable the "fncache" repository format which enhances
841 Enable or disable the "fncache" repository format which enhances
842 the "store" repository format (which has to be enabled to use
842 the "store" repository format (which has to be enabled to use
843 fncache) to allow longer filenames and avoids using Windows
843 fncache) to allow longer filenames and avoids using Windows
844 reserved names, e.g. "nul".
844 reserved names, e.g. "nul".
845
845
846 Repositories with this on-disk format require Mercurial version 1.1.
846 Repositories with this on-disk format require Mercurial version 1.1.
847
847
848 Enabled by default.
848 Enabled by default.
849
849
850 ``usestore``
850 ``usestore``
851 Enable or disable the "store" repository format which improves
851 Enable or disable the "store" repository format which improves
852 compatibility with systems that fold case or otherwise mangle
852 compatibility with systems that fold case or otherwise mangle
853 filenames. Disabling this option will allow you to store longer filenames
853 filenames. Disabling this option will allow you to store longer filenames
854 in some situations at the expense of compatibility.
854 in some situations at the expense of compatibility.
855
855
856 Repositories with this on-disk format require Mercurial version 0.9.4.
856 Repositories with this on-disk format require Mercurial version 0.9.4.
857
857
858 Enabled by default.
858 Enabled by default.
859
859
860 ``sparse-revlog``
860 ``sparse-revlog``
861 Enable or disable the ``sparse-revlog`` delta strategy. This format improves
861 Enable or disable the ``sparse-revlog`` delta strategy. This format improves
862 delta re-use inside revlog. For very branchy repositories, it results in a
862 delta re-use inside revlog. For very branchy repositories, it results in a
863 smaller store. For repositories with many revisions, it also helps
863 smaller store. For repositories with many revisions, it also helps
864 performance (by using shortened delta chains.)
864 performance (by using shortened delta chains.)
865
865
866 Repositories with this on-disk format require Mercurial version 4.7
866 Repositories with this on-disk format require Mercurial version 4.7
867
867
868 Enabled by default.
868 Enabled by default.
869
869
870 ``graph``
870 ``graph``
871 ---------
871 ---------
872
872
873 Web graph view configuration. This section let you change graph
873 Web graph view configuration. This section let you change graph
874 elements display properties by branches, for instance to make the
874 elements display properties by branches, for instance to make the
875 ``default`` branch stand out.
875 ``default`` branch stand out.
876
876
877 Each line has the following format::
877 Each line has the following format::
878
878
879 <branch>.<argument> = <value>
879 <branch>.<argument> = <value>
880
880
881 where ``<branch>`` is the name of the branch being
881 where ``<branch>`` is the name of the branch being
882 customized. Example::
882 customized. Example::
883
883
884 [graph]
884 [graph]
885 # 2px width
885 # 2px width
886 default.width = 2
886 default.width = 2
887 # red color
887 # red color
888 default.color = FF0000
888 default.color = FF0000
889
889
890 Supported arguments:
890 Supported arguments:
891
891
892 ``width``
892 ``width``
893 Set branch edges width in pixels.
893 Set branch edges width in pixels.
894
894
895 ``color``
895 ``color``
896 Set branch edges color in hexadecimal RGB notation.
896 Set branch edges color in hexadecimal RGB notation.
897
897
898 ``hooks``
898 ``hooks``
899 ---------
899 ---------
900
900
901 Commands or Python functions that get automatically executed by
901 Commands or Python functions that get automatically executed by
902 various actions such as starting or finishing a commit. Multiple
902 various actions such as starting or finishing a commit. Multiple
903 hooks can be run for the same action by appending a suffix to the
903 hooks can be run for the same action by appending a suffix to the
904 action. Overriding a site-wide hook can be done by changing its
904 action. Overriding a site-wide hook can be done by changing its
905 value or setting it to an empty string. Hooks can be prioritized
905 value or setting it to an empty string. Hooks can be prioritized
906 by adding a prefix of ``priority.`` to the hook name on a new line
906 by adding a prefix of ``priority.`` to the hook name on a new line
907 and setting the priority. The default priority is 0.
907 and setting the priority. The default priority is 0.
908
908
909 Example ``.hg/hgrc``::
909 Example ``.hg/hgrc``::
910
910
911 [hooks]
911 [hooks]
912 # update working directory after adding changesets
912 # update working directory after adding changesets
913 changegroup.update = hg update
913 changegroup.update = hg update
914 # do not use the site-wide hook
914 # do not use the site-wide hook
915 incoming =
915 incoming =
916 incoming.email = /my/email/hook
916 incoming.email = /my/email/hook
917 incoming.autobuild = /my/build/hook
917 incoming.autobuild = /my/build/hook
918 # force autobuild hook to run before other incoming hooks
918 # force autobuild hook to run before other incoming hooks
919 priority.incoming.autobuild = 1
919 priority.incoming.autobuild = 1
920
920
921 Most hooks are run with environment variables set that give useful
921 Most hooks are run with environment variables set that give useful
922 additional information. For each hook below, the environment variables
922 additional information. For each hook below, the environment variables
923 it is passed are listed with names in the form ``$HG_foo``. The
923 it is passed are listed with names in the form ``$HG_foo``. The
924 ``$HG_HOOKTYPE`` and ``$HG_HOOKNAME`` variables are set for all hooks.
924 ``$HG_HOOKTYPE`` and ``$HG_HOOKNAME`` variables are set for all hooks.
925 They contain the type of hook which triggered the run and the full name
925 They contain the type of hook which triggered the run and the full name
926 of the hook in the config, respectively. In the example above, this will
926 of the hook in the config, respectively. In the example above, this will
927 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
927 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
928
928
929 .. container:: windows
929 .. container:: windows
930
930
931 Some basic Unix syntax can be enabled for portability, including ``$VAR``
931 Some basic Unix syntax can be enabled for portability, including ``$VAR``
932 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
932 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
933 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
933 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
934 on Unix. To use a literal ``$`` or ``~``, it must be escaped with a back
934 on Unix. To use a literal ``$`` or ``~``, it must be escaped with a back
935 slash or inside of a strong quote. Strong quotes will be replaced by
935 slash or inside of a strong quote. Strong quotes will be replaced by
936 double quotes after processing.
936 double quotes after processing.
937
937
938 This feature is enabled by adding a prefix of ``tonative.`` to the hook
938 This feature is enabled by adding a prefix of ``tonative.`` to the hook
939 name on a new line, and setting it to ``True``. For example::
939 name on a new line, and setting it to ``True``. For example::
940
940
941 [hooks]
941 [hooks]
942 incoming.autobuild = /my/build/hook
942 incoming.autobuild = /my/build/hook
943 # enable translation to cmd.exe syntax for autobuild hook
943 # enable translation to cmd.exe syntax for autobuild hook
944 tonative.incoming.autobuild = True
944 tonative.incoming.autobuild = True
945
945
946 ``changegroup``
946 ``changegroup``
947 Run after a changegroup has been added via push, pull or unbundle. The ID of
947 Run after a changegroup has been added via push, pull or unbundle. The ID of
948 the first new changeset is in ``$HG_NODE`` and last is in ``$HG_NODE_LAST``.
948 the first new changeset is in ``$HG_NODE`` and last is in ``$HG_NODE_LAST``.
949 The URL from which changes came is in ``$HG_URL``.
949 The URL from which changes came is in ``$HG_URL``.
950
950
951 ``commit``
951 ``commit``
952 Run after a changeset has been created in the local repository. The ID
952 Run after a changeset has been created in the local repository. The ID
953 of the newly created changeset is in ``$HG_NODE``. Parent changeset
953 of the newly created changeset is in ``$HG_NODE``. Parent changeset
954 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
954 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
955
955
956 ``incoming``
956 ``incoming``
957 Run after a changeset has been pulled, pushed, or unbundled into
957 Run after a changeset has been pulled, pushed, or unbundled into
958 the local repository. The ID of the newly arrived changeset is in
958 the local repository. The ID of the newly arrived changeset is in
959 ``$HG_NODE``. The URL that was source of the changes is in ``$HG_URL``.
959 ``$HG_NODE``. The URL that was source of the changes is in ``$HG_URL``.
960
960
961 ``outgoing``
961 ``outgoing``
962 Run after sending changes from the local repository to another. The ID of
962 Run after sending changes from the local repository to another. The ID of
963 first changeset sent is in ``$HG_NODE``. The source of operation is in
963 first changeset sent is in ``$HG_NODE``. The source of operation is in
964 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
964 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
965
965
966 ``post-<command>``
966 ``post-<command>``
967 Run after successful invocations of the associated command. The
967 Run after successful invocations of the associated command. The
968 contents of the command line are passed as ``$HG_ARGS`` and the result
968 contents of the command line are passed as ``$HG_ARGS`` and the result
969 code in ``$HG_RESULT``. Parsed command line arguments are passed as
969 code in ``$HG_RESULT``. Parsed command line arguments are passed as
970 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
970 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
971 the python data internally passed to <command>. ``$HG_OPTS`` is a
971 the python data internally passed to <command>. ``$HG_OPTS`` is a
972 dictionary of options (with unspecified options set to their defaults).
972 dictionary of options (with unspecified options set to their defaults).
973 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
973 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
974
974
975 ``fail-<command>``
975 ``fail-<command>``
976 Run after a failed invocation of an associated command. The contents
976 Run after a failed invocation of an associated command. The contents
977 of the command line are passed as ``$HG_ARGS``. Parsed command line
977 of the command line are passed as ``$HG_ARGS``. Parsed command line
978 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
978 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
979 string representations of the python data internally passed to
979 string representations of the python data internally passed to
980 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
980 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
981 options set to their defaults). ``$HG_PATS`` is a list of arguments.
981 options set to their defaults). ``$HG_PATS`` is a list of arguments.
982 Hook failure is ignored.
982 Hook failure is ignored.
983
983
984 ``pre-<command>``
984 ``pre-<command>``
985 Run before executing the associated command. The contents of the
985 Run before executing the associated command. The contents of the
986 command line are passed as ``$HG_ARGS``. Parsed command line arguments
986 command line are passed as ``$HG_ARGS``. Parsed command line arguments
987 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
987 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
988 representations of the data internally passed to <command>. ``$HG_OPTS``
988 representations of the data internally passed to <command>. ``$HG_OPTS``
989 is a dictionary of options (with unspecified options set to their
989 is a dictionary of options (with unspecified options set to their
990 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
990 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
991 failure, the command doesn't execute and Mercurial returns the failure
991 failure, the command doesn't execute and Mercurial returns the failure
992 code.
992 code.
993
993
994 ``prechangegroup``
994 ``prechangegroup``
995 Run before a changegroup is added via push, pull or unbundle. Exit
995 Run before a changegroup is added via push, pull or unbundle. Exit
996 status 0 allows the changegroup to proceed. A non-zero status will
996 status 0 allows the changegroup to proceed. A non-zero status will
997 cause the push, pull or unbundle to fail. The URL from which changes
997 cause the push, pull or unbundle to fail. The URL from which changes
998 will come is in ``$HG_URL``.
998 will come is in ``$HG_URL``.
999
999
1000 ``precommit``
1000 ``precommit``
1001 Run before starting a local commit. Exit status 0 allows the
1001 Run before starting a local commit. Exit status 0 allows the
1002 commit to proceed. A non-zero status will cause the commit to fail.
1002 commit to proceed. A non-zero status will cause the commit to fail.
1003 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1003 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1004
1004
1005 ``prelistkeys``
1005 ``prelistkeys``
1006 Run before listing pushkeys (like bookmarks) in the
1006 Run before listing pushkeys (like bookmarks) in the
1007 repository. A non-zero status will cause failure. The key namespace is
1007 repository. A non-zero status will cause failure. The key namespace is
1008 in ``$HG_NAMESPACE``.
1008 in ``$HG_NAMESPACE``.
1009
1009
1010 ``preoutgoing``
1010 ``preoutgoing``
1011 Run before collecting changes to send from the local repository to
1011 Run before collecting changes to send from the local repository to
1012 another. A non-zero status will cause failure. This lets you prevent
1012 another. A non-zero status will cause failure. This lets you prevent
1013 pull over HTTP or SSH. It can also prevent propagating commits (via
1013 pull over HTTP or SSH. It can also prevent propagating commits (via
1014 local pull, push (outbound) or bundle commands), but not completely,
1014 local pull, push (outbound) or bundle commands), but not completely,
1015 since you can just copy files instead. The source of operation is in
1015 since you can just copy files instead. The source of operation is in
1016 ``$HG_SOURCE``. If "serve", the operation is happening on behalf of a remote
1016 ``$HG_SOURCE``. If "serve", the operation is happening on behalf of a remote
1017 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1017 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1018 is happening on behalf of a repository on same system.
1018 is happening on behalf of a repository on same system.
1019
1019
1020 ``prepushkey``
1020 ``prepushkey``
1021 Run before a pushkey (like a bookmark) is added to the
1021 Run before a pushkey (like a bookmark) is added to the
1022 repository. A non-zero status will cause the key to be rejected. The
1022 repository. A non-zero status will cause the key to be rejected. The
1023 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
1023 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
1024 the old value (if any) is in ``$HG_OLD``, and the new value is in
1024 the old value (if any) is in ``$HG_OLD``, and the new value is in
1025 ``$HG_NEW``.
1025 ``$HG_NEW``.
1026
1026
1027 ``pretag``
1027 ``pretag``
1028 Run before creating a tag. Exit status 0 allows the tag to be
1028 Run before creating a tag. Exit status 0 allows the tag to be
1029 created. A non-zero status will cause the tag to fail. The ID of the
1029 created. A non-zero status will cause the tag to fail. The ID of the
1030 changeset to tag is in ``$HG_NODE``. The name of tag is in ``$HG_TAG``. The
1030 changeset to tag is in ``$HG_NODE``. The name of tag is in ``$HG_TAG``. The
1031 tag is local if ``$HG_LOCAL=1``, or in the repository if ``$HG_LOCAL=0``.
1031 tag is local if ``$HG_LOCAL=1``, or in the repository if ``$HG_LOCAL=0``.
1032
1032
1033 ``pretxnopen``
1033 ``pretxnopen``
1034 Run before any new repository transaction is open. The reason for the
1034 Run before any new repository transaction is open. The reason for the
1035 transaction will be in ``$HG_TXNNAME``, and a unique identifier for the
1035 transaction will be in ``$HG_TXNNAME``, and a unique identifier for the
1036 transaction will be in ``HG_TXNID``. A non-zero status will prevent the
1036 transaction will be in ``HG_TXNID``. A non-zero status will prevent the
1037 transaction from being opened.
1037 transaction from being opened.
1038
1038
1039 ``pretxnclose``
1039 ``pretxnclose``
1040 Run right before the transaction is actually finalized. Any repository change
1040 Run right before the transaction is actually finalized. Any repository change
1041 will be visible to the hook program. This lets you validate the transaction
1041 will be visible to the hook program. This lets you validate the transaction
1042 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1042 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1043 status will cause the transaction to be rolled back. The reason for the
1043 status will cause the transaction to be rolled back. The reason for the
1044 transaction opening will be in ``$HG_TXNNAME``, and a unique identifier for
1044 transaction opening will be in ``$HG_TXNNAME``, and a unique identifier for
1045 the transaction will be in ``HG_TXNID``. The rest of the available data will
1045 the transaction will be in ``HG_TXNID``. The rest of the available data will
1046 vary according the transaction type. New changesets will add ``$HG_NODE``
1046 vary according the transaction type. New changesets will add ``$HG_NODE``
1047 (the ID of the first added changeset), ``$HG_NODE_LAST`` (the ID of the last
1047 (the ID of the first added changeset), ``$HG_NODE_LAST`` (the ID of the last
1048 added changeset), ``$HG_URL`` and ``$HG_SOURCE`` variables. Bookmark and
1048 added changeset), ``$HG_URL`` and ``$HG_SOURCE`` variables. Bookmark and
1049 phase changes will set ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``
1049 phase changes will set ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``
1050 respectively, etc.
1050 respectively, etc.
1051
1051
1052 ``pretxnclose-bookmark``
1052 ``pretxnclose-bookmark``
1053 Run right before a bookmark change is actually finalized. Any repository
1053 Run right before a bookmark change is actually finalized. Any repository
1054 change will be visible to the hook program. This lets you validate the
1054 change will be visible to the hook program. This lets you validate the
1055 transaction content or change it. Exit status 0 allows the commit to
1055 transaction content or change it. Exit status 0 allows the commit to
1056 proceed. A non-zero status will cause the transaction to be rolled back.
1056 proceed. A non-zero status will cause the transaction to be rolled back.
1057 The name of the bookmark will be available in ``$HG_BOOKMARK``, the new
1057 The name of the bookmark will be available in ``$HG_BOOKMARK``, the new
1058 bookmark location will be available in ``$HG_NODE`` while the previous
1058 bookmark location will be available in ``$HG_NODE`` while the previous
1059 location will be available in ``$HG_OLDNODE``. In case of a bookmark
1059 location will be available in ``$HG_OLDNODE``. In case of a bookmark
1060 creation ``$HG_OLDNODE`` will be empty. In case of deletion ``$HG_NODE``
1060 creation ``$HG_OLDNODE`` will be empty. In case of deletion ``$HG_NODE``
1061 will be empty.
1061 will be empty.
1062 In addition, the reason for the transaction opening will be in
1062 In addition, the reason for the transaction opening will be in
1063 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1063 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1064 ``HG_TXNID``.
1064 ``HG_TXNID``.
1065
1065
1066 ``pretxnclose-phase``
1066 ``pretxnclose-phase``
1067 Run right before a phase change is actually finalized. Any repository change
1067 Run right before a phase change is actually finalized. Any repository change
1068 will be visible to the hook program. This lets you validate the transaction
1068 will be visible to the hook program. This lets you validate the transaction
1069 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1069 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1070 status will cause the transaction to be rolled back. The hook is called
1070 status will cause the transaction to be rolled back. The hook is called
1071 multiple times, once for each revision affected by a phase change.
1071 multiple times, once for each revision affected by a phase change.
1072 The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``
1072 The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``
1073 while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``
1073 while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``
1074 will be empty. In addition, the reason for the transaction opening will be in
1074 will be empty. In addition, the reason for the transaction opening will be in
1075 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1075 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1076 ``HG_TXNID``. The hook is also run for newly added revisions. In this case
1076 ``HG_TXNID``. The hook is also run for newly added revisions. In this case
1077 the ``$HG_OLDPHASE`` entry will be empty.
1077 the ``$HG_OLDPHASE`` entry will be empty.
1078
1078
1079 ``txnclose``
1079 ``txnclose``
1080 Run after any repository transaction has been committed. At this
1080 Run after any repository transaction has been committed. At this
1081 point, the transaction can no longer be rolled back. The hook will run
1081 point, the transaction can no longer be rolled back. The hook will run
1082 after the lock is released. See :hg:`help config.hooks.pretxnclose` for
1082 after the lock is released. See :hg:`help config.hooks.pretxnclose` for
1083 details about available variables.
1083 details about available variables.
1084
1084
1085 ``txnclose-bookmark``
1085 ``txnclose-bookmark``
1086 Run after any bookmark change has been committed. At this point, the
1086 Run after any bookmark change has been committed. At this point, the
1087 transaction can no longer be rolled back. The hook will run after the lock
1087 transaction can no longer be rolled back. The hook will run after the lock
1088 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1088 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1089 about available variables.
1089 about available variables.
1090
1090
1091 ``txnclose-phase``
1091 ``txnclose-phase``
1092 Run after any phase change has been committed. At this point, the
1092 Run after any phase change has been committed. At this point, the
1093 transaction can no longer be rolled back. The hook will run after the lock
1093 transaction can no longer be rolled back. The hook will run after the lock
1094 is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
1094 is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
1095 available variables.
1095 available variables.
1096
1096
1097 ``txnabort``
1097 ``txnabort``
1098 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
1098 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
1099 for details about available variables.
1099 for details about available variables.
1100
1100
1101 ``pretxnchangegroup``
1101 ``pretxnchangegroup``
1102 Run after a changegroup has been added via push, pull or unbundle, but before
1102 Run after a changegroup has been added via push, pull or unbundle, but before
1103 the transaction has been committed. The changegroup is visible to the hook
1103 the transaction has been committed. The changegroup is visible to the hook
1104 program. This allows validation of incoming changes before accepting them.
1104 program. This allows validation of incoming changes before accepting them.
1105 The ID of the first new changeset is in ``$HG_NODE`` and last is in
1105 The ID of the first new changeset is in ``$HG_NODE`` and last is in
1106 ``$HG_NODE_LAST``. Exit status 0 allows the transaction to commit. A non-zero
1106 ``$HG_NODE_LAST``. Exit status 0 allows the transaction to commit. A non-zero
1107 status will cause the transaction to be rolled back, and the push, pull or
1107 status will cause the transaction to be rolled back, and the push, pull or
1108 unbundle will fail. The URL that was the source of changes is in ``$HG_URL``.
1108 unbundle will fail. The URL that was the source of changes is in ``$HG_URL``.
1109
1109
1110 ``pretxncommit``
1110 ``pretxncommit``
1111 Run after a changeset has been created, but before the transaction is
1111 Run after a changeset has been created, but before the transaction is
1112 committed. The changeset is visible to the hook program. This allows
1112 committed. The changeset is visible to the hook program. This allows
1113 validation of the commit message and changes. Exit status 0 allows the
1113 validation of the commit message and changes. Exit status 0 allows the
1114 commit to proceed. A non-zero status will cause the transaction to
1114 commit to proceed. A non-zero status will cause the transaction to
1115 be rolled back. The ID of the new changeset is in ``$HG_NODE``. The parent
1115 be rolled back. The ID of the new changeset is in ``$HG_NODE``. The parent
1116 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1116 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1117
1117
1118 ``preupdate``
1118 ``preupdate``
1119 Run before updating the working directory. Exit status 0 allows
1119 Run before updating the working directory. Exit status 0 allows
1120 the update to proceed. A non-zero status will prevent the update.
1120 the update to proceed. A non-zero status will prevent the update.
1121 The changeset ID of first new parent is in ``$HG_PARENT1``. If updating to a
1121 The changeset ID of first new parent is in ``$HG_PARENT1``. If updating to a
1122 merge, the ID of second new parent is in ``$HG_PARENT2``.
1122 merge, the ID of second new parent is in ``$HG_PARENT2``.
1123
1123
1124 ``listkeys``
1124 ``listkeys``
1125 Run after listing pushkeys (like bookmarks) in the repository. The
1125 Run after listing pushkeys (like bookmarks) in the repository. The
1126 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1126 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1127 dictionary containing the keys and values.
1127 dictionary containing the keys and values.
1128
1128
1129 ``pushkey``
1129 ``pushkey``
1130 Run after a pushkey (like a bookmark) is added to the
1130 Run after a pushkey (like a bookmark) is added to the
1131 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
1131 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
1132 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
1132 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
1133 value is in ``$HG_NEW``.
1133 value is in ``$HG_NEW``.
1134
1134
1135 ``tag``
1135 ``tag``
1136 Run after a tag is created. The ID of the tagged changeset is in ``$HG_NODE``.
1136 Run after a tag is created. The ID of the tagged changeset is in ``$HG_NODE``.
1137 The name of tag is in ``$HG_TAG``. The tag is local if ``$HG_LOCAL=1``, or in
1137 The name of tag is in ``$HG_TAG``. The tag is local if ``$HG_LOCAL=1``, or in
1138 the repository if ``$HG_LOCAL=0``.
1138 the repository if ``$HG_LOCAL=0``.
1139
1139
1140 ``update``
1140 ``update``
1141 Run after updating the working directory. The changeset ID of first
1141 Run after updating the working directory. The changeset ID of first
1142 new parent is in ``$HG_PARENT1``. If updating to a merge, the ID of second new
1142 new parent is in ``$HG_PARENT1``. If updating to a merge, the ID of second new
1143 parent is in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
1143 parent is in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
1144 update failed (e.g. because conflicts were not resolved), ``$HG_ERROR=1``.
1144 update failed (e.g. because conflicts were not resolved), ``$HG_ERROR=1``.
1145
1145
1146 .. note::
1146 .. note::
1147
1147
1148 It is generally better to use standard hooks rather than the
1148 It is generally better to use standard hooks rather than the
1149 generic pre- and post- command hooks, as they are guaranteed to be
1149 generic pre- and post- command hooks, as they are guaranteed to be
1150 called in the appropriate contexts for influencing transactions.
1150 called in the appropriate contexts for influencing transactions.
1151 Also, hooks like "commit" will be called in all contexts that
1151 Also, hooks like "commit" will be called in all contexts that
1152 generate a commit (e.g. tag) and not just the commit command.
1152 generate a commit (e.g. tag) and not just the commit command.
1153
1153
1154 .. note::
1154 .. note::
1155
1155
1156 Environment variables with empty values may not be passed to
1156 Environment variables with empty values may not be passed to
1157 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1157 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1158 will have an empty value under Unix-like platforms for non-merge
1158 will have an empty value under Unix-like platforms for non-merge
1159 changesets, while it will not be available at all under Windows.
1159 changesets, while it will not be available at all under Windows.
1160
1160
1161 The syntax for Python hooks is as follows::
1161 The syntax for Python hooks is as follows::
1162
1162
1163 hookname = python:modulename.submodule.callable
1163 hookname = python:modulename.submodule.callable
1164 hookname = python:/path/to/python/module.py:callable
1164 hookname = python:/path/to/python/module.py:callable
1165
1165
1166 Python hooks are run within the Mercurial process. Each hook is
1166 Python hooks are run within the Mercurial process. Each hook is
1167 called with at least three keyword arguments: a ui object (keyword
1167 called with at least three keyword arguments: a ui object (keyword
1168 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1168 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1169 keyword that tells what kind of hook is used. Arguments listed as
1169 keyword that tells what kind of hook is used. Arguments listed as
1170 environment variables above are passed as keyword arguments, with no
1170 environment variables above are passed as keyword arguments, with no
1171 ``HG_`` prefix, and names in lower case.
1171 ``HG_`` prefix, and names in lower case.
1172
1172
1173 If a Python hook returns a "true" value or raises an exception, this
1173 If a Python hook returns a "true" value or raises an exception, this
1174 is treated as a failure.
1174 is treated as a failure.
1175
1175
1176
1176
1177 ``hostfingerprints``
1177 ``hostfingerprints``
1178 --------------------
1178 --------------------
1179
1179
1180 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1180 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1181
1181
1182 Fingerprints of the certificates of known HTTPS servers.
1182 Fingerprints of the certificates of known HTTPS servers.
1183
1183
1184 A HTTPS connection to a server with a fingerprint configured here will
1184 A HTTPS connection to a server with a fingerprint configured here will
1185 only succeed if the servers certificate matches the fingerprint.
1185 only succeed if the servers certificate matches the fingerprint.
1186 This is very similar to how ssh known hosts works.
1186 This is very similar to how ssh known hosts works.
1187
1187
1188 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
1188 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
1189 Multiple values can be specified (separated by spaces or commas). This can
1189 Multiple values can be specified (separated by spaces or commas). This can
1190 be used to define both old and new fingerprints while a host transitions
1190 be used to define both old and new fingerprints while a host transitions
1191 to a new certificate.
1191 to a new certificate.
1192
1192
1193 The CA chain and web.cacerts is not used for servers with a fingerprint.
1193 The CA chain and web.cacerts is not used for servers with a fingerprint.
1194
1194
1195 For example::
1195 For example::
1196
1196
1197 [hostfingerprints]
1197 [hostfingerprints]
1198 hg.intevation.de = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
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 hg.intevation.org = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
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 ``hostsecurity``
1201 ``hostsecurity``
1202 ----------------
1202 ----------------
1203
1203
1204 Used to specify global and per-host security settings for connecting to
1204 Used to specify global and per-host security settings for connecting to
1205 other machines.
1205 other machines.
1206
1206
1207 The following options control default behavior for all hosts.
1207 The following options control default behavior for all hosts.
1208
1208
1209 ``ciphers``
1209 ``ciphers``
1210 Defines the cryptographic ciphers to use for connections.
1210 Defines the cryptographic ciphers to use for connections.
1211
1211
1212 Value must be a valid OpenSSL Cipher List Format as documented at
1212 Value must be a valid OpenSSL Cipher List Format as documented at
1213 https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
1213 https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
1214
1214
1215 This setting is for advanced users only. Setting to incorrect values
1215 This setting is for advanced users only. Setting to incorrect values
1216 can significantly lower connection security or decrease performance.
1216 can significantly lower connection security or decrease performance.
1217 You have been warned.
1217 You have been warned.
1218
1218
1219 This option requires Python 2.7.
1219 This option requires Python 2.7.
1220
1220
1221 ``minimumprotocol``
1221 ``minimumprotocol``
1222 Defines the minimum channel encryption protocol to use.
1222 Defines the minimum channel encryption protocol to use.
1223
1223
1224 By default, the highest version of TLS supported by both client and server
1224 By default, the highest version of TLS supported by both client and server
1225 is used.
1225 is used.
1226
1226
1227 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1227 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1228
1228
1229 When running on an old Python version, only ``tls1.0`` is allowed since
1229 When running on an old Python version, only ``tls1.0`` is allowed since
1230 old versions of Python only support up to TLS 1.0.
1230 old versions of Python only support up to TLS 1.0.
1231
1231
1232 When running a Python that supports modern TLS versions, the default is
1232 When running a Python that supports modern TLS versions, the default is
1233 ``tls1.1``. ``tls1.0`` can still be used to allow TLS 1.0. However, this
1233 ``tls1.1``. ``tls1.0`` can still be used to allow TLS 1.0. However, this
1234 weakens security and should only be used as a feature of last resort if
1234 weakens security and should only be used as a feature of last resort if
1235 a server does not support TLS 1.1+.
1235 a server does not support TLS 1.1+.
1236
1236
1237 Options in the ``[hostsecurity]`` section can have the form
1237 Options in the ``[hostsecurity]`` section can have the form
1238 ``hostname``:``setting``. This allows multiple settings to be defined on a
1238 ``hostname``:``setting``. This allows multiple settings to be defined on a
1239 per-host basis.
1239 per-host basis.
1240
1240
1241 The following per-host settings can be defined.
1241 The following per-host settings can be defined.
1242
1242
1243 ``ciphers``
1243 ``ciphers``
1244 This behaves like ``ciphers`` as described above except it only applies
1244 This behaves like ``ciphers`` as described above except it only applies
1245 to the host on which it is defined.
1245 to the host on which it is defined.
1246
1246
1247 ``fingerprints``
1247 ``fingerprints``
1248 A list of hashes of the DER encoded peer/remote certificate. Values have
1248 A list of hashes of the DER encoded peer/remote certificate. Values have
1249 the form ``algorithm``:``fingerprint``. e.g.
1249 the form ``algorithm``:``fingerprint``. e.g.
1250 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1250 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1251 In addition, colons (``:``) can appear in the fingerprint part.
1251 In addition, colons (``:``) can appear in the fingerprint part.
1252
1252
1253 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1253 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1254 ``sha512``.
1254 ``sha512``.
1255
1255
1256 Use of ``sha256`` or ``sha512`` is preferred.
1256 Use of ``sha256`` or ``sha512`` is preferred.
1257
1257
1258 If a fingerprint is specified, the CA chain is not validated for this
1258 If a fingerprint is specified, the CA chain is not validated for this
1259 host and Mercurial will require the remote certificate to match one
1259 host and Mercurial will require the remote certificate to match one
1260 of the fingerprints specified. This means if the server updates its
1260 of the fingerprints specified. This means if the server updates its
1261 certificate, Mercurial will abort until a new fingerprint is defined.
1261 certificate, Mercurial will abort until a new fingerprint is defined.
1262 This can provide stronger security than traditional CA-based validation
1262 This can provide stronger security than traditional CA-based validation
1263 at the expense of convenience.
1263 at the expense of convenience.
1264
1264
1265 This option takes precedence over ``verifycertsfile``.
1265 This option takes precedence over ``verifycertsfile``.
1266
1266
1267 ``minimumprotocol``
1267 ``minimumprotocol``
1268 This behaves like ``minimumprotocol`` as described above except it
1268 This behaves like ``minimumprotocol`` as described above except it
1269 only applies to the host on which it is defined.
1269 only applies to the host on which it is defined.
1270
1270
1271 ``verifycertsfile``
1271 ``verifycertsfile``
1272 Path to file a containing a list of PEM encoded certificates used to
1272 Path to file a containing a list of PEM encoded certificates used to
1273 verify the server certificate. Environment variables and ``~user``
1273 verify the server certificate. Environment variables and ``~user``
1274 constructs are expanded in the filename.
1274 constructs are expanded in the filename.
1275
1275
1276 The server certificate or the certificate's certificate authority (CA)
1276 The server certificate or the certificate's certificate authority (CA)
1277 must match a certificate from this file or certificate verification
1277 must match a certificate from this file or certificate verification
1278 will fail and connections to the server will be refused.
1278 will fail and connections to the server will be refused.
1279
1279
1280 If defined, only certificates provided by this file will be used:
1280 If defined, only certificates provided by this file will be used:
1281 ``web.cacerts`` and any system/default certificates will not be
1281 ``web.cacerts`` and any system/default certificates will not be
1282 used.
1282 used.
1283
1283
1284 This option has no effect if the per-host ``fingerprints`` option
1284 This option has no effect if the per-host ``fingerprints`` option
1285 is set.
1285 is set.
1286
1286
1287 The format of the file is as follows::
1287 The format of the file is as follows::
1288
1288
1289 -----BEGIN CERTIFICATE-----
1289 -----BEGIN CERTIFICATE-----
1290 ... (certificate in base64 PEM encoding) ...
1290 ... (certificate in base64 PEM encoding) ...
1291 -----END CERTIFICATE-----
1291 -----END CERTIFICATE-----
1292 -----BEGIN CERTIFICATE-----
1292 -----BEGIN CERTIFICATE-----
1293 ... (certificate in base64 PEM encoding) ...
1293 ... (certificate in base64 PEM encoding) ...
1294 -----END CERTIFICATE-----
1294 -----END CERTIFICATE-----
1295
1295
1296 For example::
1296 For example::
1297
1297
1298 [hostsecurity]
1298 [hostsecurity]
1299 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
1299 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
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
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 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
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 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1302 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1303
1303
1304 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1304 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1305 when connecting to ``hg.example.com``::
1305 when connecting to ``hg.example.com``::
1306
1306
1307 [hostsecurity]
1307 [hostsecurity]
1308 minimumprotocol = tls1.2
1308 minimumprotocol = tls1.2
1309 hg.example.com:minimumprotocol = tls1.1
1309 hg.example.com:minimumprotocol = tls1.1
1310
1310
1311 ``http_proxy``
1311 ``http_proxy``
1312 --------------
1312 --------------
1313
1313
1314 Used to access web-based Mercurial repositories through a HTTP
1314 Used to access web-based Mercurial repositories through a HTTP
1315 proxy.
1315 proxy.
1316
1316
1317 ``host``
1317 ``host``
1318 Host name and (optional) port of the proxy server, for example
1318 Host name and (optional) port of the proxy server, for example
1319 "myproxy:8000".
1319 "myproxy:8000".
1320
1320
1321 ``no``
1321 ``no``
1322 Optional. Comma-separated list of host names that should bypass
1322 Optional. Comma-separated list of host names that should bypass
1323 the proxy.
1323 the proxy.
1324
1324
1325 ``passwd``
1325 ``passwd``
1326 Optional. Password to authenticate with at the proxy server.
1326 Optional. Password to authenticate with at the proxy server.
1327
1327
1328 ``user``
1328 ``user``
1329 Optional. User name to authenticate with at the proxy server.
1329 Optional. User name to authenticate with at the proxy server.
1330
1330
1331 ``always``
1331 ``always``
1332 Optional. Always use the proxy, even for localhost and any entries
1332 Optional. Always use the proxy, even for localhost and any entries
1333 in ``http_proxy.no``. (default: False)
1333 in ``http_proxy.no``. (default: False)
1334
1334
1335 ``http``
1335 ``http``
1336 ----------
1336 ----------
1337
1337
1338 Used to configure access to Mercurial repositories via HTTP.
1338 Used to configure access to Mercurial repositories via HTTP.
1339
1339
1340 ``timeout``
1340 ``timeout``
1341 If set, blocking operations will timeout after that many seconds.
1341 If set, blocking operations will timeout after that many seconds.
1342 (default: None)
1342 (default: None)
1343
1343
1344 ``merge``
1344 ``merge``
1345 ---------
1345 ---------
1346
1346
1347 This section specifies behavior during merges and updates.
1347 This section specifies behavior during merges and updates.
1348
1348
1349 ``checkignored``
1349 ``checkignored``
1350 Controls behavior when an ignored file on disk has the same name as a tracked
1350 Controls behavior when an ignored file on disk has the same name as a tracked
1351 file in the changeset being merged or updated to, and has different
1351 file in the changeset being merged or updated to, and has different
1352 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1352 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1353 abort on such files. With ``warn``, warn on such files and back them up as
1353 abort on such files. With ``warn``, warn on such files and back them up as
1354 ``.orig``. With ``ignore``, don't print a warning and back them up as
1354 ``.orig``. With ``ignore``, don't print a warning and back them up as
1355 ``.orig``. (default: ``abort``)
1355 ``.orig``. (default: ``abort``)
1356
1356
1357 ``checkunknown``
1357 ``checkunknown``
1358 Controls behavior when an unknown file that isn't ignored has the same name
1358 Controls behavior when an unknown file that isn't ignored has the same name
1359 as a tracked file in the changeset being merged or updated to, and has
1359 as a tracked file in the changeset being merged or updated to, and has
1360 different contents. Similar to ``merge.checkignored``, except for files that
1360 different contents. Similar to ``merge.checkignored``, except for files that
1361 are not ignored. (default: ``abort``)
1361 are not ignored. (default: ``abort``)
1362
1362
1363 ``on-failure``
1363 ``on-failure``
1364 When set to ``continue`` (the default), the merge process attempts to
1364 When set to ``continue`` (the default), the merge process attempts to
1365 merge all unresolved files using the merge chosen tool, regardless of
1365 merge all unresolved files using the merge chosen tool, regardless of
1366 whether previous file merge attempts during the process succeeded or not.
1366 whether previous file merge attempts during the process succeeded or not.
1367 Setting this to ``prompt`` will prompt after any merge failure continue
1367 Setting this to ``prompt`` will prompt after any merge failure continue
1368 or halt the merge process. Setting this to ``halt`` will automatically
1368 or halt the merge process. Setting this to ``halt`` will automatically
1369 halt the merge process on any merge tool failure. The merge process
1369 halt the merge process on any merge tool failure. The merge process
1370 can be restarted by using the ``resolve`` command. When a merge is
1370 can be restarted by using the ``resolve`` command. When a merge is
1371 halted, the repository is left in a normal ``unresolved`` merge state.
1371 halted, the repository is left in a normal ``unresolved`` merge state.
1372 (default: ``continue``)
1372 (default: ``continue``)
1373
1373
1374 ``strict-capability-check``
1374 ``strict-capability-check``
1375 Whether capabilities of internal merge tools are checked strictly
1375 Whether capabilities of internal merge tools are checked strictly
1376 or not, while examining rules to decide merge tool to be used.
1376 or not, while examining rules to decide merge tool to be used.
1377 (default: False)
1377 (default: False)
1378
1378
1379 ``merge-patterns``
1379 ``merge-patterns``
1380 ------------------
1380 ------------------
1381
1381
1382 This section specifies merge tools to associate with particular file
1382 This section specifies merge tools to associate with particular file
1383 patterns. Tools matched here will take precedence over the default
1383 patterns. Tools matched here will take precedence over the default
1384 merge tool. Patterns are globs by default, rooted at the repository
1384 merge tool. Patterns are globs by default, rooted at the repository
1385 root.
1385 root.
1386
1386
1387 Example::
1387 Example::
1388
1388
1389 [merge-patterns]
1389 [merge-patterns]
1390 **.c = kdiff3
1390 **.c = kdiff3
1391 **.jpg = myimgmerge
1391 **.jpg = myimgmerge
1392
1392
1393 ``merge-tools``
1393 ``merge-tools``
1394 ---------------
1394 ---------------
1395
1395
1396 This section configures external merge tools to use for file-level
1396 This section configures external merge tools to use for file-level
1397 merges. This section has likely been preconfigured at install time.
1397 merges. This section has likely been preconfigured at install time.
1398 Use :hg:`config merge-tools` to check the existing configuration.
1398 Use :hg:`config merge-tools` to check the existing configuration.
1399 Also see :hg:`help merge-tools` for more details.
1399 Also see :hg:`help merge-tools` for more details.
1400
1400
1401 Example ``~/.hgrc``::
1401 Example ``~/.hgrc``::
1402
1402
1403 [merge-tools]
1403 [merge-tools]
1404 # Override stock tool location
1404 # Override stock tool location
1405 kdiff3.executable = ~/bin/kdiff3
1405 kdiff3.executable = ~/bin/kdiff3
1406 # Specify command line
1406 # Specify command line
1407 kdiff3.args = $base $local $other -o $output
1407 kdiff3.args = $base $local $other -o $output
1408 # Give higher priority
1408 # Give higher priority
1409 kdiff3.priority = 1
1409 kdiff3.priority = 1
1410
1410
1411 # Changing the priority of preconfigured tool
1411 # Changing the priority of preconfigured tool
1412 meld.priority = 0
1412 meld.priority = 0
1413
1413
1414 # Disable a preconfigured tool
1414 # Disable a preconfigured tool
1415 vimdiff.disabled = yes
1415 vimdiff.disabled = yes
1416
1416
1417 # Define new tool
1417 # Define new tool
1418 myHtmlTool.args = -m $local $other $base $output
1418 myHtmlTool.args = -m $local $other $base $output
1419 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1419 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1420 myHtmlTool.priority = 1
1420 myHtmlTool.priority = 1
1421
1421
1422 Supported arguments:
1422 Supported arguments:
1423
1423
1424 ``priority``
1424 ``priority``
1425 The priority in which to evaluate this tool.
1425 The priority in which to evaluate this tool.
1426 (default: 0)
1426 (default: 0)
1427
1427
1428 ``executable``
1428 ``executable``
1429 Either just the name of the executable or its pathname.
1429 Either just the name of the executable or its pathname.
1430
1430
1431 .. container:: windows
1431 .. container:: windows
1432
1432
1433 On Windows, the path can use environment variables with ${ProgramFiles}
1433 On Windows, the path can use environment variables with ${ProgramFiles}
1434 syntax.
1434 syntax.
1435
1435
1436 (default: the tool name)
1436 (default: the tool name)
1437
1437
1438 ``args``
1438 ``args``
1439 The arguments to pass to the tool executable. You can refer to the
1439 The arguments to pass to the tool executable. You can refer to the
1440 files being merged as well as the output file through these
1440 files being merged as well as the output file through these
1441 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1441 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1442
1442
1443 The meaning of ``$local`` and ``$other`` can vary depending on which action is
1443 The meaning of ``$local`` and ``$other`` can vary depending on which action is
1444 being performed. During an update or merge, ``$local`` represents the original
1444 being performed. During an update or merge, ``$local`` represents the original
1445 state of the file, while ``$other`` represents the commit you are updating to or
1445 state of the file, while ``$other`` represents the commit you are updating to or
1446 the commit you are merging with. During a rebase, ``$local`` represents the
1446 the commit you are merging with. During a rebase, ``$local`` represents the
1447 destination of the rebase, and ``$other`` represents the commit being rebased.
1447 destination of the rebase, and ``$other`` represents the commit being rebased.
1448
1448
1449 Some operations define custom labels to assist with identifying the revisions,
1449 Some operations define custom labels to assist with identifying the revisions,
1450 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1450 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1451 labels are not available, these will be ``local``, ``other``, and ``base``,
1451 labels are not available, these will be ``local``, ``other``, and ``base``,
1452 respectively.
1452 respectively.
1453 (default: ``$local $base $other``)
1453 (default: ``$local $base $other``)
1454
1454
1455 ``premerge``
1455 ``premerge``
1456 Attempt to run internal non-interactive 3-way merge tool before
1456 Attempt to run internal non-interactive 3-way merge tool before
1457 launching external tool. Options are ``true``, ``false``, ``keep`` or
1457 launching external tool. Options are ``true``, ``false``, ``keep`` or
1458 ``keep-merge3``. The ``keep`` option will leave markers in the file if the
1458 ``keep-merge3``. The ``keep`` option will leave markers in the file if the
1459 premerge fails. The ``keep-merge3`` will do the same but include information
1459 premerge fails. The ``keep-merge3`` will do the same but include information
1460 about the base of the merge in the marker (see internal :merge3 in
1460 about the base of the merge in the marker (see internal :merge3 in
1461 :hg:`help merge-tools`).
1461 :hg:`help merge-tools`).
1462 (default: True)
1462 (default: True)
1463
1463
1464 ``binary``
1464 ``binary``
1465 This tool can merge binary files. (default: False, unless tool
1465 This tool can merge binary files. (default: False, unless tool
1466 was selected by file pattern match)
1466 was selected by file pattern match)
1467
1467
1468 ``symlink``
1468 ``symlink``
1469 This tool can merge symlinks. (default: False)
1469 This tool can merge symlinks. (default: False)
1470
1470
1471 ``check``
1471 ``check``
1472 A list of merge success-checking options:
1472 A list of merge success-checking options:
1473
1473
1474 ``changed``
1474 ``changed``
1475 Ask whether merge was successful when the merged file shows no changes.
1475 Ask whether merge was successful when the merged file shows no changes.
1476 ``conflicts``
1476 ``conflicts``
1477 Check whether there are conflicts even though the tool reported success.
1477 Check whether there are conflicts even though the tool reported success.
1478 ``prompt``
1478 ``prompt``
1479 Always prompt for merge success, regardless of success reported by tool.
1479 Always prompt for merge success, regardless of success reported by tool.
1480
1480
1481 ``fixeol``
1481 ``fixeol``
1482 Attempt to fix up EOL changes caused by the merge tool.
1482 Attempt to fix up EOL changes caused by the merge tool.
1483 (default: False)
1483 (default: False)
1484
1484
1485 ``gui``
1485 ``gui``
1486 This tool requires a graphical interface to run. (default: False)
1486 This tool requires a graphical interface to run. (default: False)
1487
1487
1488 ``mergemarkers``
1488 ``mergemarkers``
1489 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1489 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1490 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1490 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1491 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1491 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1492 markers generated during premerge will be ``detailed`` if either this option or
1492 markers generated during premerge will be ``detailed`` if either this option or
1493 the corresponding option in the ``[ui]`` section is ``detailed``.
1493 the corresponding option in the ``[ui]`` section is ``detailed``.
1494 (default: ``basic``)
1494 (default: ``basic``)
1495
1495
1496 ``mergemarkertemplate``
1496 ``mergemarkertemplate``
1497 This setting can be used to override ``mergemarkertemplate`` from the ``[ui]``
1497 This setting can be used to override ``mergemarkertemplate`` from the ``[ui]``
1498 section on a per-tool basis; this applies to the ``$label``-prefixed variables
1498 section on a per-tool basis; this applies to the ``$label``-prefixed variables
1499 and to the conflict markers that are generated if ``premerge`` is ``keep` or
1499 and to the conflict markers that are generated if ``premerge`` is ``keep` or
1500 ``keep-merge3``. See the corresponding variable in ``[ui]`` for more
1500 ``keep-merge3``. See the corresponding variable in ``[ui]`` for more
1501 information.
1501 information.
1502
1502
1503 .. container:: windows
1503 .. container:: windows
1504
1504
1505 ``regkey``
1505 ``regkey``
1506 Windows registry key which describes install location of this
1506 Windows registry key which describes install location of this
1507 tool. Mercurial will search for this key first under
1507 tool. Mercurial will search for this key first under
1508 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1508 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1509 (default: None)
1509 (default: None)
1510
1510
1511 ``regkeyalt``
1511 ``regkeyalt``
1512 An alternate Windows registry key to try if the first key is not
1512 An alternate Windows registry key to try if the first key is not
1513 found. The alternate key uses the same ``regname`` and ``regappend``
1513 found. The alternate key uses the same ``regname`` and ``regappend``
1514 semantics of the primary key. The most common use for this key
1514 semantics of the primary key. The most common use for this key
1515 is to search for 32bit applications on 64bit operating systems.
1515 is to search for 32bit applications on 64bit operating systems.
1516 (default: None)
1516 (default: None)
1517
1517
1518 ``regname``
1518 ``regname``
1519 Name of value to read from specified registry key.
1519 Name of value to read from specified registry key.
1520 (default: the unnamed (default) value)
1520 (default: the unnamed (default) value)
1521
1521
1522 ``regappend``
1522 ``regappend``
1523 String to append to the value read from the registry, typically
1523 String to append to the value read from the registry, typically
1524 the executable name of the tool.
1524 the executable name of the tool.
1525 (default: None)
1525 (default: None)
1526
1526
1527 ``pager``
1527 ``pager``
1528 ---------
1528 ---------
1529
1529
1530 Setting used to control when to paginate and with what external tool. See
1530 Setting used to control when to paginate and with what external tool. See
1531 :hg:`help pager` for details.
1531 :hg:`help pager` for details.
1532
1532
1533 ``pager``
1533 ``pager``
1534 Define the external tool used as pager.
1534 Define the external tool used as pager.
1535
1535
1536 If no pager is set, Mercurial uses the environment variable $PAGER.
1536 If no pager is set, Mercurial uses the environment variable $PAGER.
1537 If neither pager.pager, nor $PAGER is set, a default pager will be
1537 If neither pager.pager, nor $PAGER is set, a default pager will be
1538 used, typically `less` on Unix and `more` on Windows. Example::
1538 used, typically `less` on Unix and `more` on Windows. Example::
1539
1539
1540 [pager]
1540 [pager]
1541 pager = less -FRX
1541 pager = less -FRX
1542
1542
1543 ``ignore``
1543 ``ignore``
1544 List of commands to disable the pager for. Example::
1544 List of commands to disable the pager for. Example::
1545
1545
1546 [pager]
1546 [pager]
1547 ignore = version, help, update
1547 ignore = version, help, update
1548
1548
1549 ``patch``
1549 ``patch``
1550 ---------
1550 ---------
1551
1551
1552 Settings used when applying patches, for instance through the 'import'
1552 Settings used when applying patches, for instance through the 'import'
1553 command or with Mercurial Queues extension.
1553 command or with Mercurial Queues extension.
1554
1554
1555 ``eol``
1555 ``eol``
1556 When set to 'strict' patch content and patched files end of lines
1556 When set to 'strict' patch content and patched files end of lines
1557 are preserved. When set to ``lf`` or ``crlf``, both files end of
1557 are preserved. When set to ``lf`` or ``crlf``, both files end of
1558 lines are ignored when patching and the result line endings are
1558 lines are ignored when patching and the result line endings are
1559 normalized to either LF (Unix) or CRLF (Windows). When set to
1559 normalized to either LF (Unix) or CRLF (Windows). When set to
1560 ``auto``, end of lines are again ignored while patching but line
1560 ``auto``, end of lines are again ignored while patching but line
1561 endings in patched files are normalized to their original setting
1561 endings in patched files are normalized to their original setting
1562 on a per-file basis. If target file does not exist or has no end
1562 on a per-file basis. If target file does not exist or has no end
1563 of line, patch line endings are preserved.
1563 of line, patch line endings are preserved.
1564 (default: strict)
1564 (default: strict)
1565
1565
1566 ``fuzz``
1566 ``fuzz``
1567 The number of lines of 'fuzz' to allow when applying patches. This
1567 The number of lines of 'fuzz' to allow when applying patches. This
1568 controls how much context the patcher is allowed to ignore when
1568 controls how much context the patcher is allowed to ignore when
1569 trying to apply a patch.
1569 trying to apply a patch.
1570 (default: 2)
1570 (default: 2)
1571
1571
1572 ``paths``
1572 ``paths``
1573 ---------
1573 ---------
1574
1574
1575 Assigns symbolic names and behavior to repositories.
1575 Assigns symbolic names and behavior to repositories.
1576
1576
1577 Options are symbolic names defining the URL or directory that is the
1577 Options are symbolic names defining the URL or directory that is the
1578 location of the repository. Example::
1578 location of the repository. Example::
1579
1579
1580 [paths]
1580 [paths]
1581 my_server = https://example.com/my_repo
1581 my_server = https://example.com/my_repo
1582 local_path = /home/me/repo
1582 local_path = /home/me/repo
1583
1583
1584 These symbolic names can be used from the command line. To pull
1584 These symbolic names can be used from the command line. To pull
1585 from ``my_server``: :hg:`pull my_server`. To push to ``local_path``:
1585 from ``my_server``: :hg:`pull my_server`. To push to ``local_path``:
1586 :hg:`push local_path`.
1586 :hg:`push local_path`.
1587
1587
1588 Options containing colons (``:``) denote sub-options that can influence
1588 Options containing colons (``:``) denote sub-options that can influence
1589 behavior for that specific path. Example::
1589 behavior for that specific path. Example::
1590
1590
1591 [paths]
1591 [paths]
1592 my_server = https://example.com/my_path
1592 my_server = https://example.com/my_path
1593 my_server:pushurl = ssh://example.com/my_path
1593 my_server:pushurl = ssh://example.com/my_path
1594
1594
1595 The following sub-options can be defined:
1595 The following sub-options can be defined:
1596
1596
1597 ``pushurl``
1597 ``pushurl``
1598 The URL to use for push operations. If not defined, the location
1598 The URL to use for push operations. If not defined, the location
1599 defined by the path's main entry is used.
1599 defined by the path's main entry is used.
1600
1600
1601 ``pushrev``
1601 ``pushrev``
1602 A revset defining which revisions to push by default.
1602 A revset defining which revisions to push by default.
1603
1603
1604 When :hg:`push` is executed without a ``-r`` argument, the revset
1604 When :hg:`push` is executed without a ``-r`` argument, the revset
1605 defined by this sub-option is evaluated to determine what to push.
1605 defined by this sub-option is evaluated to determine what to push.
1606
1606
1607 For example, a value of ``.`` will push the working directory's
1607 For example, a value of ``.`` will push the working directory's
1608 revision by default.
1608 revision by default.
1609
1609
1610 Revsets specifying bookmarks will not result in the bookmark being
1610 Revsets specifying bookmarks will not result in the bookmark being
1611 pushed.
1611 pushed.
1612
1612
1613 The following special named paths exist:
1613 The following special named paths exist:
1614
1614
1615 ``default``
1615 ``default``
1616 The URL or directory to use when no source or remote is specified.
1616 The URL or directory to use when no source or remote is specified.
1617
1617
1618 :hg:`clone` will automatically define this path to the location the
1618 :hg:`clone` will automatically define this path to the location the
1619 repository was cloned from.
1619 repository was cloned from.
1620
1620
1621 ``default-push``
1621 ``default-push``
1622 (deprecated) The URL or directory for the default :hg:`push` location.
1622 (deprecated) The URL or directory for the default :hg:`push` location.
1623 ``default:pushurl`` should be used instead.
1623 ``default:pushurl`` should be used instead.
1624
1624
1625 ``phases``
1625 ``phases``
1626 ----------
1626 ----------
1627
1627
1628 Specifies default handling of phases. See :hg:`help phases` for more
1628 Specifies default handling of phases. See :hg:`help phases` for more
1629 information about working with phases.
1629 information about working with phases.
1630
1630
1631 ``publish``
1631 ``publish``
1632 Controls draft phase behavior when working as a server. When true,
1632 Controls draft phase behavior when working as a server. When true,
1633 pushed changesets are set to public in both client and server and
1633 pushed changesets are set to public in both client and server and
1634 pulled or cloned changesets are set to public in the client.
1634 pulled or cloned changesets are set to public in the client.
1635 (default: True)
1635 (default: True)
1636
1636
1637 ``new-commit``
1637 ``new-commit``
1638 Phase of newly-created commits.
1638 Phase of newly-created commits.
1639 (default: draft)
1639 (default: draft)
1640
1640
1641 ``checksubrepos``
1641 ``checksubrepos``
1642 Check the phase of the current revision of each subrepository. Allowed
1642 Check the phase of the current revision of each subrepository. Allowed
1643 values are "ignore", "follow" and "abort". For settings other than
1643 values are "ignore", "follow" and "abort". For settings other than
1644 "ignore", the phase of the current revision of each subrepository is
1644 "ignore", the phase of the current revision of each subrepository is
1645 checked before committing the parent repository. If any of those phases is
1645 checked before committing the parent repository. If any of those phases is
1646 greater than the phase of the parent repository (e.g. if a subrepo is in a
1646 greater than the phase of the parent repository (e.g. if a subrepo is in a
1647 "secret" phase while the parent repo is in "draft" phase), the commit is
1647 "secret" phase while the parent repo is in "draft" phase), the commit is
1648 either aborted (if checksubrepos is set to "abort") or the higher phase is
1648 either aborted (if checksubrepos is set to "abort") or the higher phase is
1649 used for the parent repository commit (if set to "follow").
1649 used for the parent repository commit (if set to "follow").
1650 (default: follow)
1650 (default: follow)
1651
1651
1652
1652
1653 ``profiling``
1653 ``profiling``
1654 -------------
1654 -------------
1655
1655
1656 Specifies profiling type, format, and file output. Two profilers are
1656 Specifies profiling type, format, and file output. Two profilers are
1657 supported: an instrumenting profiler (named ``ls``), and a sampling
1657 supported: an instrumenting profiler (named ``ls``), and a sampling
1658 profiler (named ``stat``).
1658 profiler (named ``stat``).
1659
1659
1660 In this section description, 'profiling data' stands for the raw data
1660 In this section description, 'profiling data' stands for the raw data
1661 collected during profiling, while 'profiling report' stands for a
1661 collected during profiling, while 'profiling report' stands for a
1662 statistical text report generated from the profiling data.
1662 statistical text report generated from the profiling data.
1663
1663
1664 ``enabled``
1664 ``enabled``
1665 Enable the profiler.
1665 Enable the profiler.
1666 (default: false)
1666 (default: false)
1667
1667
1668 This is equivalent to passing ``--profile`` on the command line.
1668 This is equivalent to passing ``--profile`` on the command line.
1669
1669
1670 ``type``
1670 ``type``
1671 The type of profiler to use.
1671 The type of profiler to use.
1672 (default: stat)
1672 (default: stat)
1673
1673
1674 ``ls``
1674 ``ls``
1675 Use Python's built-in instrumenting profiler. This profiler
1675 Use Python's built-in instrumenting profiler. This profiler
1676 works on all platforms, but each line number it reports is the
1676 works on all platforms, but each line number it reports is the
1677 first line of a function. This restriction makes it difficult to
1677 first line of a function. This restriction makes it difficult to
1678 identify the expensive parts of a non-trivial function.
1678 identify the expensive parts of a non-trivial function.
1679 ``stat``
1679 ``stat``
1680 Use a statistical profiler, statprof. This profiler is most
1680 Use a statistical profiler, statprof. This profiler is most
1681 useful for profiling commands that run for longer than about 0.1
1681 useful for profiling commands that run for longer than about 0.1
1682 seconds.
1682 seconds.
1683
1683
1684 ``format``
1684 ``format``
1685 Profiling format. Specific to the ``ls`` instrumenting profiler.
1685 Profiling format. Specific to the ``ls`` instrumenting profiler.
1686 (default: text)
1686 (default: text)
1687
1687
1688 ``text``
1688 ``text``
1689 Generate a profiling report. When saving to a file, it should be
1689 Generate a profiling report. When saving to a file, it should be
1690 noted that only the report is saved, and the profiling data is
1690 noted that only the report is saved, and the profiling data is
1691 not kept.
1691 not kept.
1692 ``kcachegrind``
1692 ``kcachegrind``
1693 Format profiling data for kcachegrind use: when saving to a
1693 Format profiling data for kcachegrind use: when saving to a
1694 file, the generated file can directly be loaded into
1694 file, the generated file can directly be loaded into
1695 kcachegrind.
1695 kcachegrind.
1696
1696
1697 ``statformat``
1697 ``statformat``
1698 Profiling format for the ``stat`` profiler.
1698 Profiling format for the ``stat`` profiler.
1699 (default: hotpath)
1699 (default: hotpath)
1700
1700
1701 ``hotpath``
1701 ``hotpath``
1702 Show a tree-based display containing the hot path of execution (where
1702 Show a tree-based display containing the hot path of execution (where
1703 most time was spent).
1703 most time was spent).
1704 ``bymethod``
1704 ``bymethod``
1705 Show a table of methods ordered by how frequently they are active.
1705 Show a table of methods ordered by how frequently they are active.
1706 ``byline``
1706 ``byline``
1707 Show a table of lines in files ordered by how frequently they are active.
1707 Show a table of lines in files ordered by how frequently they are active.
1708 ``json``
1708 ``json``
1709 Render profiling data as JSON.
1709 Render profiling data as JSON.
1710
1710
1711 ``frequency``
1711 ``frequency``
1712 Sampling frequency. Specific to the ``stat`` sampling profiler.
1712 Sampling frequency. Specific to the ``stat`` sampling profiler.
1713 (default: 1000)
1713 (default: 1000)
1714
1714
1715 ``output``
1715 ``output``
1716 File path where profiling data or report should be saved. If the
1716 File path where profiling data or report should be saved. If the
1717 file exists, it is replaced. (default: None, data is printed on
1717 file exists, it is replaced. (default: None, data is printed on
1718 stderr)
1718 stderr)
1719
1719
1720 ``sort``
1720 ``sort``
1721 Sort field. Specific to the ``ls`` instrumenting profiler.
1721 Sort field. Specific to the ``ls`` instrumenting profiler.
1722 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1722 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1723 ``inlinetime``.
1723 ``inlinetime``.
1724 (default: inlinetime)
1724 (default: inlinetime)
1725
1725
1726 ``time-track``
1726 ``time-track``
1727 Control if the stat profiler track ``cpu`` or ``real`` time.
1727 Control if the stat profiler track ``cpu`` or ``real`` time.
1728 (default: ``cpu`` on Windows, otherwise ``real``)
1728 (default: ``cpu`` on Windows, otherwise ``real``)
1729
1729
1730 ``limit``
1730 ``limit``
1731 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1731 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1732 (default: 30)
1732 (default: 30)
1733
1733
1734 ``nested``
1734 ``nested``
1735 Show at most this number of lines of drill-down info after each main entry.
1735 Show at most this number of lines of drill-down info after each main entry.
1736 This can help explain the difference between Total and Inline.
1736 This can help explain the difference between Total and Inline.
1737 Specific to the ``ls`` instrumenting profiler.
1737 Specific to the ``ls`` instrumenting profiler.
1738 (default: 0)
1738 (default: 0)
1739
1739
1740 ``showmin``
1740 ``showmin``
1741 Minimum fraction of samples an entry must have for it to be displayed.
1741 Minimum fraction of samples an entry must have for it to be displayed.
1742 Can be specified as a float between ``0.0`` and ``1.0`` or can have a
1742 Can be specified as a float between ``0.0`` and ``1.0`` or can have a
1743 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
1743 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
1744
1744
1745 Only used by the ``stat`` profiler.
1745 Only used by the ``stat`` profiler.
1746
1746
1747 For the ``hotpath`` format, default is ``0.05``.
1747 For the ``hotpath`` format, default is ``0.05``.
1748 For the ``chrome`` format, default is ``0.005``.
1748 For the ``chrome`` format, default is ``0.005``.
1749
1749
1750 The option is unused on other formats.
1750 The option is unused on other formats.
1751
1751
1752 ``showmax``
1752 ``showmax``
1753 Maximum fraction of samples an entry can have before it is ignored in
1753 Maximum fraction of samples an entry can have before it is ignored in
1754 display. Values format is the same as ``showmin``.
1754 display. Values format is the same as ``showmin``.
1755
1755
1756 Only used by the ``stat`` profiler.
1756 Only used by the ``stat`` profiler.
1757
1757
1758 For the ``chrome`` format, default is ``0.999``.
1758 For the ``chrome`` format, default is ``0.999``.
1759
1759
1760 The option is unused on other formats.
1760 The option is unused on other formats.
1761
1761
1762 ``progress``
1762 ``progress``
1763 ------------
1763 ------------
1764
1764
1765 Mercurial commands can draw progress bars that are as informative as
1765 Mercurial commands can draw progress bars that are as informative as
1766 possible. Some progress bars only offer indeterminate information, while others
1766 possible. Some progress bars only offer indeterminate information, while others
1767 have a definite end point.
1767 have a definite end point.
1768
1768
1769 ``debug``
1769 ``debug``
1770 Whether to print debug info when updating the progress bar. (default: False)
1770 Whether to print debug info when updating the progress bar. (default: False)
1771
1771
1772 ``delay``
1772 ``delay``
1773 Number of seconds (float) before showing the progress bar. (default: 3)
1773 Number of seconds (float) before showing the progress bar. (default: 3)
1774
1774
1775 ``changedelay``
1775 ``changedelay``
1776 Minimum delay before showing a new topic. When set to less than 3 * refresh,
1776 Minimum delay before showing a new topic. When set to less than 3 * refresh,
1777 that value will be used instead. (default: 1)
1777 that value will be used instead. (default: 1)
1778
1778
1779 ``estimateinterval``
1779 ``estimateinterval``
1780 Maximum sampling interval in seconds for speed and estimated time
1780 Maximum sampling interval in seconds for speed and estimated time
1781 calculation. (default: 60)
1781 calculation. (default: 60)
1782
1782
1783 ``refresh``
1783 ``refresh``
1784 Time in seconds between refreshes of the progress bar. (default: 0.1)
1784 Time in seconds between refreshes of the progress bar. (default: 0.1)
1785
1785
1786 ``format``
1786 ``format``
1787 Format of the progress bar.
1787 Format of the progress bar.
1788
1788
1789 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1789 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1790 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1790 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1791 last 20 characters of the item, but this can be changed by adding either
1791 last 20 characters of the item, but this can be changed by adding either
1792 ``-<num>`` which would take the last num characters, or ``+<num>`` for the
1792 ``-<num>`` which would take the last num characters, or ``+<num>`` for the
1793 first num characters.
1793 first num characters.
1794
1794
1795 (default: topic bar number estimate)
1795 (default: topic bar number estimate)
1796
1796
1797 ``width``
1797 ``width``
1798 If set, the maximum width of the progress information (that is, min(width,
1798 If set, the maximum width of the progress information (that is, min(width,
1799 term width) will be used).
1799 term width) will be used).
1800
1800
1801 ``clear-complete``
1801 ``clear-complete``
1802 Clear the progress bar after it's done. (default: True)
1802 Clear the progress bar after it's done. (default: True)
1803
1803
1804 ``disable``
1804 ``disable``
1805 If true, don't show a progress bar.
1805 If true, don't show a progress bar.
1806
1806
1807 ``assume-tty``
1807 ``assume-tty``
1808 If true, ALWAYS show a progress bar, unless disable is given.
1808 If true, ALWAYS show a progress bar, unless disable is given.
1809
1809
1810 ``rebase``
1810 ``rebase``
1811 ----------
1811 ----------
1812
1812
1813 ``evolution.allowdivergence``
1813 ``evolution.allowdivergence``
1814 Default to False, when True allow creating divergence when performing
1814 Default to False, when True allow creating divergence when performing
1815 rebase of obsolete changesets.
1815 rebase of obsolete changesets.
1816
1816
1817 ``revsetalias``
1817 ``revsetalias``
1818 ---------------
1818 ---------------
1819
1819
1820 Alias definitions for revsets. See :hg:`help revsets` for details.
1820 Alias definitions for revsets. See :hg:`help revsets` for details.
1821
1821
1822 ``rewrite``
1822 ``rewrite``
1823 -----------
1823 -----------
1824
1824
1825 ``backup-bundle``
1825 ``backup-bundle``
1826 Whether to save stripped changesets to a bundle file. (default: True)
1826 Whether to save stripped changesets to a bundle file. (default: True)
1827
1827
1828 ``update-timestamp``
1828 ``update-timestamp``
1829 If true, updates the date and time of the changeset to current. It is only
1829 If true, updates the date and time of the changeset to current. It is only
1830 applicable for hg amend in current version.
1830 applicable for hg amend in current version.
1831
1831
1832 ``storage``
1832 ``storage``
1833 -----------
1833 -----------
1834
1834
1835 Control the strategy Mercurial uses internally to store history. Options in this
1835 Control the strategy Mercurial uses internally to store history. Options in this
1836 category impact performance and repository size.
1836 category impact performance and repository size.
1837
1837
1838 ``revlog.optimize-delta-parent-choice``
1838 ``revlog.optimize-delta-parent-choice``
1839 When storing a merge revision, both parents will be equally considered as
1839 When storing a merge revision, both parents will be equally considered as
1840 a possible delta base. This results in better delta selection and improved
1840 a possible delta base. This results in better delta selection and improved
1841 revlog compression. This option is enabled by default.
1841 revlog compression. This option is enabled by default.
1842
1842
1843 Turning this option off can result in large increase of repository size for
1843 Turning this option off can result in large increase of repository size for
1844 repository with many merges.
1844 repository with many merges.
1845
1845
1846 ``revlog.reuse-external-delta-parent``
1846 ``revlog.reuse-external-delta-parent``
1847 Control the order in which delta parents are considered when adding new
1847 Control the order in which delta parents are considered when adding new
1848 revisions from an external source.
1848 revisions from an external source.
1849 (typically: apply bundle from `hg pull` or `hg push`).
1849 (typically: apply bundle from `hg pull` or `hg push`).
1850
1850
1851 New revisions are usually provided as a delta against other revisions. By
1851 New revisions are usually provided as a delta against other revisions. By
1852 default, Mercurial will try to reuse this delta first, therefore using the
1852 default, Mercurial will try to reuse this delta first, therefore using the
1853 same "delta parent" as the source. Directly using delta's from the source
1853 same "delta parent" as the source. Directly using delta's from the source
1854 reduces CPU usage and usually speeds up operation. However, in some case,
1854 reduces CPU usage and usually speeds up operation. However, in some case,
1855 the source might have sub-optimal delta bases and forcing their reevaluation
1855 the source might have sub-optimal delta bases and forcing their reevaluation
1856 is useful. For example, pushes from an old client could have sub-optimal
1856 is useful. For example, pushes from an old client could have sub-optimal
1857 delta's parent that the server want to optimize. (lack of general delta, bad
1857 delta's parent that the server want to optimize. (lack of general delta, bad
1858 parents, choice, lack of sparse-revlog, etc).
1858 parents, choice, lack of sparse-revlog, etc).
1859
1859
1860 This option is enabled by default. Turning it off will ensure bad delta
1860 This option is enabled by default. Turning it off will ensure bad delta
1861 parent choices from older client do not propagate to this repository, at
1861 parent choices from older client do not propagate to this repository, at
1862 the cost of a small increase in CPU consumption.
1862 the cost of a small increase in CPU consumption.
1863
1863
1864 Note: this option only control the order in which delta parents are
1864 Note: this option only control the order in which delta parents are
1865 considered. Even when disabled, the existing delta from the source will be
1865 considered. Even when disabled, the existing delta from the source will be
1866 reused if the same delta parent is selected.
1866 reused if the same delta parent is selected.
1867
1867
1868 ``revlog.reuse-external-delta``
1868 ``revlog.reuse-external-delta``
1869 Control the reuse of delta from external source.
1869 Control the reuse of delta from external source.
1870 (typically: apply bundle from `hg pull` or `hg push`).
1870 (typically: apply bundle from `hg pull` or `hg push`).
1871
1871
1872 New revisions are usually provided as a delta against another revision. By
1872 New revisions are usually provided as a delta against another revision. By
1873 default, Mercurial will not recompute the same delta again, trusting
1873 default, Mercurial will not recompute the same delta again, trusting
1874 externally provided deltas. There have been rare cases of small adjustment
1874 externally provided deltas. There have been rare cases of small adjustment
1875 to the diffing algorithm in the past. So in some rare case, recomputing
1875 to the diffing algorithm in the past. So in some rare case, recomputing
1876 delta provided by ancient clients can provides better results. Disabling
1876 delta provided by ancient clients can provides better results. Disabling
1877 this option means going through a full delta recomputation for all incoming
1877 this option means going through a full delta recomputation for all incoming
1878 revisions. It means a large increase in CPU usage and will slow operations
1878 revisions. It means a large increase in CPU usage and will slow operations
1879 down.
1879 down.
1880
1880
1881 This option is enabled by default. When disabled, it also disables the
1881 This option is enabled by default. When disabled, it also disables the
1882 related ``storage.revlog.reuse-external-delta-parent`` option.
1882 related ``storage.revlog.reuse-external-delta-parent`` option.
1883
1883
1884 ``server``
1884 ``server``
1885 ----------
1885 ----------
1886
1886
1887 Controls generic server settings.
1887 Controls generic server settings.
1888
1888
1889 ``bookmarks-pushkey-compat``
1889 ``bookmarks-pushkey-compat``
1890 Trigger pushkey hook when being pushed bookmark updates. This config exist
1890 Trigger pushkey hook when being pushed bookmark updates. This config exist
1891 for compatibility purpose (default to True)
1891 for compatibility purpose (default to True)
1892
1892
1893 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
1893 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
1894 movement we recommend you migrate them to ``txnclose-bookmark`` and
1894 movement we recommend you migrate them to ``txnclose-bookmark`` and
1895 ``pretxnclose-bookmark``.
1895 ``pretxnclose-bookmark``.
1896
1896
1897 ``compressionengines``
1897 ``compressionengines``
1898 List of compression engines and their relative priority to advertise
1898 List of compression engines and their relative priority to advertise
1899 to clients.
1899 to clients.
1900
1900
1901 The order of compression engines determines their priority, the first
1901 The order of compression engines determines their priority, the first
1902 having the highest priority. If a compression engine is not listed
1902 having the highest priority. If a compression engine is not listed
1903 here, it won't be advertised to clients.
1903 here, it won't be advertised to clients.
1904
1904
1905 If not set (the default), built-in defaults are used. Run
1905 If not set (the default), built-in defaults are used. Run
1906 :hg:`debuginstall` to list available compression engines and their
1906 :hg:`debuginstall` to list available compression engines and their
1907 default wire protocol priority.
1907 default wire protocol priority.
1908
1908
1909 Older Mercurial clients only support zlib compression and this setting
1909 Older Mercurial clients only support zlib compression and this setting
1910 has no effect for legacy clients.
1910 has no effect for legacy clients.
1911
1911
1912 ``uncompressed``
1912 ``uncompressed``
1913 Whether to allow clients to clone a repository using the
1913 Whether to allow clients to clone a repository using the
1914 uncompressed streaming protocol. This transfers about 40% more
1914 uncompressed streaming protocol. This transfers about 40% more
1915 data than a regular clone, but uses less memory and CPU on both
1915 data than a regular clone, but uses less memory and CPU on both
1916 server and client. Over a LAN (100 Mbps or better) or a very fast
1916 server and client. Over a LAN (100 Mbps or better) or a very fast
1917 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
1917 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
1918 regular clone. Over most WAN connections (anything slower than
1918 regular clone. Over most WAN connections (anything slower than
1919 about 6 Mbps), uncompressed streaming is slower, because of the
1919 about 6 Mbps), uncompressed streaming is slower, because of the
1920 extra data transfer overhead. This mode will also temporarily hold
1920 extra data transfer overhead. This mode will also temporarily hold
1921 the write lock while determining what data to transfer.
1921 the write lock while determining what data to transfer.
1922 (default: True)
1922 (default: True)
1923
1923
1924 ``uncompressedallowsecret``
1924 ``uncompressedallowsecret``
1925 Whether to allow stream clones when the repository contains secret
1925 Whether to allow stream clones when the repository contains secret
1926 changesets. (default: False)
1926 changesets. (default: False)
1927
1927
1928 ``preferuncompressed``
1928 ``preferuncompressed``
1929 When set, clients will try to use the uncompressed streaming
1929 When set, clients will try to use the uncompressed streaming
1930 protocol. (default: False)
1930 protocol. (default: False)
1931
1931
1932 ``disablefullbundle``
1932 ``disablefullbundle``
1933 When set, servers will refuse attempts to do pull-based clones.
1933 When set, servers will refuse attempts to do pull-based clones.
1934 If this option is set, ``preferuncompressed`` and/or clone bundles
1934 If this option is set, ``preferuncompressed`` and/or clone bundles
1935 are highly recommended. Partial clones will still be allowed.
1935 are highly recommended. Partial clones will still be allowed.
1936 (default: False)
1936 (default: False)
1937
1937
1938 ``streamunbundle``
1938 ``streamunbundle``
1939 When set, servers will apply data sent from the client directly,
1939 When set, servers will apply data sent from the client directly,
1940 otherwise it will be written to a temporary file first. This option
1940 otherwise it will be written to a temporary file first. This option
1941 effectively prevents concurrent pushes.
1941 effectively prevents concurrent pushes.
1942
1942
1943 ``pullbundle``
1943 ``pullbundle``
1944 When set, the server will check pullbundle.manifest for bundles
1944 When set, the server will check pullbundle.manifest for bundles
1945 covering the requested heads and common nodes. The first matching
1945 covering the requested heads and common nodes. The first matching
1946 entry will be streamed to the client.
1946 entry will be streamed to the client.
1947
1947
1948 For HTTP transport, the stream will still use zlib compression
1948 For HTTP transport, the stream will still use zlib compression
1949 for older clients.
1949 for older clients.
1950
1950
1951 ``concurrent-push-mode``
1951 ``concurrent-push-mode``
1952 Level of allowed race condition between two pushing clients.
1952 Level of allowed race condition between two pushing clients.
1953
1953
1954 - 'strict': push is abort if another client touched the repository
1954 - 'strict': push is abort if another client touched the repository
1955 while the push was preparing. (default)
1955 while the push was preparing. (default)
1956 - 'check-related': push is only aborted if it affects head that got also
1956 - 'check-related': push is only aborted if it affects head that got also
1957 affected while the push was preparing.
1957 affected while the push was preparing.
1958
1958
1959 This requires compatible client (version 4.3 and later). Old client will
1959 This requires compatible client (version 4.3 and later). Old client will
1960 use 'strict'.
1960 use 'strict'.
1961
1961
1962 ``validate``
1962 ``validate``
1963 Whether to validate the completeness of pushed changesets by
1963 Whether to validate the completeness of pushed changesets by
1964 checking that all new file revisions specified in manifests are
1964 checking that all new file revisions specified in manifests are
1965 present. (default: False)
1965 present. (default: False)
1966
1966
1967 ``maxhttpheaderlen``
1967 ``maxhttpheaderlen``
1968 Instruct HTTP clients not to send request headers longer than this
1968 Instruct HTTP clients not to send request headers longer than this
1969 many bytes. (default: 1024)
1969 many bytes. (default: 1024)
1970
1970
1971 ``bundle1``
1971 ``bundle1``
1972 Whether to allow clients to push and pull using the legacy bundle1
1972 Whether to allow clients to push and pull using the legacy bundle1
1973 exchange format. (default: True)
1973 exchange format. (default: True)
1974
1974
1975 ``bundle1gd``
1975 ``bundle1gd``
1976 Like ``bundle1`` but only used if the repository is using the
1976 Like ``bundle1`` but only used if the repository is using the
1977 *generaldelta* storage format. (default: True)
1977 *generaldelta* storage format. (default: True)
1978
1978
1979 ``bundle1.push``
1979 ``bundle1.push``
1980 Whether to allow clients to push using the legacy bundle1 exchange
1980 Whether to allow clients to push using the legacy bundle1 exchange
1981 format. (default: True)
1981 format. (default: True)
1982
1982
1983 ``bundle1gd.push``
1983 ``bundle1gd.push``
1984 Like ``bundle1.push`` but only used if the repository is using the
1984 Like ``bundle1.push`` but only used if the repository is using the
1985 *generaldelta* storage format. (default: True)
1985 *generaldelta* storage format. (default: True)
1986
1986
1987 ``bundle1.pull``
1987 ``bundle1.pull``
1988 Whether to allow clients to pull using the legacy bundle1 exchange
1988 Whether to allow clients to pull using the legacy bundle1 exchange
1989 format. (default: True)
1989 format. (default: True)
1990
1990
1991 ``bundle1gd.pull``
1991 ``bundle1gd.pull``
1992 Like ``bundle1.pull`` but only used if the repository is using the
1992 Like ``bundle1.pull`` but only used if the repository is using the
1993 *generaldelta* storage format. (default: True)
1993 *generaldelta* storage format. (default: True)
1994
1994
1995 Large repositories using the *generaldelta* storage format should
1995 Large repositories using the *generaldelta* storage format should
1996 consider setting this option because converting *generaldelta*
1996 consider setting this option because converting *generaldelta*
1997 repositories to the exchange format required by the bundle1 data
1997 repositories to the exchange format required by the bundle1 data
1998 format can consume a lot of CPU.
1998 format can consume a lot of CPU.
1999
1999
2000 ``bundle2.stream``
2000 ``bundle2.stream``
2001 Whether to allow clients to pull using the bundle2 streaming protocol.
2001 Whether to allow clients to pull using the bundle2 streaming protocol.
2002 (default: True)
2002 (default: True)
2003
2003
2004 ``zliblevel``
2004 ``zliblevel``
2005 Integer between ``-1`` and ``9`` that controls the zlib compression level
2005 Integer between ``-1`` and ``9`` that controls the zlib compression level
2006 for wire protocol commands that send zlib compressed output (notably the
2006 for wire protocol commands that send zlib compressed output (notably the
2007 commands that send repository history data).
2007 commands that send repository history data).
2008
2008
2009 The default (``-1``) uses the default zlib compression level, which is
2009 The default (``-1``) uses the default zlib compression level, which is
2010 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2010 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2011 maximum compression.
2011 maximum compression.
2012
2012
2013 Setting this option allows server operators to make trade-offs between
2013 Setting this option allows server operators to make trade-offs between
2014 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2014 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2015 but sends more bytes to clients.
2015 but sends more bytes to clients.
2016
2016
2017 This option only impacts the HTTP server.
2017 This option only impacts the HTTP server.
2018
2018
2019 ``zstdlevel``
2019 ``zstdlevel``
2020 Integer between ``1`` and ``22`` that controls the zstd compression level
2020 Integer between ``1`` and ``22`` that controls the zstd compression level
2021 for wire protocol commands. ``1`` is the minimal amount of compression and
2021 for wire protocol commands. ``1`` is the minimal amount of compression and
2022 ``22`` is the highest amount of compression.
2022 ``22`` is the highest amount of compression.
2023
2023
2024 The default (``3``) should be significantly faster than zlib while likely
2024 The default (``3``) should be significantly faster than zlib while likely
2025 delivering better compression ratios.
2025 delivering better compression ratios.
2026
2026
2027 This option only impacts the HTTP server.
2027 This option only impacts the HTTP server.
2028
2028
2029 See also ``server.zliblevel``.
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 ``smtp``
2037 ``smtp``
2032 --------
2038 --------
2033
2039
2034 Configuration for extensions that need to send email messages.
2040 Configuration for extensions that need to send email messages.
2035
2041
2036 ``host``
2042 ``host``
2037 Host name of mail server, e.g. "mail.example.com".
2043 Host name of mail server, e.g. "mail.example.com".
2038
2044
2039 ``port``
2045 ``port``
2040 Optional. Port to connect to on mail server. (default: 465 if
2046 Optional. Port to connect to on mail server. (default: 465 if
2041 ``tls`` is smtps; 25 otherwise)
2047 ``tls`` is smtps; 25 otherwise)
2042
2048
2043 ``tls``
2049 ``tls``
2044 Optional. Method to enable TLS when connecting to mail server: starttls,
2050 Optional. Method to enable TLS when connecting to mail server: starttls,
2045 smtps or none. (default: none)
2051 smtps or none. (default: none)
2046
2052
2047 ``username``
2053 ``username``
2048 Optional. User name for authenticating with the SMTP server.
2054 Optional. User name for authenticating with the SMTP server.
2049 (default: None)
2055 (default: None)
2050
2056
2051 ``password``
2057 ``password``
2052 Optional. Password for authenticating with the SMTP server. If not
2058 Optional. Password for authenticating with the SMTP server. If not
2053 specified, interactive sessions will prompt the user for a
2059 specified, interactive sessions will prompt the user for a
2054 password; non-interactive sessions will fail. (default: None)
2060 password; non-interactive sessions will fail. (default: None)
2055
2061
2056 ``local_hostname``
2062 ``local_hostname``
2057 Optional. The hostname that the sender can use to identify
2063 Optional. The hostname that the sender can use to identify
2058 itself to the MTA.
2064 itself to the MTA.
2059
2065
2060
2066
2061 ``subpaths``
2067 ``subpaths``
2062 ------------
2068 ------------
2063
2069
2064 Subrepository source URLs can go stale if a remote server changes name
2070 Subrepository source URLs can go stale if a remote server changes name
2065 or becomes temporarily unavailable. This section lets you define
2071 or becomes temporarily unavailable. This section lets you define
2066 rewrite rules of the form::
2072 rewrite rules of the form::
2067
2073
2068 <pattern> = <replacement>
2074 <pattern> = <replacement>
2069
2075
2070 where ``pattern`` is a regular expression matching a subrepository
2076 where ``pattern`` is a regular expression matching a subrepository
2071 source URL and ``replacement`` is the replacement string used to
2077 source URL and ``replacement`` is the replacement string used to
2072 rewrite it. Groups can be matched in ``pattern`` and referenced in
2078 rewrite it. Groups can be matched in ``pattern`` and referenced in
2073 ``replacements``. For instance::
2079 ``replacements``. For instance::
2074
2080
2075 http://server/(.*)-hg/ = http://hg.server/\1/
2081 http://server/(.*)-hg/ = http://hg.server/\1/
2076
2082
2077 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2083 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2078
2084
2079 Relative subrepository paths are first made absolute, and the
2085 Relative subrepository paths are first made absolute, and the
2080 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2086 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2081 doesn't match the full path, an attempt is made to apply it on the
2087 doesn't match the full path, an attempt is made to apply it on the
2082 relative path alone. The rules are applied in definition order.
2088 relative path alone. The rules are applied in definition order.
2083
2089
2084 ``subrepos``
2090 ``subrepos``
2085 ------------
2091 ------------
2086
2092
2087 This section contains options that control the behavior of the
2093 This section contains options that control the behavior of the
2088 subrepositories feature. See also :hg:`help subrepos`.
2094 subrepositories feature. See also :hg:`help subrepos`.
2089
2095
2090 Security note: auditing in Mercurial is known to be insufficient to
2096 Security note: auditing in Mercurial is known to be insufficient to
2091 prevent clone-time code execution with carefully constructed Git
2097 prevent clone-time code execution with carefully constructed Git
2092 subrepos. It is unknown if a similar detect is present in Subversion
2098 subrepos. It is unknown if a similar detect is present in Subversion
2093 subrepos. Both Git and Subversion subrepos are disabled by default
2099 subrepos. Both Git and Subversion subrepos are disabled by default
2094 out of security concerns. These subrepo types can be enabled using
2100 out of security concerns. These subrepo types can be enabled using
2095 the respective options below.
2101 the respective options below.
2096
2102
2097 ``allowed``
2103 ``allowed``
2098 Whether subrepositories are allowed in the working directory.
2104 Whether subrepositories are allowed in the working directory.
2099
2105
2100 When false, commands involving subrepositories (like :hg:`update`)
2106 When false, commands involving subrepositories (like :hg:`update`)
2101 will fail for all subrepository types.
2107 will fail for all subrepository types.
2102 (default: true)
2108 (default: true)
2103
2109
2104 ``hg:allowed``
2110 ``hg:allowed``
2105 Whether Mercurial subrepositories are allowed in the working
2111 Whether Mercurial subrepositories are allowed in the working
2106 directory. This option only has an effect if ``subrepos.allowed``
2112 directory. This option only has an effect if ``subrepos.allowed``
2107 is true.
2113 is true.
2108 (default: true)
2114 (default: true)
2109
2115
2110 ``git:allowed``
2116 ``git:allowed``
2111 Whether Git subrepositories are allowed in the working directory.
2117 Whether Git subrepositories are allowed in the working directory.
2112 This option only has an effect if ``subrepos.allowed`` is true.
2118 This option only has an effect if ``subrepos.allowed`` is true.
2113
2119
2114 See the security note above before enabling Git subrepos.
2120 See the security note above before enabling Git subrepos.
2115 (default: false)
2121 (default: false)
2116
2122
2117 ``svn:allowed``
2123 ``svn:allowed``
2118 Whether Subversion subrepositories are allowed in the working
2124 Whether Subversion subrepositories are allowed in the working
2119 directory. This option only has an effect if ``subrepos.allowed``
2125 directory. This option only has an effect if ``subrepos.allowed``
2120 is true.
2126 is true.
2121
2127
2122 See the security note above before enabling Subversion subrepos.
2128 See the security note above before enabling Subversion subrepos.
2123 (default: false)
2129 (default: false)
2124
2130
2125 ``templatealias``
2131 ``templatealias``
2126 -----------------
2132 -----------------
2127
2133
2128 Alias definitions for templates. See :hg:`help templates` for details.
2134 Alias definitions for templates. See :hg:`help templates` for details.
2129
2135
2130 ``templates``
2136 ``templates``
2131 -------------
2137 -------------
2132
2138
2133 Use the ``[templates]`` section to define template strings.
2139 Use the ``[templates]`` section to define template strings.
2134 See :hg:`help templates` for details.
2140 See :hg:`help templates` for details.
2135
2141
2136 ``trusted``
2142 ``trusted``
2137 -----------
2143 -----------
2138
2144
2139 Mercurial will not use the settings in the
2145 Mercurial will not use the settings in the
2140 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2146 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2141 user or to a trusted group, as various hgrc features allow arbitrary
2147 user or to a trusted group, as various hgrc features allow arbitrary
2142 commands to be run. This issue is often encountered when configuring
2148 commands to be run. This issue is often encountered when configuring
2143 hooks or extensions for shared repositories or servers. However,
2149 hooks or extensions for shared repositories or servers. However,
2144 the web interface will use some safe settings from the ``[web]``
2150 the web interface will use some safe settings from the ``[web]``
2145 section.
2151 section.
2146
2152
2147 This section specifies what users and groups are trusted. The
2153 This section specifies what users and groups are trusted. The
2148 current user is always trusted. To trust everybody, list a user or a
2154 current user is always trusted. To trust everybody, list a user or a
2149 group with name ``*``. These settings must be placed in an
2155 group with name ``*``. These settings must be placed in an
2150 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2156 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2151 user or service running Mercurial.
2157 user or service running Mercurial.
2152
2158
2153 ``users``
2159 ``users``
2154 Comma-separated list of trusted users.
2160 Comma-separated list of trusted users.
2155
2161
2156 ``groups``
2162 ``groups``
2157 Comma-separated list of trusted groups.
2163 Comma-separated list of trusted groups.
2158
2164
2159
2165
2160 ``ui``
2166 ``ui``
2161 ------
2167 ------
2162
2168
2163 User interface controls.
2169 User interface controls.
2164
2170
2165 ``archivemeta``
2171 ``archivemeta``
2166 Whether to include the .hg_archival.txt file containing meta data
2172 Whether to include the .hg_archival.txt file containing meta data
2167 (hashes for the repository base and for tip) in archives created
2173 (hashes for the repository base and for tip) in archives created
2168 by the :hg:`archive` command or downloaded via hgweb.
2174 by the :hg:`archive` command or downloaded via hgweb.
2169 (default: True)
2175 (default: True)
2170
2176
2171 ``askusername``
2177 ``askusername``
2172 Whether to prompt for a username when committing. If True, and
2178 Whether to prompt for a username when committing. If True, and
2173 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2179 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2174 be prompted to enter a username. If no username is entered, the
2180 be prompted to enter a username. If no username is entered, the
2175 default ``USER@HOST`` is used instead.
2181 default ``USER@HOST`` is used instead.
2176 (default: False)
2182 (default: False)
2177
2183
2178 ``clonebundles``
2184 ``clonebundles``
2179 Whether the "clone bundles" feature is enabled.
2185 Whether the "clone bundles" feature is enabled.
2180
2186
2181 When enabled, :hg:`clone` may download and apply a server-advertised
2187 When enabled, :hg:`clone` may download and apply a server-advertised
2182 bundle file from a URL instead of using the normal exchange mechanism.
2188 bundle file from a URL instead of using the normal exchange mechanism.
2183
2189
2184 This can likely result in faster and more reliable clones.
2190 This can likely result in faster and more reliable clones.
2185
2191
2186 (default: True)
2192 (default: True)
2187
2193
2188 ``clonebundlefallback``
2194 ``clonebundlefallback``
2189 Whether failure to apply an advertised "clone bundle" from a server
2195 Whether failure to apply an advertised "clone bundle" from a server
2190 should result in fallback to a regular clone.
2196 should result in fallback to a regular clone.
2191
2197
2192 This is disabled by default because servers advertising "clone
2198 This is disabled by default because servers advertising "clone
2193 bundles" often do so to reduce server load. If advertised bundles
2199 bundles" often do so to reduce server load. If advertised bundles
2194 start mass failing and clients automatically fall back to a regular
2200 start mass failing and clients automatically fall back to a regular
2195 clone, this would add significant and unexpected load to the server
2201 clone, this would add significant and unexpected load to the server
2196 since the server is expecting clone operations to be offloaded to
2202 since the server is expecting clone operations to be offloaded to
2197 pre-generated bundles. Failing fast (the default behavior) ensures
2203 pre-generated bundles. Failing fast (the default behavior) ensures
2198 clients don't overwhelm the server when "clone bundle" application
2204 clients don't overwhelm the server when "clone bundle" application
2199 fails.
2205 fails.
2200
2206
2201 (default: False)
2207 (default: False)
2202
2208
2203 ``clonebundleprefers``
2209 ``clonebundleprefers``
2204 Defines preferences for which "clone bundles" to use.
2210 Defines preferences for which "clone bundles" to use.
2205
2211
2206 Servers advertising "clone bundles" may advertise multiple available
2212 Servers advertising "clone bundles" may advertise multiple available
2207 bundles. Each bundle may have different attributes, such as the bundle
2213 bundles. Each bundle may have different attributes, such as the bundle
2208 type and compression format. This option is used to prefer a particular
2214 type and compression format. This option is used to prefer a particular
2209 bundle over another.
2215 bundle over another.
2210
2216
2211 The following keys are defined by Mercurial:
2217 The following keys are defined by Mercurial:
2212
2218
2213 BUNDLESPEC
2219 BUNDLESPEC
2214 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2220 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2215 e.g. ``gzip-v2`` or ``bzip2-v1``.
2221 e.g. ``gzip-v2`` or ``bzip2-v1``.
2216
2222
2217 COMPRESSION
2223 COMPRESSION
2218 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2224 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2219
2225
2220 Server operators may define custom keys.
2226 Server operators may define custom keys.
2221
2227
2222 Example values: ``COMPRESSION=bzip2``,
2228 Example values: ``COMPRESSION=bzip2``,
2223 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2229 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2224
2230
2225 By default, the first bundle advertised by the server is used.
2231 By default, the first bundle advertised by the server is used.
2226
2232
2227 ``color``
2233 ``color``
2228 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2234 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2229 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2235 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2230 seems possible. See :hg:`help color` for details.
2236 seems possible. See :hg:`help color` for details.
2231
2237
2232 ``commitsubrepos``
2238 ``commitsubrepos``
2233 Whether to commit modified subrepositories when committing the
2239 Whether to commit modified subrepositories when committing the
2234 parent repository. If False and one subrepository has uncommitted
2240 parent repository. If False and one subrepository has uncommitted
2235 changes, abort the commit.
2241 changes, abort the commit.
2236 (default: False)
2242 (default: False)
2237
2243
2238 ``debug``
2244 ``debug``
2239 Print debugging information. (default: False)
2245 Print debugging information. (default: False)
2240
2246
2241 ``editor``
2247 ``editor``
2242 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2248 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2243
2249
2244 ``fallbackencoding``
2250 ``fallbackencoding``
2245 Encoding to try if it's not possible to decode the changelog using
2251 Encoding to try if it's not possible to decode the changelog using
2246 UTF-8. (default: ISO-8859-1)
2252 UTF-8. (default: ISO-8859-1)
2247
2253
2248 ``graphnodetemplate``
2254 ``graphnodetemplate``
2249 The template used to print changeset nodes in an ASCII revision graph.
2255 The template used to print changeset nodes in an ASCII revision graph.
2250 (default: ``{graphnode}``)
2256 (default: ``{graphnode}``)
2251
2257
2252 ``ignore``
2258 ``ignore``
2253 A file to read per-user ignore patterns from. This file should be
2259 A file to read per-user ignore patterns from. This file should be
2254 in the same format as a repository-wide .hgignore file. Filenames
2260 in the same format as a repository-wide .hgignore file. Filenames
2255 are relative to the repository root. This option supports hook syntax,
2261 are relative to the repository root. This option supports hook syntax,
2256 so if you want to specify multiple ignore files, you can do so by
2262 so if you want to specify multiple ignore files, you can do so by
2257 setting something like ``ignore.other = ~/.hgignore2``. For details
2263 setting something like ``ignore.other = ~/.hgignore2``. For details
2258 of the ignore file format, see the ``hgignore(5)`` man page.
2264 of the ignore file format, see the ``hgignore(5)`` man page.
2259
2265
2260 ``interactive``
2266 ``interactive``
2261 Allow to prompt the user. (default: True)
2267 Allow to prompt the user. (default: True)
2262
2268
2263 ``interface``
2269 ``interface``
2264 Select the default interface for interactive features (default: text).
2270 Select the default interface for interactive features (default: text).
2265 Possible values are 'text' and 'curses'.
2271 Possible values are 'text' and 'curses'.
2266
2272
2267 ``interface.chunkselector``
2273 ``interface.chunkselector``
2268 Select the interface for change recording (e.g. :hg:`commit -i`).
2274 Select the interface for change recording (e.g. :hg:`commit -i`).
2269 Possible values are 'text' and 'curses'.
2275 Possible values are 'text' and 'curses'.
2270 This config overrides the interface specified by ui.interface.
2276 This config overrides the interface specified by ui.interface.
2271
2277
2272 ``large-file-limit``
2278 ``large-file-limit``
2273 Largest file size that gives no memory use warning.
2279 Largest file size that gives no memory use warning.
2274 Possible values are integers or 0 to disable the check.
2280 Possible values are integers or 0 to disable the check.
2275 (default: 10000000)
2281 (default: 10000000)
2276
2282
2277 ``logtemplate``
2283 ``logtemplate``
2278 Template string for commands that print changesets.
2284 Template string for commands that print changesets.
2279
2285
2280 ``merge``
2286 ``merge``
2281 The conflict resolution program to use during a manual merge.
2287 The conflict resolution program to use during a manual merge.
2282 For more information on merge tools see :hg:`help merge-tools`.
2288 For more information on merge tools see :hg:`help merge-tools`.
2283 For configuring merge tools see the ``[merge-tools]`` section.
2289 For configuring merge tools see the ``[merge-tools]`` section.
2284
2290
2285 ``mergemarkers``
2291 ``mergemarkers``
2286 Sets the merge conflict marker label styling. The ``detailed``
2292 Sets the merge conflict marker label styling. The ``detailed``
2287 style uses the ``mergemarkertemplate`` setting to style the labels.
2293 style uses the ``mergemarkertemplate`` setting to style the labels.
2288 The ``basic`` style just uses 'local' and 'other' as the marker label.
2294 The ``basic`` style just uses 'local' and 'other' as the marker label.
2289 One of ``basic`` or ``detailed``.
2295 One of ``basic`` or ``detailed``.
2290 (default: ``basic``)
2296 (default: ``basic``)
2291
2297
2292 ``mergemarkertemplate``
2298 ``mergemarkertemplate``
2293 The template used to print the commit description next to each conflict
2299 The template used to print the commit description next to each conflict
2294 marker during merge conflicts. See :hg:`help templates` for the template
2300 marker during merge conflicts. See :hg:`help templates` for the template
2295 format.
2301 format.
2296
2302
2297 Defaults to showing the hash, tags, branches, bookmarks, author, and
2303 Defaults to showing the hash, tags, branches, bookmarks, author, and
2298 the first line of the commit description.
2304 the first line of the commit description.
2299
2305
2300 If you use non-ASCII characters in names for tags, branches, bookmarks,
2306 If you use non-ASCII characters in names for tags, branches, bookmarks,
2301 authors, and/or commit descriptions, you must pay attention to encodings of
2307 authors, and/or commit descriptions, you must pay attention to encodings of
2302 managed files. At template expansion, non-ASCII characters use the encoding
2308 managed files. At template expansion, non-ASCII characters use the encoding
2303 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2309 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2304 environment variables that govern your locale. If the encoding of the merge
2310 environment variables that govern your locale. If the encoding of the merge
2305 markers is different from the encoding of the merged files,
2311 markers is different from the encoding of the merged files,
2306 serious problems may occur.
2312 serious problems may occur.
2307
2313
2308 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2314 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2309
2315
2310 ``message-output``
2316 ``message-output``
2311 Where to write status and error messages. (default: ``stdio``)
2317 Where to write status and error messages. (default: ``stdio``)
2312
2318
2313 ``stderr``
2319 ``stderr``
2314 Everything to stderr.
2320 Everything to stderr.
2315 ``stdio``
2321 ``stdio``
2316 Status to stdout, and error to stderr.
2322 Status to stdout, and error to stderr.
2317
2323
2318 ``origbackuppath``
2324 ``origbackuppath``
2319 The path to a directory used to store generated .orig files. If the path is
2325 The path to a directory used to store generated .orig files. If the path is
2320 not a directory, one will be created. If set, files stored in this
2326 not a directory, one will be created. If set, files stored in this
2321 directory have the same name as the original file and do not have a .orig
2327 directory have the same name as the original file and do not have a .orig
2322 suffix.
2328 suffix.
2323
2329
2324 ``paginate``
2330 ``paginate``
2325 Control the pagination of command output (default: True). See :hg:`help pager`
2331 Control the pagination of command output (default: True). See :hg:`help pager`
2326 for details.
2332 for details.
2327
2333
2328 ``patch``
2334 ``patch``
2329 An optional external tool that ``hg import`` and some extensions
2335 An optional external tool that ``hg import`` and some extensions
2330 will use for applying patches. By default Mercurial uses an
2336 will use for applying patches. By default Mercurial uses an
2331 internal patch utility. The external tool must work as the common
2337 internal patch utility. The external tool must work as the common
2332 Unix ``patch`` program. In particular, it must accept a ``-p``
2338 Unix ``patch`` program. In particular, it must accept a ``-p``
2333 argument to strip patch headers, a ``-d`` argument to specify the
2339 argument to strip patch headers, a ``-d`` argument to specify the
2334 current directory, a file name to patch, and a patch file to take
2340 current directory, a file name to patch, and a patch file to take
2335 from stdin.
2341 from stdin.
2336
2342
2337 It is possible to specify a patch tool together with extra
2343 It is possible to specify a patch tool together with extra
2338 arguments. For example, setting this option to ``patch --merge``
2344 arguments. For example, setting this option to ``patch --merge``
2339 will use the ``patch`` program with its 2-way merge option.
2345 will use the ``patch`` program with its 2-way merge option.
2340
2346
2341 ``portablefilenames``
2347 ``portablefilenames``
2342 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2348 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2343 (default: ``warn``)
2349 (default: ``warn``)
2344
2350
2345 ``warn``
2351 ``warn``
2346 Print a warning message on POSIX platforms, if a file with a non-portable
2352 Print a warning message on POSIX platforms, if a file with a non-portable
2347 filename is added (e.g. a file with a name that can't be created on
2353 filename is added (e.g. a file with a name that can't be created on
2348 Windows because it contains reserved parts like ``AUX``, reserved
2354 Windows because it contains reserved parts like ``AUX``, reserved
2349 characters like ``:``, or would cause a case collision with an existing
2355 characters like ``:``, or would cause a case collision with an existing
2350 file).
2356 file).
2351
2357
2352 ``ignore``
2358 ``ignore``
2353 Don't print a warning.
2359 Don't print a warning.
2354
2360
2355 ``abort``
2361 ``abort``
2356 The command is aborted.
2362 The command is aborted.
2357
2363
2358 ``true``
2364 ``true``
2359 Alias for ``warn``.
2365 Alias for ``warn``.
2360
2366
2361 ``false``
2367 ``false``
2362 Alias for ``ignore``.
2368 Alias for ``ignore``.
2363
2369
2364 .. container:: windows
2370 .. container:: windows
2365
2371
2366 On Windows, this configuration option is ignored and the command aborted.
2372 On Windows, this configuration option is ignored and the command aborted.
2367
2373
2368 ``pre-merge-tool-output-template``
2374 ``pre-merge-tool-output-template``
2369 A template that is printed before executing an external merge tool. This can
2375 A template that is printed before executing an external merge tool. This can
2370 be used to print out additional context that might be useful to have during
2376 be used to print out additional context that might be useful to have during
2371 the conflict resolution, such as the description of the various commits
2377 the conflict resolution, such as the description of the various commits
2372 involved or bookmarks/tags.
2378 involved or bookmarks/tags.
2373
2379
2374 Additional information is available in the ``local`, ``base``, and ``other``
2380 Additional information is available in the ``local`, ``base``, and ``other``
2375 dicts. For example: ``{local.label}``, ``{base.name}``, or
2381 dicts. For example: ``{local.label}``, ``{base.name}``, or
2376 ``{other.islink}``.
2382 ``{other.islink}``.
2377
2383
2378 ``quiet``
2384 ``quiet``
2379 Reduce the amount of output printed.
2385 Reduce the amount of output printed.
2380 (default: False)
2386 (default: False)
2381
2387
2382 ``relative-paths``
2388 ``relative-paths``
2383 Prefer relative paths in the UI.
2389 Prefer relative paths in the UI.
2384
2390
2385 ``remotecmd``
2391 ``remotecmd``
2386 Remote command to use for clone/push/pull operations.
2392 Remote command to use for clone/push/pull operations.
2387 (default: ``hg``)
2393 (default: ``hg``)
2388
2394
2389 ``report_untrusted``
2395 ``report_untrusted``
2390 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2396 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2391 trusted user or group.
2397 trusted user or group.
2392 (default: True)
2398 (default: True)
2393
2399
2394 ``slash``
2400 ``slash``
2395 (Deprecated. Use ``slashpath`` template filter instead.)
2401 (Deprecated. Use ``slashpath`` template filter instead.)
2396
2402
2397 Display paths using a slash (``/``) as the path separator. This
2403 Display paths using a slash (``/``) as the path separator. This
2398 only makes a difference on systems where the default path
2404 only makes a difference on systems where the default path
2399 separator is not the slash character (e.g. Windows uses the
2405 separator is not the slash character (e.g. Windows uses the
2400 backslash character (``\``)).
2406 backslash character (``\``)).
2401 (default: False)
2407 (default: False)
2402
2408
2403 ``statuscopies``
2409 ``statuscopies``
2404 Display copies in the status command.
2410 Display copies in the status command.
2405
2411
2406 ``ssh``
2412 ``ssh``
2407 Command to use for SSH connections. (default: ``ssh``)
2413 Command to use for SSH connections. (default: ``ssh``)
2408
2414
2409 ``ssherrorhint``
2415 ``ssherrorhint``
2410 A hint shown to the user in the case of SSH error (e.g.
2416 A hint shown to the user in the case of SSH error (e.g.
2411 ``Please see http://company/internalwiki/ssh.html``)
2417 ``Please see http://company/internalwiki/ssh.html``)
2412
2418
2413 ``strict``
2419 ``strict``
2414 Require exact command names, instead of allowing unambiguous
2420 Require exact command names, instead of allowing unambiguous
2415 abbreviations. (default: False)
2421 abbreviations. (default: False)
2416
2422
2417 ``style``
2423 ``style``
2418 Name of style to use for command output.
2424 Name of style to use for command output.
2419
2425
2420 ``supportcontact``
2426 ``supportcontact``
2421 A URL where users should report a Mercurial traceback. Use this if you are a
2427 A URL where users should report a Mercurial traceback. Use this if you are a
2422 large organisation with its own Mercurial deployment process and crash
2428 large organisation with its own Mercurial deployment process and crash
2423 reports should be addressed to your internal support.
2429 reports should be addressed to your internal support.
2424
2430
2425 ``textwidth``
2431 ``textwidth``
2426 Maximum width of help text. A longer line generated by ``hg help`` or
2432 Maximum width of help text. A longer line generated by ``hg help`` or
2427 ``hg subcommand --help`` will be broken after white space to get this
2433 ``hg subcommand --help`` will be broken after white space to get this
2428 width or the terminal width, whichever comes first.
2434 width or the terminal width, whichever comes first.
2429 A non-positive value will disable this and the terminal width will be
2435 A non-positive value will disable this and the terminal width will be
2430 used. (default: 78)
2436 used. (default: 78)
2431
2437
2432 ``timeout``
2438 ``timeout``
2433 The timeout used when a lock is held (in seconds), a negative value
2439 The timeout used when a lock is held (in seconds), a negative value
2434 means no timeout. (default: 600)
2440 means no timeout. (default: 600)
2435
2441
2436 ``timeout.warn``
2442 ``timeout.warn``
2437 Time (in seconds) before a warning is printed about held lock. A negative
2443 Time (in seconds) before a warning is printed about held lock. A negative
2438 value means no warning. (default: 0)
2444 value means no warning. (default: 0)
2439
2445
2440 ``traceback``
2446 ``traceback``
2441 Mercurial always prints a traceback when an unknown exception
2447 Mercurial always prints a traceback when an unknown exception
2442 occurs. Setting this to True will make Mercurial print a traceback
2448 occurs. Setting this to True will make Mercurial print a traceback
2443 on all exceptions, even those recognized by Mercurial (such as
2449 on all exceptions, even those recognized by Mercurial (such as
2444 IOError or MemoryError). (default: False)
2450 IOError or MemoryError). (default: False)
2445
2451
2446 ``tweakdefaults``
2452 ``tweakdefaults``
2447
2453
2448 By default Mercurial's behavior changes very little from release
2454 By default Mercurial's behavior changes very little from release
2449 to release, but over time the recommended config settings
2455 to release, but over time the recommended config settings
2450 shift. Enable this config to opt in to get automatic tweaks to
2456 shift. Enable this config to opt in to get automatic tweaks to
2451 Mercurial's behavior over time. This config setting will have no
2457 Mercurial's behavior over time. This config setting will have no
2452 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2458 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2453 not include ``tweakdefaults``. (default: False)
2459 not include ``tweakdefaults``. (default: False)
2454
2460
2455 It currently means::
2461 It currently means::
2456
2462
2457 .. tweakdefaultsmarker
2463 .. tweakdefaultsmarker
2458
2464
2459 ``username``
2465 ``username``
2460 The committer of a changeset created when running "commit".
2466 The committer of a changeset created when running "commit".
2461 Typically a person's name and email address, e.g. ``Fred Widget
2467 Typically a person's name and email address, e.g. ``Fred Widget
2462 <fred@example.com>``. Environment variables in the
2468 <fred@example.com>``. Environment variables in the
2463 username are expanded.
2469 username are expanded.
2464
2470
2465 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2471 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2466 hgrc is empty, e.g. if the system admin set ``username =`` in the
2472 hgrc is empty, e.g. if the system admin set ``username =`` in the
2467 system hgrc, it has to be specified manually or in a different
2473 system hgrc, it has to be specified manually or in a different
2468 hgrc file)
2474 hgrc file)
2469
2475
2470 ``verbose``
2476 ``verbose``
2471 Increase the amount of output printed. (default: False)
2477 Increase the amount of output printed. (default: False)
2472
2478
2473
2479
2474 ``web``
2480 ``web``
2475 -------
2481 -------
2476
2482
2477 Web interface configuration. The settings in this section apply to
2483 Web interface configuration. The settings in this section apply to
2478 both the builtin webserver (started by :hg:`serve`) and the script you
2484 both the builtin webserver (started by :hg:`serve`) and the script you
2479 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2485 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2480 and WSGI).
2486 and WSGI).
2481
2487
2482 The Mercurial webserver does no authentication (it does not prompt for
2488 The Mercurial webserver does no authentication (it does not prompt for
2483 usernames and passwords to validate *who* users are), but it does do
2489 usernames and passwords to validate *who* users are), but it does do
2484 authorization (it grants or denies access for *authenticated users*
2490 authorization (it grants or denies access for *authenticated users*
2485 based on settings in this section). You must either configure your
2491 based on settings in this section). You must either configure your
2486 webserver to do authentication for you, or disable the authorization
2492 webserver to do authentication for you, or disable the authorization
2487 checks.
2493 checks.
2488
2494
2489 For a quick setup in a trusted environment, e.g., a private LAN, where
2495 For a quick setup in a trusted environment, e.g., a private LAN, where
2490 you want it to accept pushes from anybody, you can use the following
2496 you want it to accept pushes from anybody, you can use the following
2491 command line::
2497 command line::
2492
2498
2493 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2499 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2494
2500
2495 Note that this will allow anybody to push anything to the server and
2501 Note that this will allow anybody to push anything to the server and
2496 that this should not be used for public servers.
2502 that this should not be used for public servers.
2497
2503
2498 The full set of options is:
2504 The full set of options is:
2499
2505
2500 ``accesslog``
2506 ``accesslog``
2501 Where to output the access log. (default: stdout)
2507 Where to output the access log. (default: stdout)
2502
2508
2503 ``address``
2509 ``address``
2504 Interface address to bind to. (default: all)
2510 Interface address to bind to. (default: all)
2505
2511
2506 ``allow-archive``
2512 ``allow-archive``
2507 List of archive format (bz2, gz, zip) allowed for downloading.
2513 List of archive format (bz2, gz, zip) allowed for downloading.
2508 (default: empty)
2514 (default: empty)
2509
2515
2510 ``allowbz2``
2516 ``allowbz2``
2511 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2517 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2512 revisions.
2518 revisions.
2513 (default: False)
2519 (default: False)
2514
2520
2515 ``allowgz``
2521 ``allowgz``
2516 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2522 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2517 revisions.
2523 revisions.
2518 (default: False)
2524 (default: False)
2519
2525
2520 ``allow-pull``
2526 ``allow-pull``
2521 Whether to allow pulling from the repository. (default: True)
2527 Whether to allow pulling from the repository. (default: True)
2522
2528
2523 ``allow-push``
2529 ``allow-push``
2524 Whether to allow pushing to the repository. If empty or not set,
2530 Whether to allow pushing to the repository. If empty or not set,
2525 pushing is not allowed. If the special value ``*``, any remote
2531 pushing is not allowed. If the special value ``*``, any remote
2526 user can push, including unauthenticated users. Otherwise, the
2532 user can push, including unauthenticated users. Otherwise, the
2527 remote user must have been authenticated, and the authenticated
2533 remote user must have been authenticated, and the authenticated
2528 user name must be present in this list. The contents of the
2534 user name must be present in this list. The contents of the
2529 allow-push list are examined after the deny_push list.
2535 allow-push list are examined after the deny_push list.
2530
2536
2531 ``allow_read``
2537 ``allow_read``
2532 If the user has not already been denied repository access due to
2538 If the user has not already been denied repository access due to
2533 the contents of deny_read, this list determines whether to grant
2539 the contents of deny_read, this list determines whether to grant
2534 repository access to the user. If this list is not empty, and the
2540 repository access to the user. If this list is not empty, and the
2535 user is unauthenticated or not present in the list, then access is
2541 user is unauthenticated or not present in the list, then access is
2536 denied for the user. If the list is empty or not set, then access
2542 denied for the user. If the list is empty or not set, then access
2537 is permitted to all users by default. Setting allow_read to the
2543 is permitted to all users by default. Setting allow_read to the
2538 special value ``*`` is equivalent to it not being set (i.e. access
2544 special value ``*`` is equivalent to it not being set (i.e. access
2539 is permitted to all users). The contents of the allow_read list are
2545 is permitted to all users). The contents of the allow_read list are
2540 examined after the deny_read list.
2546 examined after the deny_read list.
2541
2547
2542 ``allowzip``
2548 ``allowzip``
2543 (DEPRECATED) Whether to allow .zip downloading of repository
2549 (DEPRECATED) Whether to allow .zip downloading of repository
2544 revisions. This feature creates temporary files.
2550 revisions. This feature creates temporary files.
2545 (default: False)
2551 (default: False)
2546
2552
2547 ``archivesubrepos``
2553 ``archivesubrepos``
2548 Whether to recurse into subrepositories when archiving.
2554 Whether to recurse into subrepositories when archiving.
2549 (default: False)
2555 (default: False)
2550
2556
2551 ``baseurl``
2557 ``baseurl``
2552 Base URL to use when publishing URLs in other locations, so
2558 Base URL to use when publishing URLs in other locations, so
2553 third-party tools like email notification hooks can construct
2559 third-party tools like email notification hooks can construct
2554 URLs. Example: ``http://hgserver/repos/``.
2560 URLs. Example: ``http://hgserver/repos/``.
2555
2561
2556 ``cacerts``
2562 ``cacerts``
2557 Path to file containing a list of PEM encoded certificate
2563 Path to file containing a list of PEM encoded certificate
2558 authority certificates. Environment variables and ``~user``
2564 authority certificates. Environment variables and ``~user``
2559 constructs are expanded in the filename. If specified on the
2565 constructs are expanded in the filename. If specified on the
2560 client, then it will verify the identity of remote HTTPS servers
2566 client, then it will verify the identity of remote HTTPS servers
2561 with these certificates.
2567 with these certificates.
2562
2568
2563 To disable SSL verification temporarily, specify ``--insecure`` from
2569 To disable SSL verification temporarily, specify ``--insecure`` from
2564 command line.
2570 command line.
2565
2571
2566 You can use OpenSSL's CA certificate file if your platform has
2572 You can use OpenSSL's CA certificate file if your platform has
2567 one. On most Linux systems this will be
2573 one. On most Linux systems this will be
2568 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2574 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2569 generate this file manually. The form must be as follows::
2575 generate this file manually. The form must be as follows::
2570
2576
2571 -----BEGIN CERTIFICATE-----
2577 -----BEGIN CERTIFICATE-----
2572 ... (certificate in base64 PEM encoding) ...
2578 ... (certificate in base64 PEM encoding) ...
2573 -----END CERTIFICATE-----
2579 -----END CERTIFICATE-----
2574 -----BEGIN CERTIFICATE-----
2580 -----BEGIN CERTIFICATE-----
2575 ... (certificate in base64 PEM encoding) ...
2581 ... (certificate in base64 PEM encoding) ...
2576 -----END CERTIFICATE-----
2582 -----END CERTIFICATE-----
2577
2583
2578 ``cache``
2584 ``cache``
2579 Whether to support caching in hgweb. (default: True)
2585 Whether to support caching in hgweb. (default: True)
2580
2586
2581 ``certificate``
2587 ``certificate``
2582 Certificate to use when running :hg:`serve`.
2588 Certificate to use when running :hg:`serve`.
2583
2589
2584 ``collapse``
2590 ``collapse``
2585 With ``descend`` enabled, repositories in subdirectories are shown at
2591 With ``descend`` enabled, repositories in subdirectories are shown at
2586 a single level alongside repositories in the current path. With
2592 a single level alongside repositories in the current path. With
2587 ``collapse`` also enabled, repositories residing at a deeper level than
2593 ``collapse`` also enabled, repositories residing at a deeper level than
2588 the current path are grouped behind navigable directory entries that
2594 the current path are grouped behind navigable directory entries that
2589 lead to the locations of these repositories. In effect, this setting
2595 lead to the locations of these repositories. In effect, this setting
2590 collapses each collection of repositories found within a subdirectory
2596 collapses each collection of repositories found within a subdirectory
2591 into a single entry for that subdirectory. (default: False)
2597 into a single entry for that subdirectory. (default: False)
2592
2598
2593 ``comparisoncontext``
2599 ``comparisoncontext``
2594 Number of lines of context to show in side-by-side file comparison. If
2600 Number of lines of context to show in side-by-side file comparison. If
2595 negative or the value ``full``, whole files are shown. (default: 5)
2601 negative or the value ``full``, whole files are shown. (default: 5)
2596
2602
2597 This setting can be overridden by a ``context`` request parameter to the
2603 This setting can be overridden by a ``context`` request parameter to the
2598 ``comparison`` command, taking the same values.
2604 ``comparison`` command, taking the same values.
2599
2605
2600 ``contact``
2606 ``contact``
2601 Name or email address of the person in charge of the repository.
2607 Name or email address of the person in charge of the repository.
2602 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2608 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2603
2609
2604 ``csp``
2610 ``csp``
2605 Send a ``Content-Security-Policy`` HTTP header with this value.
2611 Send a ``Content-Security-Policy`` HTTP header with this value.
2606
2612
2607 The value may contain a special string ``%nonce%``, which will be replaced
2613 The value may contain a special string ``%nonce%``, which will be replaced
2608 by a randomly-generated one-time use value. If the value contains
2614 by a randomly-generated one-time use value. If the value contains
2609 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2615 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2610 one-time property of the nonce. This nonce will also be inserted into
2616 one-time property of the nonce. This nonce will also be inserted into
2611 ``<script>`` elements containing inline JavaScript.
2617 ``<script>`` elements containing inline JavaScript.
2612
2618
2613 Note: lots of HTML content sent by the server is derived from repository
2619 Note: lots of HTML content sent by the server is derived from repository
2614 data. Please consider the potential for malicious repository data to
2620 data. Please consider the potential for malicious repository data to
2615 "inject" itself into generated HTML content as part of your security
2621 "inject" itself into generated HTML content as part of your security
2616 threat model.
2622 threat model.
2617
2623
2618 ``deny_push``
2624 ``deny_push``
2619 Whether to deny pushing to the repository. If empty or not set,
2625 Whether to deny pushing to the repository. If empty or not set,
2620 push is not denied. If the special value ``*``, all remote users are
2626 push is not denied. If the special value ``*``, all remote users are
2621 denied push. Otherwise, unauthenticated users are all denied, and
2627 denied push. Otherwise, unauthenticated users are all denied, and
2622 any authenticated user name present in this list is also denied. The
2628 any authenticated user name present in this list is also denied. The
2623 contents of the deny_push list are examined before the allow-push list.
2629 contents of the deny_push list are examined before the allow-push list.
2624
2630
2625 ``deny_read``
2631 ``deny_read``
2626 Whether to deny reading/viewing of the repository. If this list is
2632 Whether to deny reading/viewing of the repository. If this list is
2627 not empty, unauthenticated users are all denied, and any
2633 not empty, unauthenticated users are all denied, and any
2628 authenticated user name present in this list is also denied access to
2634 authenticated user name present in this list is also denied access to
2629 the repository. If set to the special value ``*``, all remote users
2635 the repository. If set to the special value ``*``, all remote users
2630 are denied access (rarely needed ;). If deny_read is empty or not set,
2636 are denied access (rarely needed ;). If deny_read is empty or not set,
2631 the determination of repository access depends on the presence and
2637 the determination of repository access depends on the presence and
2632 content of the allow_read list (see description). If both
2638 content of the allow_read list (see description). If both
2633 deny_read and allow_read are empty or not set, then access is
2639 deny_read and allow_read are empty or not set, then access is
2634 permitted to all users by default. If the repository is being
2640 permitted to all users by default. If the repository is being
2635 served via hgwebdir, denied users will not be able to see it in
2641 served via hgwebdir, denied users will not be able to see it in
2636 the list of repositories. The contents of the deny_read list have
2642 the list of repositories. The contents of the deny_read list have
2637 priority over (are examined before) the contents of the allow_read
2643 priority over (are examined before) the contents of the allow_read
2638 list.
2644 list.
2639
2645
2640 ``descend``
2646 ``descend``
2641 hgwebdir indexes will not descend into subdirectories. Only repositories
2647 hgwebdir indexes will not descend into subdirectories. Only repositories
2642 directly in the current path will be shown (other repositories are still
2648 directly in the current path will be shown (other repositories are still
2643 available from the index corresponding to their containing path).
2649 available from the index corresponding to their containing path).
2644
2650
2645 ``description``
2651 ``description``
2646 Textual description of the repository's purpose or contents.
2652 Textual description of the repository's purpose or contents.
2647 (default: "unknown")
2653 (default: "unknown")
2648
2654
2649 ``encoding``
2655 ``encoding``
2650 Character encoding name. (default: the current locale charset)
2656 Character encoding name. (default: the current locale charset)
2651 Example: "UTF-8".
2657 Example: "UTF-8".
2652
2658
2653 ``errorlog``
2659 ``errorlog``
2654 Where to output the error log. (default: stderr)
2660 Where to output the error log. (default: stderr)
2655
2661
2656 ``guessmime``
2662 ``guessmime``
2657 Control MIME types for raw download of file content.
2663 Control MIME types for raw download of file content.
2658 Set to True to let hgweb guess the content type from the file
2664 Set to True to let hgweb guess the content type from the file
2659 extension. This will serve HTML files as ``text/html`` and might
2665 extension. This will serve HTML files as ``text/html`` and might
2660 allow cross-site scripting attacks when serving untrusted
2666 allow cross-site scripting attacks when serving untrusted
2661 repositories. (default: False)
2667 repositories. (default: False)
2662
2668
2663 ``hidden``
2669 ``hidden``
2664 Whether to hide the repository in the hgwebdir index.
2670 Whether to hide the repository in the hgwebdir index.
2665 (default: False)
2671 (default: False)
2666
2672
2667 ``ipv6``
2673 ``ipv6``
2668 Whether to use IPv6. (default: False)
2674 Whether to use IPv6. (default: False)
2669
2675
2670 ``labels``
2676 ``labels``
2671 List of string *labels* associated with the repository.
2677 List of string *labels* associated with the repository.
2672
2678
2673 Labels are exposed as a template keyword and can be used to customize
2679 Labels are exposed as a template keyword and can be used to customize
2674 output. e.g. the ``index`` template can group or filter repositories
2680 output. e.g. the ``index`` template can group or filter repositories
2675 by labels and the ``summary`` template can display additional content
2681 by labels and the ``summary`` template can display additional content
2676 if a specific label is present.
2682 if a specific label is present.
2677
2683
2678 ``logoimg``
2684 ``logoimg``
2679 File name of the logo image that some templates display on each page.
2685 File name of the logo image that some templates display on each page.
2680 The file name is relative to ``staticurl``. That is, the full path to
2686 The file name is relative to ``staticurl``. That is, the full path to
2681 the logo image is "staticurl/logoimg".
2687 the logo image is "staticurl/logoimg".
2682 If unset, ``hglogo.png`` will be used.
2688 If unset, ``hglogo.png`` will be used.
2683
2689
2684 ``logourl``
2690 ``logourl``
2685 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2691 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2686 will be used.
2692 will be used.
2687
2693
2688 ``maxchanges``
2694 ``maxchanges``
2689 Maximum number of changes to list on the changelog. (default: 10)
2695 Maximum number of changes to list on the changelog. (default: 10)
2690
2696
2691 ``maxfiles``
2697 ``maxfiles``
2692 Maximum number of files to list per changeset. (default: 10)
2698 Maximum number of files to list per changeset. (default: 10)
2693
2699
2694 ``maxshortchanges``
2700 ``maxshortchanges``
2695 Maximum number of changes to list on the shortlog, graph or filelog
2701 Maximum number of changes to list on the shortlog, graph or filelog
2696 pages. (default: 60)
2702 pages. (default: 60)
2697
2703
2698 ``name``
2704 ``name``
2699 Repository name to use in the web interface.
2705 Repository name to use in the web interface.
2700 (default: current working directory)
2706 (default: current working directory)
2701
2707
2702 ``port``
2708 ``port``
2703 Port to listen on. (default: 8000)
2709 Port to listen on. (default: 8000)
2704
2710
2705 ``prefix``
2711 ``prefix``
2706 Prefix path to serve from. (default: '' (server root))
2712 Prefix path to serve from. (default: '' (server root))
2707
2713
2708 ``push_ssl``
2714 ``push_ssl``
2709 Whether to require that inbound pushes be transported over SSL to
2715 Whether to require that inbound pushes be transported over SSL to
2710 prevent password sniffing. (default: True)
2716 prevent password sniffing. (default: True)
2711
2717
2712 ``refreshinterval``
2718 ``refreshinterval``
2713 How frequently directory listings re-scan the filesystem for new
2719 How frequently directory listings re-scan the filesystem for new
2714 repositories, in seconds. This is relevant when wildcards are used
2720 repositories, in seconds. This is relevant when wildcards are used
2715 to define paths. Depending on how much filesystem traversal is
2721 to define paths. Depending on how much filesystem traversal is
2716 required, refreshing may negatively impact performance.
2722 required, refreshing may negatively impact performance.
2717
2723
2718 Values less than or equal to 0 always refresh.
2724 Values less than or equal to 0 always refresh.
2719 (default: 20)
2725 (default: 20)
2720
2726
2721 ``server-header``
2727 ``server-header``
2722 Value for HTTP ``Server`` response header.
2728 Value for HTTP ``Server`` response header.
2723
2729
2724 ``static``
2730 ``static``
2725 Directory where static files are served from.
2731 Directory where static files are served from.
2726
2732
2727 ``staticurl``
2733 ``staticurl``
2728 Base URL to use for static files. If unset, static files (e.g. the
2734 Base URL to use for static files. If unset, static files (e.g. the
2729 hgicon.png favicon) will be served by the CGI script itself. Use
2735 hgicon.png favicon) will be served by the CGI script itself. Use
2730 this setting to serve them directly with the HTTP server.
2736 this setting to serve them directly with the HTTP server.
2731 Example: ``http://hgserver/static/``.
2737 Example: ``http://hgserver/static/``.
2732
2738
2733 ``stripes``
2739 ``stripes``
2734 How many lines a "zebra stripe" should span in multi-line output.
2740 How many lines a "zebra stripe" should span in multi-line output.
2735 Set to 0 to disable. (default: 1)
2741 Set to 0 to disable. (default: 1)
2736
2742
2737 ``style``
2743 ``style``
2738 Which template map style to use. The available options are the names of
2744 Which template map style to use. The available options are the names of
2739 subdirectories in the HTML templates path. (default: ``paper``)
2745 subdirectories in the HTML templates path. (default: ``paper``)
2740 Example: ``monoblue``.
2746 Example: ``monoblue``.
2741
2747
2742 ``templates``
2748 ``templates``
2743 Where to find the HTML templates. The default path to the HTML templates
2749 Where to find the HTML templates. The default path to the HTML templates
2744 can be obtained from ``hg debuginstall``.
2750 can be obtained from ``hg debuginstall``.
2745
2751
2746 ``websub``
2752 ``websub``
2747 ----------
2753 ----------
2748
2754
2749 Web substitution filter definition. You can use this section to
2755 Web substitution filter definition. You can use this section to
2750 define a set of regular expression substitution patterns which
2756 define a set of regular expression substitution patterns which
2751 let you automatically modify the hgweb server output.
2757 let you automatically modify the hgweb server output.
2752
2758
2753 The default hgweb templates only apply these substitution patterns
2759 The default hgweb templates only apply these substitution patterns
2754 on the revision description fields. You can apply them anywhere
2760 on the revision description fields. You can apply them anywhere
2755 you want when you create your own templates by adding calls to the
2761 you want when you create your own templates by adding calls to the
2756 "websub" filter (usually after calling the "escape" filter).
2762 "websub" filter (usually after calling the "escape" filter).
2757
2763
2758 This can be used, for example, to convert issue references to links
2764 This can be used, for example, to convert issue references to links
2759 to your issue tracker, or to convert "markdown-like" syntax into
2765 to your issue tracker, or to convert "markdown-like" syntax into
2760 HTML (see the examples below).
2766 HTML (see the examples below).
2761
2767
2762 Each entry in this section names a substitution filter.
2768 Each entry in this section names a substitution filter.
2763 The value of each entry defines the substitution expression itself.
2769 The value of each entry defines the substitution expression itself.
2764 The websub expressions follow the old interhg extension syntax,
2770 The websub expressions follow the old interhg extension syntax,
2765 which in turn imitates the Unix sed replacement syntax::
2771 which in turn imitates the Unix sed replacement syntax::
2766
2772
2767 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2773 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2768
2774
2769 You can use any separator other than "/". The final "i" is optional
2775 You can use any separator other than "/". The final "i" is optional
2770 and indicates that the search must be case insensitive.
2776 and indicates that the search must be case insensitive.
2771
2777
2772 Examples::
2778 Examples::
2773
2779
2774 [websub]
2780 [websub]
2775 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2781 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2776 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2782 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2777 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2783 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2778
2784
2779 ``worker``
2785 ``worker``
2780 ----------
2786 ----------
2781
2787
2782 Parallel master/worker configuration. We currently perform working
2788 Parallel master/worker configuration. We currently perform working
2783 directory updates in parallel on Unix-like systems, which greatly
2789 directory updates in parallel on Unix-like systems, which greatly
2784 helps performance.
2790 helps performance.
2785
2791
2786 ``enabled``
2792 ``enabled``
2787 Whether to enable workers code to be used.
2793 Whether to enable workers code to be used.
2788 (default: true)
2794 (default: true)
2789
2795
2790 ``numcpus``
2796 ``numcpus``
2791 Number of CPUs to use for parallel operations. A zero or
2797 Number of CPUs to use for parallel operations. A zero or
2792 negative value is treated as ``use the default``.
2798 negative value is treated as ``use the default``.
2793 (default: 4 or the number of CPUs on the system, whichever is larger)
2799 (default: 4 or the number of CPUs on the system, whichever is larger)
2794
2800
2795 ``backgroundclose``
2801 ``backgroundclose``
2796 Whether to enable closing file handles on background threads during certain
2802 Whether to enable closing file handles on background threads during certain
2797 operations. Some platforms aren't very efficient at closing file
2803 operations. Some platforms aren't very efficient at closing file
2798 handles that have been written or appended to. By performing file closing
2804 handles that have been written or appended to. By performing file closing
2799 on background threads, file write rate can increase substantially.
2805 on background threads, file write rate can increase substantially.
2800 (default: true on Windows, false elsewhere)
2806 (default: true on Windows, false elsewhere)
2801
2807
2802 ``backgroundcloseminfilecount``
2808 ``backgroundcloseminfilecount``
2803 Minimum number of files required to trigger background file closing.
2809 Minimum number of files required to trigger background file closing.
2804 Operations not writing this many files won't start background close
2810 Operations not writing this many files won't start background close
2805 threads.
2811 threads.
2806 (default: 2048)
2812 (default: 2048)
2807
2813
2808 ``backgroundclosemaxqueue``
2814 ``backgroundclosemaxqueue``
2809 The maximum number of opened file handles waiting to be closed in the
2815 The maximum number of opened file handles waiting to be closed in the
2810 background. This option only has an effect if ``backgroundclose`` is
2816 background. This option only has an effect if ``backgroundclose`` is
2811 enabled.
2817 enabled.
2812 (default: 384)
2818 (default: 384)
2813
2819
2814 ``backgroundclosethreadcount``
2820 ``backgroundclosethreadcount``
2815 Number of threads to process background file closes. Only relevant if
2821 Number of threads to process background file closes. Only relevant if
2816 ``backgroundclose`` is enabled.
2822 ``backgroundclose`` is enabled.
2817 (default: 4)
2823 (default: 4)
@@ -1,671 +1,671
1 # wireprotov1server.py - Wire protocol version 1 server functionality
1 # wireprotov1server.py - Wire protocol version 1 server functionality
2 #
2 #
3 # Copyright 2005-2010 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2010 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import binascii
10 import binascii
11 import os
11 import os
12
12
13 from .i18n import _
13 from .i18n import _
14 from .node import (
14 from .node import (
15 hex,
15 hex,
16 nullid,
16 nullid,
17 )
17 )
18
18
19 from . import (
19 from . import (
20 bundle2,
20 bundle2,
21 changegroup as changegroupmod,
21 changegroup as changegroupmod,
22 discovery,
22 discovery,
23 encoding,
23 encoding,
24 error,
24 error,
25 exchange,
25 exchange,
26 pushkey as pushkeymod,
26 pushkey as pushkeymod,
27 pycompat,
27 pycompat,
28 streamclone,
28 streamclone,
29 util,
29 util,
30 wireprototypes,
30 wireprototypes,
31 )
31 )
32
32
33 from .utils import (
33 from .utils import (
34 procutil,
34 procutil,
35 stringutil,
35 stringutil,
36 )
36 )
37
37
38 urlerr = util.urlerr
38 urlerr = util.urlerr
39 urlreq = util.urlreq
39 urlreq = util.urlreq
40
40
41 bundle2requiredmain = _('incompatible Mercurial client; bundle2 required')
41 bundle2requiredmain = _('incompatible Mercurial client; bundle2 required')
42 bundle2requiredhint = _('see https://www.mercurial-scm.org/wiki/'
42 bundle2requiredhint = _('see https://www.mercurial-scm.org/wiki/'
43 'IncompatibleClient')
43 'IncompatibleClient')
44 bundle2required = '%s\n(%s)\n' % (bundle2requiredmain, bundle2requiredhint)
44 bundle2required = '%s\n(%s)\n' % (bundle2requiredmain, bundle2requiredhint)
45
45
46 def clientcompressionsupport(proto):
46 def clientcompressionsupport(proto):
47 """Returns a list of compression methods supported by the client.
47 """Returns a list of compression methods supported by the client.
48
48
49 Returns a list of the compression methods supported by the client
49 Returns a list of the compression methods supported by the client
50 according to the protocol capabilities. If no such capability has
50 according to the protocol capabilities. If no such capability has
51 been announced, fallback to the default of zlib and uncompressed.
51 been announced, fallback to the default of zlib and uncompressed.
52 """
52 """
53 for cap in proto.getprotocaps():
53 for cap in proto.getprotocaps():
54 if cap.startswith('comp='):
54 if cap.startswith('comp='):
55 return cap[5:].split(',')
55 return cap[5:].split(',')
56 return ['zlib', 'none']
56 return ['zlib', 'none']
57
57
58 # wire protocol command can either return a string or one of these classes.
58 # wire protocol command can either return a string or one of these classes.
59
59
60 def getdispatchrepo(repo, proto, command):
60 def getdispatchrepo(repo, proto, command):
61 """Obtain the repo used for processing wire protocol commands.
61 """Obtain the repo used for processing wire protocol commands.
62
62
63 The intent of this function is to serve as a monkeypatch point for
63 The intent of this function is to serve as a monkeypatch point for
64 extensions that need commands to operate on different repo views under
64 extensions that need commands to operate on different repo views under
65 specialized circumstances.
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 def dispatch(repo, proto, command):
70 def dispatch(repo, proto, command):
70 repo = getdispatchrepo(repo, proto, command)
71 repo = getdispatchrepo(repo, proto, command)
71
72
72 func, spec = commands[command]
73 func, spec = commands[command]
73 args = proto.getargs(spec)
74 args = proto.getargs(spec)
74
75
75 return func(repo, proto, *args)
76 return func(repo, proto, *args)
76
77
77 def options(cmd, keys, others):
78 def options(cmd, keys, others):
78 opts = {}
79 opts = {}
79 for k in keys:
80 for k in keys:
80 if k in others:
81 if k in others:
81 opts[k] = others[k]
82 opts[k] = others[k]
82 del others[k]
83 del others[k]
83 if others:
84 if others:
84 procutil.stderr.write("warning: %s ignored unexpected arguments %s\n"
85 procutil.stderr.write("warning: %s ignored unexpected arguments %s\n"
85 % (cmd, ",".join(others)))
86 % (cmd, ",".join(others)))
86 return opts
87 return opts
87
88
88 def bundle1allowed(repo, action):
89 def bundle1allowed(repo, action):
89 """Whether a bundle1 operation is allowed from the server.
90 """Whether a bundle1 operation is allowed from the server.
90
91
91 Priority is:
92 Priority is:
92
93
93 1. server.bundle1gd.<action> (if generaldelta active)
94 1. server.bundle1gd.<action> (if generaldelta active)
94 2. server.bundle1.<action>
95 2. server.bundle1.<action>
95 3. server.bundle1gd (if generaldelta active)
96 3. server.bundle1gd (if generaldelta active)
96 4. server.bundle1
97 4. server.bundle1
97 """
98 """
98 ui = repo.ui
99 ui = repo.ui
99 gd = 'generaldelta' in repo.requirements
100 gd = 'generaldelta' in repo.requirements
100
101
101 if gd:
102 if gd:
102 v = ui.configbool('server', 'bundle1gd.%s' % action)
103 v = ui.configbool('server', 'bundle1gd.%s' % action)
103 if v is not None:
104 if v is not None:
104 return v
105 return v
105
106
106 v = ui.configbool('server', 'bundle1.%s' % action)
107 v = ui.configbool('server', 'bundle1.%s' % action)
107 if v is not None:
108 if v is not None:
108 return v
109 return v
109
110
110 if gd:
111 if gd:
111 v = ui.configbool('server', 'bundle1gd')
112 v = ui.configbool('server', 'bundle1gd')
112 if v is not None:
113 if v is not None:
113 return v
114 return v
114
115
115 return ui.configbool('server', 'bundle1')
116 return ui.configbool('server', 'bundle1')
116
117
117 commands = wireprototypes.commanddict()
118 commands = wireprototypes.commanddict()
118
119
119 def wireprotocommand(name, args=None, permission='push'):
120 def wireprotocommand(name, args=None, permission='push'):
120 """Decorator to declare a wire protocol command.
121 """Decorator to declare a wire protocol command.
121
122
122 ``name`` is the name of the wire protocol command being provided.
123 ``name`` is the name of the wire protocol command being provided.
123
124
124 ``args`` defines the named arguments accepted by the command. It is
125 ``args`` defines the named arguments accepted by the command. It is
125 a space-delimited list of argument names. ``*`` denotes a special value
126 a space-delimited list of argument names. ``*`` denotes a special value
126 that says to accept all named arguments.
127 that says to accept all named arguments.
127
128
128 ``permission`` defines the permission type needed to run this command.
129 ``permission`` defines the permission type needed to run this command.
129 Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
130 Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
130 respectively. Default is to assume command requires ``push`` permissions
131 respectively. Default is to assume command requires ``push`` permissions
131 because otherwise commands not declaring their permissions could modify
132 because otherwise commands not declaring their permissions could modify
132 a repository that is supposed to be read-only.
133 a repository that is supposed to be read-only.
133 """
134 """
134 transports = {k for k, v in wireprototypes.TRANSPORTS.items()
135 transports = {k for k, v in wireprototypes.TRANSPORTS.items()
135 if v['version'] == 1}
136 if v['version'] == 1}
136
137
137 # Because SSHv2 is a mirror of SSHv1, we allow "batch" commands through to
138 # Because SSHv2 is a mirror of SSHv1, we allow "batch" commands through to
138 # SSHv2.
139 # SSHv2.
139 # TODO undo this hack when SSH is using the unified frame protocol.
140 # TODO undo this hack when SSH is using the unified frame protocol.
140 if name == b'batch':
141 if name == b'batch':
141 transports.add(wireprototypes.SSHV2)
142 transports.add(wireprototypes.SSHV2)
142
143
143 if permission not in ('push', 'pull'):
144 if permission not in ('push', 'pull'):
144 raise error.ProgrammingError('invalid wire protocol permission; '
145 raise error.ProgrammingError('invalid wire protocol permission; '
145 'got %s; expected "push" or "pull"' %
146 'got %s; expected "push" or "pull"' %
146 permission)
147 permission)
147
148
148 if args is None:
149 if args is None:
149 args = ''
150 args = ''
150
151
151 if not isinstance(args, bytes):
152 if not isinstance(args, bytes):
152 raise error.ProgrammingError('arguments for version 1 commands '
153 raise error.ProgrammingError('arguments for version 1 commands '
153 'must be declared as bytes')
154 'must be declared as bytes')
154
155
155 def register(func):
156 def register(func):
156 if name in commands:
157 if name in commands:
157 raise error.ProgrammingError('%s command already registered '
158 raise error.ProgrammingError('%s command already registered '
158 'for version 1' % name)
159 'for version 1' % name)
159 commands[name] = wireprototypes.commandentry(
160 commands[name] = wireprototypes.commandentry(
160 func, args=args, transports=transports, permission=permission)
161 func, args=args, transports=transports, permission=permission)
161
162
162 return func
163 return func
163 return register
164 return register
164
165
165 # TODO define a more appropriate permissions type to use for this.
166 # TODO define a more appropriate permissions type to use for this.
166 @wireprotocommand('batch', 'cmds *', permission='pull')
167 @wireprotocommand('batch', 'cmds *', permission='pull')
167 def batch(repo, proto, cmds, others):
168 def batch(repo, proto, cmds, others):
168 unescapearg = wireprototypes.unescapebatcharg
169 unescapearg = wireprototypes.unescapebatcharg
169 repo = repo.filtered("served")
170 res = []
170 res = []
171 for pair in cmds.split(';'):
171 for pair in cmds.split(';'):
172 op, args = pair.split(' ', 1)
172 op, args = pair.split(' ', 1)
173 vals = {}
173 vals = {}
174 for a in args.split(','):
174 for a in args.split(','):
175 if a:
175 if a:
176 n, v = a.split('=')
176 n, v = a.split('=')
177 vals[unescapearg(n)] = unescapearg(v)
177 vals[unescapearg(n)] = unescapearg(v)
178 func, spec = commands[op]
178 func, spec = commands[op]
179
179
180 # Validate that client has permissions to perform this command.
180 # Validate that client has permissions to perform this command.
181 perm = commands[op].permission
181 perm = commands[op].permission
182 assert perm in ('push', 'pull')
182 assert perm in ('push', 'pull')
183 proto.checkperm(perm)
183 proto.checkperm(perm)
184
184
185 if spec:
185 if spec:
186 keys = spec.split()
186 keys = spec.split()
187 data = {}
187 data = {}
188 for k in keys:
188 for k in keys:
189 if k == '*':
189 if k == '*':
190 star = {}
190 star = {}
191 for key in vals.keys():
191 for key in vals.keys():
192 if key not in keys:
192 if key not in keys:
193 star[key] = vals[key]
193 star[key] = vals[key]
194 data['*'] = star
194 data['*'] = star
195 else:
195 else:
196 data[k] = vals[k]
196 data[k] = vals[k]
197 result = func(repo, proto, *[data[k] for k in keys])
197 result = func(repo, proto, *[data[k] for k in keys])
198 else:
198 else:
199 result = func(repo, proto)
199 result = func(repo, proto)
200 if isinstance(result, wireprototypes.ooberror):
200 if isinstance(result, wireprototypes.ooberror):
201 return result
201 return result
202
202
203 # For now, all batchable commands must return bytesresponse or
203 # For now, all batchable commands must return bytesresponse or
204 # raw bytes (for backwards compatibility).
204 # raw bytes (for backwards compatibility).
205 assert isinstance(result, (wireprototypes.bytesresponse, bytes))
205 assert isinstance(result, (wireprototypes.bytesresponse, bytes))
206 if isinstance(result, wireprototypes.bytesresponse):
206 if isinstance(result, wireprototypes.bytesresponse):
207 result = result.data
207 result = result.data
208 res.append(wireprototypes.escapebatcharg(result))
208 res.append(wireprototypes.escapebatcharg(result))
209
209
210 return wireprototypes.bytesresponse(';'.join(res))
210 return wireprototypes.bytesresponse(';'.join(res))
211
211
212 @wireprotocommand('between', 'pairs', permission='pull')
212 @wireprotocommand('between', 'pairs', permission='pull')
213 def between(repo, proto, pairs):
213 def between(repo, proto, pairs):
214 pairs = [wireprototypes.decodelist(p, '-') for p in pairs.split(" ")]
214 pairs = [wireprototypes.decodelist(p, '-') for p in pairs.split(" ")]
215 r = []
215 r = []
216 for b in repo.between(pairs):
216 for b in repo.between(pairs):
217 r.append(wireprototypes.encodelist(b) + "\n")
217 r.append(wireprototypes.encodelist(b) + "\n")
218
218
219 return wireprototypes.bytesresponse(''.join(r))
219 return wireprototypes.bytesresponse(''.join(r))
220
220
221 @wireprotocommand('branchmap', permission='pull')
221 @wireprotocommand('branchmap', permission='pull')
222 def branchmap(repo, proto):
222 def branchmap(repo, proto):
223 branchmap = repo.branchmap()
223 branchmap = repo.branchmap()
224 heads = []
224 heads = []
225 for branch, nodes in branchmap.iteritems():
225 for branch, nodes in branchmap.iteritems():
226 branchname = urlreq.quote(encoding.fromlocal(branch))
226 branchname = urlreq.quote(encoding.fromlocal(branch))
227 branchnodes = wireprototypes.encodelist(nodes)
227 branchnodes = wireprototypes.encodelist(nodes)
228 heads.append('%s %s' % (branchname, branchnodes))
228 heads.append('%s %s' % (branchname, branchnodes))
229
229
230 return wireprototypes.bytesresponse('\n'.join(heads))
230 return wireprototypes.bytesresponse('\n'.join(heads))
231
231
232 @wireprotocommand('branches', 'nodes', permission='pull')
232 @wireprotocommand('branches', 'nodes', permission='pull')
233 def branches(repo, proto, nodes):
233 def branches(repo, proto, nodes):
234 nodes = wireprototypes.decodelist(nodes)
234 nodes = wireprototypes.decodelist(nodes)
235 r = []
235 r = []
236 for b in repo.branches(nodes):
236 for b in repo.branches(nodes):
237 r.append(wireprototypes.encodelist(b) + "\n")
237 r.append(wireprototypes.encodelist(b) + "\n")
238
238
239 return wireprototypes.bytesresponse(''.join(r))
239 return wireprototypes.bytesresponse(''.join(r))
240
240
241 @wireprotocommand('clonebundles', '', permission='pull')
241 @wireprotocommand('clonebundles', '', permission='pull')
242 def clonebundles(repo, proto):
242 def clonebundles(repo, proto):
243 """Server command for returning info for available bundles to seed clones.
243 """Server command for returning info for available bundles to seed clones.
244
244
245 Clients will parse this response and determine what bundle to fetch.
245 Clients will parse this response and determine what bundle to fetch.
246
246
247 Extensions may wrap this command to filter or dynamically emit data
247 Extensions may wrap this command to filter or dynamically emit data
248 depending on the request. e.g. you could advertise URLs for the closest
248 depending on the request. e.g. you could advertise URLs for the closest
249 data center given the client's IP address.
249 data center given the client's IP address.
250 """
250 """
251 return wireprototypes.bytesresponse(
251 return wireprototypes.bytesresponse(
252 repo.vfs.tryread('clonebundles.manifest'))
252 repo.vfs.tryread('clonebundles.manifest'))
253
253
254 wireprotocaps = ['lookup', 'branchmap', 'pushkey',
254 wireprotocaps = ['lookup', 'branchmap', 'pushkey',
255 'known', 'getbundle', 'unbundlehash']
255 'known', 'getbundle', 'unbundlehash']
256
256
257 def _capabilities(repo, proto):
257 def _capabilities(repo, proto):
258 """return a list of capabilities for a repo
258 """return a list of capabilities for a repo
259
259
260 This function exists to allow extensions to easily wrap capabilities
260 This function exists to allow extensions to easily wrap capabilities
261 computation
261 computation
262
262
263 - returns a lists: easy to alter
263 - returns a lists: easy to alter
264 - change done here will be propagated to both `capabilities` and `hello`
264 - change done here will be propagated to both `capabilities` and `hello`
265 command without any other action needed.
265 command without any other action needed.
266 """
266 """
267 # copy to prevent modification of the global list
267 # copy to prevent modification of the global list
268 caps = list(wireprotocaps)
268 caps = list(wireprotocaps)
269
269
270 # Command of same name as capability isn't exposed to version 1 of
270 # Command of same name as capability isn't exposed to version 1 of
271 # transports. So conditionally add it.
271 # transports. So conditionally add it.
272 if commands.commandavailable('changegroupsubset', proto):
272 if commands.commandavailable('changegroupsubset', proto):
273 caps.append('changegroupsubset')
273 caps.append('changegroupsubset')
274
274
275 if streamclone.allowservergeneration(repo):
275 if streamclone.allowservergeneration(repo):
276 if repo.ui.configbool('server', 'preferuncompressed'):
276 if repo.ui.configbool('server', 'preferuncompressed'):
277 caps.append('stream-preferred')
277 caps.append('stream-preferred')
278 requiredformats = repo.requirements & repo.supportedformats
278 requiredformats = repo.requirements & repo.supportedformats
279 # if our local revlogs are just revlogv1, add 'stream' cap
279 # if our local revlogs are just revlogv1, add 'stream' cap
280 if not requiredformats - {'revlogv1'}:
280 if not requiredformats - {'revlogv1'}:
281 caps.append('stream')
281 caps.append('stream')
282 # otherwise, add 'streamreqs' detailing our local revlog format
282 # otherwise, add 'streamreqs' detailing our local revlog format
283 else:
283 else:
284 caps.append('streamreqs=%s' % ','.join(sorted(requiredformats)))
284 caps.append('streamreqs=%s' % ','.join(sorted(requiredformats)))
285 if repo.ui.configbool('experimental', 'bundle2-advertise'):
285 if repo.ui.configbool('experimental', 'bundle2-advertise'):
286 capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo, role='server'))
286 capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo, role='server'))
287 caps.append('bundle2=' + urlreq.quote(capsblob))
287 caps.append('bundle2=' + urlreq.quote(capsblob))
288 caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority))
288 caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority))
289
289
290 if repo.ui.configbool('experimental', 'narrow'):
290 if repo.ui.configbool('experimental', 'narrow'):
291 caps.append(wireprototypes.NARROWCAP)
291 caps.append(wireprototypes.NARROWCAP)
292 if repo.ui.configbool('experimental', 'narrowservebrokenellipses'):
292 if repo.ui.configbool('experimental', 'narrowservebrokenellipses'):
293 caps.append(wireprototypes.ELLIPSESCAP)
293 caps.append(wireprototypes.ELLIPSESCAP)
294
294
295 return proto.addcapabilities(repo, caps)
295 return proto.addcapabilities(repo, caps)
296
296
297 # If you are writing an extension and consider wrapping this function. Wrap
297 # If you are writing an extension and consider wrapping this function. Wrap
298 # `_capabilities` instead.
298 # `_capabilities` instead.
299 @wireprotocommand('capabilities', permission='pull')
299 @wireprotocommand('capabilities', permission='pull')
300 def capabilities(repo, proto):
300 def capabilities(repo, proto):
301 caps = _capabilities(repo, proto)
301 caps = _capabilities(repo, proto)
302 return wireprototypes.bytesresponse(' '.join(sorted(caps)))
302 return wireprototypes.bytesresponse(' '.join(sorted(caps)))
303
303
304 @wireprotocommand('changegroup', 'roots', permission='pull')
304 @wireprotocommand('changegroup', 'roots', permission='pull')
305 def changegroup(repo, proto, roots):
305 def changegroup(repo, proto, roots):
306 nodes = wireprototypes.decodelist(roots)
306 nodes = wireprototypes.decodelist(roots)
307 outgoing = discovery.outgoing(repo, missingroots=nodes,
307 outgoing = discovery.outgoing(repo, missingroots=nodes,
308 missingheads=repo.heads())
308 missingheads=repo.heads())
309 cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
309 cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
310 gen = iter(lambda: cg.read(32768), '')
310 gen = iter(lambda: cg.read(32768), '')
311 return wireprototypes.streamres(gen=gen)
311 return wireprototypes.streamres(gen=gen)
312
312
313 @wireprotocommand('changegroupsubset', 'bases heads',
313 @wireprotocommand('changegroupsubset', 'bases heads',
314 permission='pull')
314 permission='pull')
315 def changegroupsubset(repo, proto, bases, heads):
315 def changegroupsubset(repo, proto, bases, heads):
316 bases = wireprototypes.decodelist(bases)
316 bases = wireprototypes.decodelist(bases)
317 heads = wireprototypes.decodelist(heads)
317 heads = wireprototypes.decodelist(heads)
318 outgoing = discovery.outgoing(repo, missingroots=bases,
318 outgoing = discovery.outgoing(repo, missingroots=bases,
319 missingheads=heads)
319 missingheads=heads)
320 cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
320 cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
321 gen = iter(lambda: cg.read(32768), '')
321 gen = iter(lambda: cg.read(32768), '')
322 return wireprototypes.streamres(gen=gen)
322 return wireprototypes.streamres(gen=gen)
323
323
324 @wireprotocommand('debugwireargs', 'one two *',
324 @wireprotocommand('debugwireargs', 'one two *',
325 permission='pull')
325 permission='pull')
326 def debugwireargs(repo, proto, one, two, others):
326 def debugwireargs(repo, proto, one, two, others):
327 # only accept optional args from the known set
327 # only accept optional args from the known set
328 opts = options('debugwireargs', ['three', 'four'], others)
328 opts = options('debugwireargs', ['three', 'four'], others)
329 return wireprototypes.bytesresponse(repo.debugwireargs(
329 return wireprototypes.bytesresponse(repo.debugwireargs(
330 one, two, **pycompat.strkwargs(opts)))
330 one, two, **pycompat.strkwargs(opts)))
331
331
332 def find_pullbundle(repo, proto, opts, clheads, heads, common):
332 def find_pullbundle(repo, proto, opts, clheads, heads, common):
333 """Return a file object for the first matching pullbundle.
333 """Return a file object for the first matching pullbundle.
334
334
335 Pullbundles are specified in .hg/pullbundles.manifest similar to
335 Pullbundles are specified in .hg/pullbundles.manifest similar to
336 clonebundles.
336 clonebundles.
337 For each entry, the bundle specification is checked for compatibility:
337 For each entry, the bundle specification is checked for compatibility:
338 - Client features vs the BUNDLESPEC.
338 - Client features vs the BUNDLESPEC.
339 - Revisions shared with the clients vs base revisions of the bundle.
339 - Revisions shared with the clients vs base revisions of the bundle.
340 A bundle can be applied only if all its base revisions are known by
340 A bundle can be applied only if all its base revisions are known by
341 the client.
341 the client.
342 - At least one leaf of the bundle's DAG is missing on the client.
342 - At least one leaf of the bundle's DAG is missing on the client.
343 - Every leaf of the bundle's DAG is part of node set the client wants.
343 - Every leaf of the bundle's DAG is part of node set the client wants.
344 E.g. do not send a bundle of all changes if the client wants only
344 E.g. do not send a bundle of all changes if the client wants only
345 one specific branch of many.
345 one specific branch of many.
346 """
346 """
347 def decodehexstring(s):
347 def decodehexstring(s):
348 return set([binascii.unhexlify(h) for h in s.split(';')])
348 return set([binascii.unhexlify(h) for h in s.split(';')])
349
349
350 manifest = repo.vfs.tryread('pullbundles.manifest')
350 manifest = repo.vfs.tryread('pullbundles.manifest')
351 if not manifest:
351 if not manifest:
352 return None
352 return None
353 res = exchange.parseclonebundlesmanifest(repo, manifest)
353 res = exchange.parseclonebundlesmanifest(repo, manifest)
354 res = exchange.filterclonebundleentries(repo, res)
354 res = exchange.filterclonebundleentries(repo, res)
355 if not res:
355 if not res:
356 return None
356 return None
357 cl = repo.changelog
357 cl = repo.changelog
358 heads_anc = cl.ancestors([cl.rev(rev) for rev in heads], inclusive=True)
358 heads_anc = cl.ancestors([cl.rev(rev) for rev in heads], inclusive=True)
359 common_anc = cl.ancestors([cl.rev(rev) for rev in common], inclusive=True)
359 common_anc = cl.ancestors([cl.rev(rev) for rev in common], inclusive=True)
360 compformats = clientcompressionsupport(proto)
360 compformats = clientcompressionsupport(proto)
361 for entry in res:
361 for entry in res:
362 comp = entry.get('COMPRESSION')
362 comp = entry.get('COMPRESSION')
363 altcomp = util.compengines._bundlenames.get(comp)
363 altcomp = util.compengines._bundlenames.get(comp)
364 if comp and comp not in compformats and altcomp not in compformats:
364 if comp and comp not in compformats and altcomp not in compformats:
365 continue
365 continue
366 # No test yet for VERSION, since V2 is supported by any client
366 # No test yet for VERSION, since V2 is supported by any client
367 # that advertises partial pulls
367 # that advertises partial pulls
368 if 'heads' in entry:
368 if 'heads' in entry:
369 try:
369 try:
370 bundle_heads = decodehexstring(entry['heads'])
370 bundle_heads = decodehexstring(entry['heads'])
371 except TypeError:
371 except TypeError:
372 # Bad heads entry
372 # Bad heads entry
373 continue
373 continue
374 if bundle_heads.issubset(common):
374 if bundle_heads.issubset(common):
375 continue # Nothing new
375 continue # Nothing new
376 if all(cl.rev(rev) in common_anc for rev in bundle_heads):
376 if all(cl.rev(rev) in common_anc for rev in bundle_heads):
377 continue # Still nothing new
377 continue # Still nothing new
378 if any(cl.rev(rev) not in heads_anc and
378 if any(cl.rev(rev) not in heads_anc and
379 cl.rev(rev) not in common_anc for rev in bundle_heads):
379 cl.rev(rev) not in common_anc for rev in bundle_heads):
380 continue
380 continue
381 if 'bases' in entry:
381 if 'bases' in entry:
382 try:
382 try:
383 bundle_bases = decodehexstring(entry['bases'])
383 bundle_bases = decodehexstring(entry['bases'])
384 except TypeError:
384 except TypeError:
385 # Bad bases entry
385 # Bad bases entry
386 continue
386 continue
387 if not all(cl.rev(rev) in common_anc for rev in bundle_bases):
387 if not all(cl.rev(rev) in common_anc for rev in bundle_bases):
388 continue
388 continue
389 path = entry['URL']
389 path = entry['URL']
390 repo.ui.debug('sending pullbundle "%s"\n' % path)
390 repo.ui.debug('sending pullbundle "%s"\n' % path)
391 try:
391 try:
392 return repo.vfs.open(path)
392 return repo.vfs.open(path)
393 except IOError:
393 except IOError:
394 repo.ui.debug('pullbundle "%s" not accessible\n' % path)
394 repo.ui.debug('pullbundle "%s" not accessible\n' % path)
395 continue
395 continue
396 return None
396 return None
397
397
398 @wireprotocommand('getbundle', '*', permission='pull')
398 @wireprotocommand('getbundle', '*', permission='pull')
399 def getbundle(repo, proto, others):
399 def getbundle(repo, proto, others):
400 opts = options('getbundle', wireprototypes.GETBUNDLE_ARGUMENTS.keys(),
400 opts = options('getbundle', wireprototypes.GETBUNDLE_ARGUMENTS.keys(),
401 others)
401 others)
402 for k, v in opts.iteritems():
402 for k, v in opts.iteritems():
403 keytype = wireprototypes.GETBUNDLE_ARGUMENTS[k]
403 keytype = wireprototypes.GETBUNDLE_ARGUMENTS[k]
404 if keytype == 'nodes':
404 if keytype == 'nodes':
405 opts[k] = wireprototypes.decodelist(v)
405 opts[k] = wireprototypes.decodelist(v)
406 elif keytype == 'csv':
406 elif keytype == 'csv':
407 opts[k] = list(v.split(','))
407 opts[k] = list(v.split(','))
408 elif keytype == 'scsv':
408 elif keytype == 'scsv':
409 opts[k] = set(v.split(','))
409 opts[k] = set(v.split(','))
410 elif keytype == 'boolean':
410 elif keytype == 'boolean':
411 # Client should serialize False as '0', which is a non-empty string
411 # Client should serialize False as '0', which is a non-empty string
412 # so it evaluates as a True bool.
412 # so it evaluates as a True bool.
413 if v == '0':
413 if v == '0':
414 opts[k] = False
414 opts[k] = False
415 else:
415 else:
416 opts[k] = bool(v)
416 opts[k] = bool(v)
417 elif keytype != 'plain':
417 elif keytype != 'plain':
418 raise KeyError('unknown getbundle option type %s'
418 raise KeyError('unknown getbundle option type %s'
419 % keytype)
419 % keytype)
420
420
421 if not bundle1allowed(repo, 'pull'):
421 if not bundle1allowed(repo, 'pull'):
422 if not exchange.bundle2requested(opts.get('bundlecaps')):
422 if not exchange.bundle2requested(opts.get('bundlecaps')):
423 if proto.name == 'http-v1':
423 if proto.name == 'http-v1':
424 return wireprototypes.ooberror(bundle2required)
424 return wireprototypes.ooberror(bundle2required)
425 raise error.Abort(bundle2requiredmain,
425 raise error.Abort(bundle2requiredmain,
426 hint=bundle2requiredhint)
426 hint=bundle2requiredhint)
427
427
428 try:
428 try:
429 clheads = set(repo.changelog.heads())
429 clheads = set(repo.changelog.heads())
430 heads = set(opts.get('heads', set()))
430 heads = set(opts.get('heads', set()))
431 common = set(opts.get('common', set()))
431 common = set(opts.get('common', set()))
432 common.discard(nullid)
432 common.discard(nullid)
433 if (repo.ui.configbool('server', 'pullbundle') and
433 if (repo.ui.configbool('server', 'pullbundle') and
434 'partial-pull' in proto.getprotocaps()):
434 'partial-pull' in proto.getprotocaps()):
435 # Check if a pre-built bundle covers this request.
435 # Check if a pre-built bundle covers this request.
436 bundle = find_pullbundle(repo, proto, opts, clheads, heads, common)
436 bundle = find_pullbundle(repo, proto, opts, clheads, heads, common)
437 if bundle:
437 if bundle:
438 return wireprototypes.streamres(gen=util.filechunkiter(bundle),
438 return wireprototypes.streamres(gen=util.filechunkiter(bundle),
439 prefer_uncompressed=True)
439 prefer_uncompressed=True)
440
440
441 if repo.ui.configbool('server', 'disablefullbundle'):
441 if repo.ui.configbool('server', 'disablefullbundle'):
442 # Check to see if this is a full clone.
442 # Check to see if this is a full clone.
443 changegroup = opts.get('cg', True)
443 changegroup = opts.get('cg', True)
444 if changegroup and not common and clheads == heads:
444 if changegroup and not common and clheads == heads:
445 raise error.Abort(
445 raise error.Abort(
446 _('server has pull-based clones disabled'),
446 _('server has pull-based clones disabled'),
447 hint=_('remove --pull if specified or upgrade Mercurial'))
447 hint=_('remove --pull if specified or upgrade Mercurial'))
448
448
449 info, chunks = exchange.getbundlechunks(repo, 'serve',
449 info, chunks = exchange.getbundlechunks(repo, 'serve',
450 **pycompat.strkwargs(opts))
450 **pycompat.strkwargs(opts))
451 prefercompressed = info.get('prefercompressed', True)
451 prefercompressed = info.get('prefercompressed', True)
452 except error.Abort as exc:
452 except error.Abort as exc:
453 # cleanly forward Abort error to the client
453 # cleanly forward Abort error to the client
454 if not exchange.bundle2requested(opts.get('bundlecaps')):
454 if not exchange.bundle2requested(opts.get('bundlecaps')):
455 if proto.name == 'http-v1':
455 if proto.name == 'http-v1':
456 return wireprototypes.ooberror(pycompat.bytestr(exc) + '\n')
456 return wireprototypes.ooberror(pycompat.bytestr(exc) + '\n')
457 raise # cannot do better for bundle1 + ssh
457 raise # cannot do better for bundle1 + ssh
458 # bundle2 request expect a bundle2 reply
458 # bundle2 request expect a bundle2 reply
459 bundler = bundle2.bundle20(repo.ui)
459 bundler = bundle2.bundle20(repo.ui)
460 manargs = [('message', pycompat.bytestr(exc))]
460 manargs = [('message', pycompat.bytestr(exc))]
461 advargs = []
461 advargs = []
462 if exc.hint is not None:
462 if exc.hint is not None:
463 advargs.append(('hint', exc.hint))
463 advargs.append(('hint', exc.hint))
464 bundler.addpart(bundle2.bundlepart('error:abort',
464 bundler.addpart(bundle2.bundlepart('error:abort',
465 manargs, advargs))
465 manargs, advargs))
466 chunks = bundler.getchunks()
466 chunks = bundler.getchunks()
467 prefercompressed = False
467 prefercompressed = False
468
468
469 return wireprototypes.streamres(
469 return wireprototypes.streamres(
470 gen=chunks, prefer_uncompressed=not prefercompressed)
470 gen=chunks, prefer_uncompressed=not prefercompressed)
471
471
472 @wireprotocommand('heads', permission='pull')
472 @wireprotocommand('heads', permission='pull')
473 def heads(repo, proto):
473 def heads(repo, proto):
474 h = repo.heads()
474 h = repo.heads()
475 return wireprototypes.bytesresponse(wireprototypes.encodelist(h) + '\n')
475 return wireprototypes.bytesresponse(wireprototypes.encodelist(h) + '\n')
476
476
477 @wireprotocommand('hello', permission='pull')
477 @wireprotocommand('hello', permission='pull')
478 def hello(repo, proto):
478 def hello(repo, proto):
479 """Called as part of SSH handshake to obtain server info.
479 """Called as part of SSH handshake to obtain server info.
480
480
481 Returns a list of lines describing interesting things about the
481 Returns a list of lines describing interesting things about the
482 server, in an RFC822-like format.
482 server, in an RFC822-like format.
483
483
484 Currently, the only one defined is ``capabilities``, which consists of a
484 Currently, the only one defined is ``capabilities``, which consists of a
485 line of space separated tokens describing server abilities:
485 line of space separated tokens describing server abilities:
486
486
487 capabilities: <token0> <token1> <token2>
487 capabilities: <token0> <token1> <token2>
488 """
488 """
489 caps = capabilities(repo, proto).data
489 caps = capabilities(repo, proto).data
490 return wireprototypes.bytesresponse('capabilities: %s\n' % caps)
490 return wireprototypes.bytesresponse('capabilities: %s\n' % caps)
491
491
492 @wireprotocommand('listkeys', 'namespace', permission='pull')
492 @wireprotocommand('listkeys', 'namespace', permission='pull')
493 def listkeys(repo, proto, namespace):
493 def listkeys(repo, proto, namespace):
494 d = sorted(repo.listkeys(encoding.tolocal(namespace)).items())
494 d = sorted(repo.listkeys(encoding.tolocal(namespace)).items())
495 return wireprototypes.bytesresponse(pushkeymod.encodekeys(d))
495 return wireprototypes.bytesresponse(pushkeymod.encodekeys(d))
496
496
497 @wireprotocommand('lookup', 'key', permission='pull')
497 @wireprotocommand('lookup', 'key', permission='pull')
498 def lookup(repo, proto, key):
498 def lookup(repo, proto, key):
499 try:
499 try:
500 k = encoding.tolocal(key)
500 k = encoding.tolocal(key)
501 n = repo.lookup(k)
501 n = repo.lookup(k)
502 r = hex(n)
502 r = hex(n)
503 success = 1
503 success = 1
504 except Exception as inst:
504 except Exception as inst:
505 r = stringutil.forcebytestr(inst)
505 r = stringutil.forcebytestr(inst)
506 success = 0
506 success = 0
507 return wireprototypes.bytesresponse('%d %s\n' % (success, r))
507 return wireprototypes.bytesresponse('%d %s\n' % (success, r))
508
508
509 @wireprotocommand('known', 'nodes *', permission='pull')
509 @wireprotocommand('known', 'nodes *', permission='pull')
510 def known(repo, proto, nodes, others):
510 def known(repo, proto, nodes, others):
511 v = ''.join(b and '1' or '0'
511 v = ''.join(b and '1' or '0'
512 for b in repo.known(wireprototypes.decodelist(nodes)))
512 for b in repo.known(wireprototypes.decodelist(nodes)))
513 return wireprototypes.bytesresponse(v)
513 return wireprototypes.bytesresponse(v)
514
514
515 @wireprotocommand('protocaps', 'caps', permission='pull')
515 @wireprotocommand('protocaps', 'caps', permission='pull')
516 def protocaps(repo, proto, caps):
516 def protocaps(repo, proto, caps):
517 if proto.name == wireprototypes.SSHV1:
517 if proto.name == wireprototypes.SSHV1:
518 proto._protocaps = set(caps.split(' '))
518 proto._protocaps = set(caps.split(' '))
519 return wireprototypes.bytesresponse('OK')
519 return wireprototypes.bytesresponse('OK')
520
520
521 @wireprotocommand('pushkey', 'namespace key old new', permission='push')
521 @wireprotocommand('pushkey', 'namespace key old new', permission='push')
522 def pushkey(repo, proto, namespace, key, old, new):
522 def pushkey(repo, proto, namespace, key, old, new):
523 # compatibility with pre-1.8 clients which were accidentally
523 # compatibility with pre-1.8 clients which were accidentally
524 # sending raw binary nodes rather than utf-8-encoded hex
524 # sending raw binary nodes rather than utf-8-encoded hex
525 if len(new) == 20 and stringutil.escapestr(new) != new:
525 if len(new) == 20 and stringutil.escapestr(new) != new:
526 # looks like it could be a binary node
526 # looks like it could be a binary node
527 try:
527 try:
528 new.decode('utf-8')
528 new.decode('utf-8')
529 new = encoding.tolocal(new) # but cleanly decodes as UTF-8
529 new = encoding.tolocal(new) # but cleanly decodes as UTF-8
530 except UnicodeDecodeError:
530 except UnicodeDecodeError:
531 pass # binary, leave unmodified
531 pass # binary, leave unmodified
532 else:
532 else:
533 new = encoding.tolocal(new) # normal path
533 new = encoding.tolocal(new) # normal path
534
534
535 with proto.mayberedirectstdio() as output:
535 with proto.mayberedirectstdio() as output:
536 r = repo.pushkey(encoding.tolocal(namespace), encoding.tolocal(key),
536 r = repo.pushkey(encoding.tolocal(namespace), encoding.tolocal(key),
537 encoding.tolocal(old), new) or False
537 encoding.tolocal(old), new) or False
538
538
539 output = output.getvalue() if output else ''
539 output = output.getvalue() if output else ''
540 return wireprototypes.bytesresponse('%d\n%s' % (int(r), output))
540 return wireprototypes.bytesresponse('%d\n%s' % (int(r), output))
541
541
542 @wireprotocommand('stream_out', permission='pull')
542 @wireprotocommand('stream_out', permission='pull')
543 def stream(repo, proto):
543 def stream(repo, proto):
544 '''If the server supports streaming clone, it advertises the "stream"
544 '''If the server supports streaming clone, it advertises the "stream"
545 capability with a value representing the version and flags of the repo
545 capability with a value representing the version and flags of the repo
546 it is serving. Client checks to see if it understands the format.
546 it is serving. Client checks to see if it understands the format.
547 '''
547 '''
548 return wireprototypes.streamreslegacy(
548 return wireprototypes.streamreslegacy(
549 streamclone.generatev1wireproto(repo))
549 streamclone.generatev1wireproto(repo))
550
550
551 @wireprotocommand('unbundle', 'heads', permission='push')
551 @wireprotocommand('unbundle', 'heads', permission='push')
552 def unbundle(repo, proto, heads):
552 def unbundle(repo, proto, heads):
553 their_heads = wireprototypes.decodelist(heads)
553 their_heads = wireprototypes.decodelist(heads)
554
554
555 with proto.mayberedirectstdio() as output:
555 with proto.mayberedirectstdio() as output:
556 try:
556 try:
557 exchange.check_heads(repo, their_heads, 'preparing changes')
557 exchange.check_heads(repo, their_heads, 'preparing changes')
558 cleanup = lambda: None
558 cleanup = lambda: None
559 try:
559 try:
560 payload = proto.getpayload()
560 payload = proto.getpayload()
561 if repo.ui.configbool('server', 'streamunbundle'):
561 if repo.ui.configbool('server', 'streamunbundle'):
562 def cleanup():
562 def cleanup():
563 # Ensure that the full payload is consumed, so
563 # Ensure that the full payload is consumed, so
564 # that the connection doesn't contain trailing garbage.
564 # that the connection doesn't contain trailing garbage.
565 for p in payload:
565 for p in payload:
566 pass
566 pass
567 fp = util.chunkbuffer(payload)
567 fp = util.chunkbuffer(payload)
568 else:
568 else:
569 # write bundle data to temporary file as it can be big
569 # write bundle data to temporary file as it can be big
570 fp, tempname = None, None
570 fp, tempname = None, None
571 def cleanup():
571 def cleanup():
572 if fp:
572 if fp:
573 fp.close()
573 fp.close()
574 if tempname:
574 if tempname:
575 os.unlink(tempname)
575 os.unlink(tempname)
576 fd, tempname = pycompat.mkstemp(prefix='hg-unbundle-')
576 fd, tempname = pycompat.mkstemp(prefix='hg-unbundle-')
577 repo.ui.debug('redirecting incoming bundle to %s\n' %
577 repo.ui.debug('redirecting incoming bundle to %s\n' %
578 tempname)
578 tempname)
579 fp = os.fdopen(fd, pycompat.sysstr('wb+'))
579 fp = os.fdopen(fd, pycompat.sysstr('wb+'))
580 for p in payload:
580 for p in payload:
581 fp.write(p)
581 fp.write(p)
582 fp.seek(0)
582 fp.seek(0)
583
583
584 gen = exchange.readbundle(repo.ui, fp, None)
584 gen = exchange.readbundle(repo.ui, fp, None)
585 if (isinstance(gen, changegroupmod.cg1unpacker)
585 if (isinstance(gen, changegroupmod.cg1unpacker)
586 and not bundle1allowed(repo, 'push')):
586 and not bundle1allowed(repo, 'push')):
587 if proto.name == 'http-v1':
587 if proto.name == 'http-v1':
588 # need to special case http because stderr do not get to
588 # need to special case http because stderr do not get to
589 # the http client on failed push so we need to abuse
589 # the http client on failed push so we need to abuse
590 # some other error type to make sure the message get to
590 # some other error type to make sure the message get to
591 # the user.
591 # the user.
592 return wireprototypes.ooberror(bundle2required)
592 return wireprototypes.ooberror(bundle2required)
593 raise error.Abort(bundle2requiredmain,
593 raise error.Abort(bundle2requiredmain,
594 hint=bundle2requiredhint)
594 hint=bundle2requiredhint)
595
595
596 r = exchange.unbundle(repo, gen, their_heads, 'serve',
596 r = exchange.unbundle(repo, gen, their_heads, 'serve',
597 proto.client())
597 proto.client())
598 if util.safehasattr(r, 'addpart'):
598 if util.safehasattr(r, 'addpart'):
599 # The return looks streamable, we are in the bundle2 case
599 # The return looks streamable, we are in the bundle2 case
600 # and should return a stream.
600 # and should return a stream.
601 return wireprototypes.streamreslegacy(gen=r.getchunks())
601 return wireprototypes.streamreslegacy(gen=r.getchunks())
602 return wireprototypes.pushres(
602 return wireprototypes.pushres(
603 r, output.getvalue() if output else '')
603 r, output.getvalue() if output else '')
604
604
605 finally:
605 finally:
606 cleanup()
606 cleanup()
607
607
608 except (error.BundleValueError, error.Abort, error.PushRaced) as exc:
608 except (error.BundleValueError, error.Abort, error.PushRaced) as exc:
609 # handle non-bundle2 case first
609 # handle non-bundle2 case first
610 if not getattr(exc, 'duringunbundle2', False):
610 if not getattr(exc, 'duringunbundle2', False):
611 try:
611 try:
612 raise
612 raise
613 except error.Abort:
613 except error.Abort:
614 # The old code we moved used procutil.stderr directly.
614 # The old code we moved used procutil.stderr directly.
615 # We did not change it to minimise code change.
615 # We did not change it to minimise code change.
616 # This need to be moved to something proper.
616 # This need to be moved to something proper.
617 # Feel free to do it.
617 # Feel free to do it.
618 procutil.stderr.write("abort: %s\n" % exc)
618 procutil.stderr.write("abort: %s\n" % exc)
619 if exc.hint is not None:
619 if exc.hint is not None:
620 procutil.stderr.write("(%s)\n" % exc.hint)
620 procutil.stderr.write("(%s)\n" % exc.hint)
621 procutil.stderr.flush()
621 procutil.stderr.flush()
622 return wireprototypes.pushres(
622 return wireprototypes.pushres(
623 0, output.getvalue() if output else '')
623 0, output.getvalue() if output else '')
624 except error.PushRaced:
624 except error.PushRaced:
625 return wireprototypes.pusherr(
625 return wireprototypes.pusherr(
626 pycompat.bytestr(exc),
626 pycompat.bytestr(exc),
627 output.getvalue() if output else '')
627 output.getvalue() if output else '')
628
628
629 bundler = bundle2.bundle20(repo.ui)
629 bundler = bundle2.bundle20(repo.ui)
630 for out in getattr(exc, '_bundle2salvagedoutput', ()):
630 for out in getattr(exc, '_bundle2salvagedoutput', ()):
631 bundler.addpart(out)
631 bundler.addpart(out)
632 try:
632 try:
633 try:
633 try:
634 raise
634 raise
635 except error.PushkeyFailed as exc:
635 except error.PushkeyFailed as exc:
636 # check client caps
636 # check client caps
637 remotecaps = getattr(exc, '_replycaps', None)
637 remotecaps = getattr(exc, '_replycaps', None)
638 if (remotecaps is not None
638 if (remotecaps is not None
639 and 'pushkey' not in remotecaps.get('error', ())):
639 and 'pushkey' not in remotecaps.get('error', ())):
640 # no support remote side, fallback to Abort handler.
640 # no support remote side, fallback to Abort handler.
641 raise
641 raise
642 part = bundler.newpart('error:pushkey')
642 part = bundler.newpart('error:pushkey')
643 part.addparam('in-reply-to', exc.partid)
643 part.addparam('in-reply-to', exc.partid)
644 if exc.namespace is not None:
644 if exc.namespace is not None:
645 part.addparam('namespace', exc.namespace,
645 part.addparam('namespace', exc.namespace,
646 mandatory=False)
646 mandatory=False)
647 if exc.key is not None:
647 if exc.key is not None:
648 part.addparam('key', exc.key, mandatory=False)
648 part.addparam('key', exc.key, mandatory=False)
649 if exc.new is not None:
649 if exc.new is not None:
650 part.addparam('new', exc.new, mandatory=False)
650 part.addparam('new', exc.new, mandatory=False)
651 if exc.old is not None:
651 if exc.old is not None:
652 part.addparam('old', exc.old, mandatory=False)
652 part.addparam('old', exc.old, mandatory=False)
653 if exc.ret is not None:
653 if exc.ret is not None:
654 part.addparam('ret', exc.ret, mandatory=False)
654 part.addparam('ret', exc.ret, mandatory=False)
655 except error.BundleValueError as exc:
655 except error.BundleValueError as exc:
656 errpart = bundler.newpart('error:unsupportedcontent')
656 errpart = bundler.newpart('error:unsupportedcontent')
657 if exc.parttype is not None:
657 if exc.parttype is not None:
658 errpart.addparam('parttype', exc.parttype)
658 errpart.addparam('parttype', exc.parttype)
659 if exc.params:
659 if exc.params:
660 errpart.addparam('params', '\0'.join(exc.params))
660 errpart.addparam('params', '\0'.join(exc.params))
661 except error.Abort as exc:
661 except error.Abort as exc:
662 manargs = [('message', stringutil.forcebytestr(exc))]
662 manargs = [('message', stringutil.forcebytestr(exc))]
663 advargs = []
663 advargs = []
664 if exc.hint is not None:
664 if exc.hint is not None:
665 advargs.append(('hint', exc.hint))
665 advargs.append(('hint', exc.hint))
666 bundler.addpart(bundle2.bundlepart('error:abort',
666 bundler.addpart(bundle2.bundlepart('error:abort',
667 manargs, advargs))
667 manargs, advargs))
668 except error.PushRaced as exc:
668 except error.PushRaced as exc:
669 bundler.newpart('error:pushraced',
669 bundler.newpart('error:pushraced',
670 [('message', stringutil.forcebytestr(exc))])
670 [('message', stringutil.forcebytestr(exc))])
671 return wireprototypes.streamreslegacy(gen=bundler.getchunks())
671 return wireprototypes.streamreslegacy(gen=bundler.getchunks())
@@ -1,1454 +1,1455
1 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
1 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
2 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 #
3 #
4 # This software may be used and distributed according to the terms of the
4 # This software may be used and distributed according to the terms of the
5 # GNU General Public License version 2 or any later version.
5 # GNU General Public License version 2 or any later version.
6
6
7 from __future__ import absolute_import
7 from __future__ import absolute_import
8
8
9 import collections
9 import collections
10 import contextlib
10 import contextlib
11 import hashlib
11 import hashlib
12
12
13 from .i18n import _
13 from .i18n import _
14 from .node import (
14 from .node import (
15 hex,
15 hex,
16 nullid,
16 nullid,
17 )
17 )
18 from . import (
18 from . import (
19 discovery,
19 discovery,
20 encoding,
20 encoding,
21 error,
21 error,
22 match as matchmod,
22 match as matchmod,
23 narrowspec,
23 narrowspec,
24 pycompat,
24 pycompat,
25 streamclone,
25 streamclone,
26 templatefilters,
26 templatefilters,
27 util,
27 util,
28 wireprotoframing,
28 wireprotoframing,
29 wireprototypes,
29 wireprototypes,
30 )
30 )
31 from .utils import (
31 from .utils import (
32 cborutil,
32 cborutil,
33 interfaceutil,
33 interfaceutil,
34 stringutil,
34 stringutil,
35 )
35 )
36
36
37 FRAMINGTYPE = b'application/mercurial-exp-framing-0006'
37 FRAMINGTYPE = b'application/mercurial-exp-framing-0006'
38
38
39 HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2
39 HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2
40
40
41 COMMANDS = wireprototypes.commanddict()
41 COMMANDS = wireprototypes.commanddict()
42
42
43 # Value inserted into cache key computation function. Change the value to
43 # Value inserted into cache key computation function. Change the value to
44 # force new cache keys for every command request. This should be done when
44 # force new cache keys for every command request. This should be done when
45 # there is a change to how caching works, etc.
45 # there is a change to how caching works, etc.
46 GLOBAL_CACHE_VERSION = 1
46 GLOBAL_CACHE_VERSION = 1
47
47
48 def handlehttpv2request(rctx, req, res, checkperm, urlparts):
48 def handlehttpv2request(rctx, req, res, checkperm, urlparts):
49 from .hgweb import common as hgwebcommon
49 from .hgweb import common as hgwebcommon
50
50
51 # URL space looks like: <permissions>/<command>, where <permission> can
51 # URL space looks like: <permissions>/<command>, where <permission> can
52 # be ``ro`` or ``rw`` to signal read-only or read-write, respectively.
52 # be ``ro`` or ``rw`` to signal read-only or read-write, respectively.
53
53
54 # Root URL does nothing meaningful... yet.
54 # Root URL does nothing meaningful... yet.
55 if not urlparts:
55 if not urlparts:
56 res.status = b'200 OK'
56 res.status = b'200 OK'
57 res.headers[b'Content-Type'] = b'text/plain'
57 res.headers[b'Content-Type'] = b'text/plain'
58 res.setbodybytes(_('HTTP version 2 API handler'))
58 res.setbodybytes(_('HTTP version 2 API handler'))
59 return
59 return
60
60
61 if len(urlparts) == 1:
61 if len(urlparts) == 1:
62 res.status = b'404 Not Found'
62 res.status = b'404 Not Found'
63 res.headers[b'Content-Type'] = b'text/plain'
63 res.headers[b'Content-Type'] = b'text/plain'
64 res.setbodybytes(_('do not know how to process %s\n') %
64 res.setbodybytes(_('do not know how to process %s\n') %
65 req.dispatchpath)
65 req.dispatchpath)
66 return
66 return
67
67
68 permission, command = urlparts[0:2]
68 permission, command = urlparts[0:2]
69
69
70 if permission not in (b'ro', b'rw'):
70 if permission not in (b'ro', b'rw'):
71 res.status = b'404 Not Found'
71 res.status = b'404 Not Found'
72 res.headers[b'Content-Type'] = b'text/plain'
72 res.headers[b'Content-Type'] = b'text/plain'
73 res.setbodybytes(_('unknown permission: %s') % permission)
73 res.setbodybytes(_('unknown permission: %s') % permission)
74 return
74 return
75
75
76 if req.method != 'POST':
76 if req.method != 'POST':
77 res.status = b'405 Method Not Allowed'
77 res.status = b'405 Method Not Allowed'
78 res.headers[b'Allow'] = b'POST'
78 res.headers[b'Allow'] = b'POST'
79 res.setbodybytes(_('commands require POST requests'))
79 res.setbodybytes(_('commands require POST requests'))
80 return
80 return
81
81
82 # At some point we'll want to use our own API instead of recycling the
82 # At some point we'll want to use our own API instead of recycling the
83 # behavior of version 1 of the wire protocol...
83 # behavior of version 1 of the wire protocol...
84 # TODO return reasonable responses - not responses that overload the
84 # TODO return reasonable responses - not responses that overload the
85 # HTTP status line message for error reporting.
85 # HTTP status line message for error reporting.
86 try:
86 try:
87 checkperm(rctx, req, 'pull' if permission == b'ro' else 'push')
87 checkperm(rctx, req, 'pull' if permission == b'ro' else 'push')
88 except hgwebcommon.ErrorResponse as e:
88 except hgwebcommon.ErrorResponse as e:
89 res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))
89 res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))
90 for k, v in e.headers:
90 for k, v in e.headers:
91 res.headers[k] = v
91 res.headers[k] = v
92 res.setbodybytes('permission denied')
92 res.setbodybytes('permission denied')
93 return
93 return
94
94
95 # We have a special endpoint to reflect the request back at the client.
95 # We have a special endpoint to reflect the request back at the client.
96 if command == b'debugreflect':
96 if command == b'debugreflect':
97 _processhttpv2reflectrequest(rctx.repo.ui, rctx.repo, req, res)
97 _processhttpv2reflectrequest(rctx.repo.ui, rctx.repo, req, res)
98 return
98 return
99
99
100 # Extra commands that we handle that aren't really wire protocol
100 # Extra commands that we handle that aren't really wire protocol
101 # commands. Think extra hard before making this hackery available to
101 # commands. Think extra hard before making this hackery available to
102 # extension.
102 # extension.
103 extracommands = {'multirequest'}
103 extracommands = {'multirequest'}
104
104
105 if command not in COMMANDS and command not in extracommands:
105 if command not in COMMANDS and command not in extracommands:
106 res.status = b'404 Not Found'
106 res.status = b'404 Not Found'
107 res.headers[b'Content-Type'] = b'text/plain'
107 res.headers[b'Content-Type'] = b'text/plain'
108 res.setbodybytes(_('unknown wire protocol command: %s\n') % command)
108 res.setbodybytes(_('unknown wire protocol command: %s\n') % command)
109 return
109 return
110
110
111 repo = rctx.repo
111 repo = rctx.repo
112 ui = repo.ui
112 ui = repo.ui
113
113
114 proto = httpv2protocolhandler(req, ui)
114 proto = httpv2protocolhandler(req, ui)
115
115
116 if (not COMMANDS.commandavailable(command, proto)
116 if (not COMMANDS.commandavailable(command, proto)
117 and command not in extracommands):
117 and command not in extracommands):
118 res.status = b'404 Not Found'
118 res.status = b'404 Not Found'
119 res.headers[b'Content-Type'] = b'text/plain'
119 res.headers[b'Content-Type'] = b'text/plain'
120 res.setbodybytes(_('invalid wire protocol command: %s') % command)
120 res.setbodybytes(_('invalid wire protocol command: %s') % command)
121 return
121 return
122
122
123 # TODO consider cases where proxies may add additional Accept headers.
123 # TODO consider cases where proxies may add additional Accept headers.
124 if req.headers.get(b'Accept') != FRAMINGTYPE:
124 if req.headers.get(b'Accept') != FRAMINGTYPE:
125 res.status = b'406 Not Acceptable'
125 res.status = b'406 Not Acceptable'
126 res.headers[b'Content-Type'] = b'text/plain'
126 res.headers[b'Content-Type'] = b'text/plain'
127 res.setbodybytes(_('client MUST specify Accept header with value: %s\n')
127 res.setbodybytes(_('client MUST specify Accept header with value: %s\n')
128 % FRAMINGTYPE)
128 % FRAMINGTYPE)
129 return
129 return
130
130
131 if req.headers.get(b'Content-Type') != FRAMINGTYPE:
131 if req.headers.get(b'Content-Type') != FRAMINGTYPE:
132 res.status = b'415 Unsupported Media Type'
132 res.status = b'415 Unsupported Media Type'
133 # TODO we should send a response with appropriate media type,
133 # TODO we should send a response with appropriate media type,
134 # since client does Accept it.
134 # since client does Accept it.
135 res.headers[b'Content-Type'] = b'text/plain'
135 res.headers[b'Content-Type'] = b'text/plain'
136 res.setbodybytes(_('client MUST send Content-Type header with '
136 res.setbodybytes(_('client MUST send Content-Type header with '
137 'value: %s\n') % FRAMINGTYPE)
137 'value: %s\n') % FRAMINGTYPE)
138 return
138 return
139
139
140 _processhttpv2request(ui, repo, req, res, permission, command, proto)
140 _processhttpv2request(ui, repo, req, res, permission, command, proto)
141
141
142 def _processhttpv2reflectrequest(ui, repo, req, res):
142 def _processhttpv2reflectrequest(ui, repo, req, res):
143 """Reads unified frame protocol request and dumps out state to client.
143 """Reads unified frame protocol request and dumps out state to client.
144
144
145 This special endpoint can be used to help debug the wire protocol.
145 This special endpoint can be used to help debug the wire protocol.
146
146
147 Instead of routing the request through the normal dispatch mechanism,
147 Instead of routing the request through the normal dispatch mechanism,
148 we instead read all frames, decode them, and feed them into our state
148 we instead read all frames, decode them, and feed them into our state
149 tracker. We then dump the log of all that activity back out to the
149 tracker. We then dump the log of all that activity back out to the
150 client.
150 client.
151 """
151 """
152 # Reflection APIs have a history of being abused, accidentally disclosing
152 # Reflection APIs have a history of being abused, accidentally disclosing
153 # sensitive data, etc. So we have a config knob.
153 # sensitive data, etc. So we have a config knob.
154 if not ui.configbool('experimental', 'web.api.debugreflect'):
154 if not ui.configbool('experimental', 'web.api.debugreflect'):
155 res.status = b'404 Not Found'
155 res.status = b'404 Not Found'
156 res.headers[b'Content-Type'] = b'text/plain'
156 res.headers[b'Content-Type'] = b'text/plain'
157 res.setbodybytes(_('debugreflect service not available'))
157 res.setbodybytes(_('debugreflect service not available'))
158 return
158 return
159
159
160 # We assume we have a unified framing protocol request body.
160 # We assume we have a unified framing protocol request body.
161
161
162 reactor = wireprotoframing.serverreactor(ui)
162 reactor = wireprotoframing.serverreactor(ui)
163 states = []
163 states = []
164
164
165 while True:
165 while True:
166 frame = wireprotoframing.readframe(req.bodyfh)
166 frame = wireprotoframing.readframe(req.bodyfh)
167
167
168 if not frame:
168 if not frame:
169 states.append(b'received: <no frame>')
169 states.append(b'received: <no frame>')
170 break
170 break
171
171
172 states.append(b'received: %d %d %d %s' % (frame.typeid, frame.flags,
172 states.append(b'received: %d %d %d %s' % (frame.typeid, frame.flags,
173 frame.requestid,
173 frame.requestid,
174 frame.payload))
174 frame.payload))
175
175
176 action, meta = reactor.onframerecv(frame)
176 action, meta = reactor.onframerecv(frame)
177 states.append(templatefilters.json((action, meta)))
177 states.append(templatefilters.json((action, meta)))
178
178
179 action, meta = reactor.oninputeof()
179 action, meta = reactor.oninputeof()
180 meta['action'] = action
180 meta['action'] = action
181 states.append(templatefilters.json(meta))
181 states.append(templatefilters.json(meta))
182
182
183 res.status = b'200 OK'
183 res.status = b'200 OK'
184 res.headers[b'Content-Type'] = b'text/plain'
184 res.headers[b'Content-Type'] = b'text/plain'
185 res.setbodybytes(b'\n'.join(states))
185 res.setbodybytes(b'\n'.join(states))
186
186
187 def _processhttpv2request(ui, repo, req, res, authedperm, reqcommand, proto):
187 def _processhttpv2request(ui, repo, req, res, authedperm, reqcommand, proto):
188 """Post-validation handler for HTTPv2 requests.
188 """Post-validation handler for HTTPv2 requests.
189
189
190 Called when the HTTP request contains unified frame-based protocol
190 Called when the HTTP request contains unified frame-based protocol
191 frames for evaluation.
191 frames for evaluation.
192 """
192 """
193 # TODO Some HTTP clients are full duplex and can receive data before
193 # TODO Some HTTP clients are full duplex and can receive data before
194 # the entire request is transmitted. Figure out a way to indicate support
194 # the entire request is transmitted. Figure out a way to indicate support
195 # for that so we can opt into full duplex mode.
195 # for that so we can opt into full duplex mode.
196 reactor = wireprotoframing.serverreactor(ui, deferoutput=True)
196 reactor = wireprotoframing.serverreactor(ui, deferoutput=True)
197 seencommand = False
197 seencommand = False
198
198
199 outstream = None
199 outstream = None
200
200
201 while True:
201 while True:
202 frame = wireprotoframing.readframe(req.bodyfh)
202 frame = wireprotoframing.readframe(req.bodyfh)
203 if not frame:
203 if not frame:
204 break
204 break
205
205
206 action, meta = reactor.onframerecv(frame)
206 action, meta = reactor.onframerecv(frame)
207
207
208 if action == 'wantframe':
208 if action == 'wantframe':
209 # Need more data before we can do anything.
209 # Need more data before we can do anything.
210 continue
210 continue
211 elif action == 'runcommand':
211 elif action == 'runcommand':
212 # Defer creating output stream because we need to wait for
212 # Defer creating output stream because we need to wait for
213 # protocol settings frames so proper encoding can be applied.
213 # protocol settings frames so proper encoding can be applied.
214 if not outstream:
214 if not outstream:
215 outstream = reactor.makeoutputstream()
215 outstream = reactor.makeoutputstream()
216
216
217 sentoutput = _httpv2runcommand(ui, repo, req, res, authedperm,
217 sentoutput = _httpv2runcommand(ui, repo, req, res, authedperm,
218 reqcommand, reactor, outstream,
218 reqcommand, reactor, outstream,
219 meta, issubsequent=seencommand)
219 meta, issubsequent=seencommand)
220
220
221 if sentoutput:
221 if sentoutput:
222 return
222 return
223
223
224 seencommand = True
224 seencommand = True
225
225
226 elif action == 'error':
226 elif action == 'error':
227 # TODO define proper error mechanism.
227 # TODO define proper error mechanism.
228 res.status = b'200 OK'
228 res.status = b'200 OK'
229 res.headers[b'Content-Type'] = b'text/plain'
229 res.headers[b'Content-Type'] = b'text/plain'
230 res.setbodybytes(meta['message'] + b'\n')
230 res.setbodybytes(meta['message'] + b'\n')
231 return
231 return
232 else:
232 else:
233 raise error.ProgrammingError(
233 raise error.ProgrammingError(
234 'unhandled action from frame processor: %s' % action)
234 'unhandled action from frame processor: %s' % action)
235
235
236 action, meta = reactor.oninputeof()
236 action, meta = reactor.oninputeof()
237 if action == 'sendframes':
237 if action == 'sendframes':
238 # We assume we haven't started sending the response yet. If we're
238 # We assume we haven't started sending the response yet. If we're
239 # wrong, the response type will raise an exception.
239 # wrong, the response type will raise an exception.
240 res.status = b'200 OK'
240 res.status = b'200 OK'
241 res.headers[b'Content-Type'] = FRAMINGTYPE
241 res.headers[b'Content-Type'] = FRAMINGTYPE
242 res.setbodygen(meta['framegen'])
242 res.setbodygen(meta['framegen'])
243 elif action == 'noop':
243 elif action == 'noop':
244 pass
244 pass
245 else:
245 else:
246 raise error.ProgrammingError('unhandled action from frame processor: %s'
246 raise error.ProgrammingError('unhandled action from frame processor: %s'
247 % action)
247 % action)
248
248
249 def _httpv2runcommand(ui, repo, req, res, authedperm, reqcommand, reactor,
249 def _httpv2runcommand(ui, repo, req, res, authedperm, reqcommand, reactor,
250 outstream, command, issubsequent):
250 outstream, command, issubsequent):
251 """Dispatch a wire protocol command made from HTTPv2 requests.
251 """Dispatch a wire protocol command made from HTTPv2 requests.
252
252
253 The authenticated permission (``authedperm``) along with the original
253 The authenticated permission (``authedperm``) along with the original
254 command from the URL (``reqcommand``) are passed in.
254 command from the URL (``reqcommand``) are passed in.
255 """
255 """
256 # We already validated that the session has permissions to perform the
256 # We already validated that the session has permissions to perform the
257 # actions in ``authedperm``. In the unified frame protocol, the canonical
257 # actions in ``authedperm``. In the unified frame protocol, the canonical
258 # command to run is expressed in a frame. However, the URL also requested
258 # command to run is expressed in a frame. However, the URL also requested
259 # to run a specific command. We need to be careful that the command we
259 # to run a specific command. We need to be careful that the command we
260 # run doesn't have permissions requirements greater than what was granted
260 # run doesn't have permissions requirements greater than what was granted
261 # by ``authedperm``.
261 # by ``authedperm``.
262 #
262 #
263 # Our rule for this is we only allow one command per HTTP request and
263 # Our rule for this is we only allow one command per HTTP request and
264 # that command must match the command in the URL. However, we make
264 # that command must match the command in the URL. However, we make
265 # an exception for the ``multirequest`` URL. This URL is allowed to
265 # an exception for the ``multirequest`` URL. This URL is allowed to
266 # execute multiple commands. We double check permissions of each command
266 # execute multiple commands. We double check permissions of each command
267 # as it is invoked to ensure there is no privilege escalation.
267 # as it is invoked to ensure there is no privilege escalation.
268 # TODO consider allowing multiple commands to regular command URLs
268 # TODO consider allowing multiple commands to regular command URLs
269 # iff each command is the same.
269 # iff each command is the same.
270
270
271 proto = httpv2protocolhandler(req, ui, args=command['args'])
271 proto = httpv2protocolhandler(req, ui, args=command['args'])
272
272
273 if reqcommand == b'multirequest':
273 if reqcommand == b'multirequest':
274 if not COMMANDS.commandavailable(command['command'], proto):
274 if not COMMANDS.commandavailable(command['command'], proto):
275 # TODO proper error mechanism
275 # TODO proper error mechanism
276 res.status = b'200 OK'
276 res.status = b'200 OK'
277 res.headers[b'Content-Type'] = b'text/plain'
277 res.headers[b'Content-Type'] = b'text/plain'
278 res.setbodybytes(_('wire protocol command not available: %s') %
278 res.setbodybytes(_('wire protocol command not available: %s') %
279 command['command'])
279 command['command'])
280 return True
280 return True
281
281
282 # TODO don't use assert here, since it may be elided by -O.
282 # TODO don't use assert here, since it may be elided by -O.
283 assert authedperm in (b'ro', b'rw')
283 assert authedperm in (b'ro', b'rw')
284 wirecommand = COMMANDS[command['command']]
284 wirecommand = COMMANDS[command['command']]
285 assert wirecommand.permission in ('push', 'pull')
285 assert wirecommand.permission in ('push', 'pull')
286
286
287 if authedperm == b'ro' and wirecommand.permission != 'pull':
287 if authedperm == b'ro' and wirecommand.permission != 'pull':
288 # TODO proper error mechanism
288 # TODO proper error mechanism
289 res.status = b'403 Forbidden'
289 res.status = b'403 Forbidden'
290 res.headers[b'Content-Type'] = b'text/plain'
290 res.headers[b'Content-Type'] = b'text/plain'
291 res.setbodybytes(_('insufficient permissions to execute '
291 res.setbodybytes(_('insufficient permissions to execute '
292 'command: %s') % command['command'])
292 'command: %s') % command['command'])
293 return True
293 return True
294
294
295 # TODO should we also call checkperm() here? Maybe not if we're going
295 # TODO should we also call checkperm() here? Maybe not if we're going
296 # to overhaul that API. The granted scope from the URL check should
296 # to overhaul that API. The granted scope from the URL check should
297 # be good enough.
297 # be good enough.
298
298
299 else:
299 else:
300 # Don't allow multiple commands outside of ``multirequest`` URL.
300 # Don't allow multiple commands outside of ``multirequest`` URL.
301 if issubsequent:
301 if issubsequent:
302 # TODO proper error mechanism
302 # TODO proper error mechanism
303 res.status = b'200 OK'
303 res.status = b'200 OK'
304 res.headers[b'Content-Type'] = b'text/plain'
304 res.headers[b'Content-Type'] = b'text/plain'
305 res.setbodybytes(_('multiple commands cannot be issued to this '
305 res.setbodybytes(_('multiple commands cannot be issued to this '
306 'URL'))
306 'URL'))
307 return True
307 return True
308
308
309 if reqcommand != command['command']:
309 if reqcommand != command['command']:
310 # TODO define proper error mechanism
310 # TODO define proper error mechanism
311 res.status = b'200 OK'
311 res.status = b'200 OK'
312 res.headers[b'Content-Type'] = b'text/plain'
312 res.headers[b'Content-Type'] = b'text/plain'
313 res.setbodybytes(_('command in frame must match command in URL'))
313 res.setbodybytes(_('command in frame must match command in URL'))
314 return True
314 return True
315
315
316 res.status = b'200 OK'
316 res.status = b'200 OK'
317 res.headers[b'Content-Type'] = FRAMINGTYPE
317 res.headers[b'Content-Type'] = FRAMINGTYPE
318
318
319 try:
319 try:
320 objs = dispatch(repo, proto, command['command'], command['redirect'])
320 objs = dispatch(repo, proto, command['command'], command['redirect'])
321
321
322 action, meta = reactor.oncommandresponsereadyobjects(
322 action, meta = reactor.oncommandresponsereadyobjects(
323 outstream, command['requestid'], objs)
323 outstream, command['requestid'], objs)
324
324
325 except error.WireprotoCommandError as e:
325 except error.WireprotoCommandError as e:
326 action, meta = reactor.oncommanderror(
326 action, meta = reactor.oncommanderror(
327 outstream, command['requestid'], e.message, e.messageargs)
327 outstream, command['requestid'], e.message, e.messageargs)
328
328
329 except Exception as e:
329 except Exception as e:
330 action, meta = reactor.onservererror(
330 action, meta = reactor.onservererror(
331 outstream, command['requestid'],
331 outstream, command['requestid'],
332 _('exception when invoking command: %s') %
332 _('exception when invoking command: %s') %
333 stringutil.forcebytestr(e))
333 stringutil.forcebytestr(e))
334
334
335 if action == 'sendframes':
335 if action == 'sendframes':
336 res.setbodygen(meta['framegen'])
336 res.setbodygen(meta['framegen'])
337 return True
337 return True
338 elif action == 'noop':
338 elif action == 'noop':
339 return False
339 return False
340 else:
340 else:
341 raise error.ProgrammingError('unhandled event from reactor: %s' %
341 raise error.ProgrammingError('unhandled event from reactor: %s' %
342 action)
342 action)
343
343
344 def getdispatchrepo(repo, proto, command):
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 def dispatch(repo, proto, command, redirect):
348 def dispatch(repo, proto, command, redirect):
348 """Run a wire protocol command.
349 """Run a wire protocol command.
349
350
350 Returns an iterable of objects that will be sent to the client.
351 Returns an iterable of objects that will be sent to the client.
351 """
352 """
352 repo = getdispatchrepo(repo, proto, command)
353 repo = getdispatchrepo(repo, proto, command)
353
354
354 entry = COMMANDS[command]
355 entry = COMMANDS[command]
355 func = entry.func
356 func = entry.func
356 spec = entry.args
357 spec = entry.args
357
358
358 args = proto.getargs(spec)
359 args = proto.getargs(spec)
359
360
360 # There is some duplicate boilerplate code here for calling the command and
361 # There is some duplicate boilerplate code here for calling the command and
361 # emitting objects. It is either that or a lot of indented code that looks
362 # emitting objects. It is either that or a lot of indented code that looks
362 # like a pyramid (since there are a lot of code paths that result in not
363 # like a pyramid (since there are a lot of code paths that result in not
363 # using the cacher).
364 # using the cacher).
364 callcommand = lambda: func(repo, proto, **pycompat.strkwargs(args))
365 callcommand = lambda: func(repo, proto, **pycompat.strkwargs(args))
365
366
366 # Request is not cacheable. Don't bother instantiating a cacher.
367 # Request is not cacheable. Don't bother instantiating a cacher.
367 if not entry.cachekeyfn:
368 if not entry.cachekeyfn:
368 for o in callcommand():
369 for o in callcommand():
369 yield o
370 yield o
370 return
371 return
371
372
372 if redirect:
373 if redirect:
373 redirecttargets = redirect[b'targets']
374 redirecttargets = redirect[b'targets']
374 redirecthashes = redirect[b'hashes']
375 redirecthashes = redirect[b'hashes']
375 else:
376 else:
376 redirecttargets = []
377 redirecttargets = []
377 redirecthashes = []
378 redirecthashes = []
378
379
379 cacher = makeresponsecacher(repo, proto, command, args,
380 cacher = makeresponsecacher(repo, proto, command, args,
380 cborutil.streamencode,
381 cborutil.streamencode,
381 redirecttargets=redirecttargets,
382 redirecttargets=redirecttargets,
382 redirecthashes=redirecthashes)
383 redirecthashes=redirecthashes)
383
384
384 # But we have no cacher. Do default handling.
385 # But we have no cacher. Do default handling.
385 if not cacher:
386 if not cacher:
386 for o in callcommand():
387 for o in callcommand():
387 yield o
388 yield o
388 return
389 return
389
390
390 with cacher:
391 with cacher:
391 cachekey = entry.cachekeyfn(repo, proto, cacher,
392 cachekey = entry.cachekeyfn(repo, proto, cacher,
392 **pycompat.strkwargs(args))
393 **pycompat.strkwargs(args))
393
394
394 # No cache key or the cacher doesn't like it. Do default handling.
395 # No cache key or the cacher doesn't like it. Do default handling.
395 if cachekey is None or not cacher.setcachekey(cachekey):
396 if cachekey is None or not cacher.setcachekey(cachekey):
396 for o in callcommand():
397 for o in callcommand():
397 yield o
398 yield o
398 return
399 return
399
400
400 # Serve it from the cache, if possible.
401 # Serve it from the cache, if possible.
401 cached = cacher.lookup()
402 cached = cacher.lookup()
402
403
403 if cached:
404 if cached:
404 for o in cached['objs']:
405 for o in cached['objs']:
405 yield o
406 yield o
406 return
407 return
407
408
408 # Else call the command and feed its output into the cacher, allowing
409 # Else call the command and feed its output into the cacher, allowing
409 # the cacher to buffer/mutate objects as it desires.
410 # the cacher to buffer/mutate objects as it desires.
410 for o in callcommand():
411 for o in callcommand():
411 for o in cacher.onobject(o):
412 for o in cacher.onobject(o):
412 yield o
413 yield o
413
414
414 for o in cacher.onfinished():
415 for o in cacher.onfinished():
415 yield o
416 yield o
416
417
417 @interfaceutil.implementer(wireprototypes.baseprotocolhandler)
418 @interfaceutil.implementer(wireprototypes.baseprotocolhandler)
418 class httpv2protocolhandler(object):
419 class httpv2protocolhandler(object):
419 def __init__(self, req, ui, args=None):
420 def __init__(self, req, ui, args=None):
420 self._req = req
421 self._req = req
421 self._ui = ui
422 self._ui = ui
422 self._args = args
423 self._args = args
423
424
424 @property
425 @property
425 def name(self):
426 def name(self):
426 return HTTP_WIREPROTO_V2
427 return HTTP_WIREPROTO_V2
427
428
428 def getargs(self, args):
429 def getargs(self, args):
429 # First look for args that were passed but aren't registered on this
430 # First look for args that were passed but aren't registered on this
430 # command.
431 # command.
431 extra = set(self._args) - set(args)
432 extra = set(self._args) - set(args)
432 if extra:
433 if extra:
433 raise error.WireprotoCommandError(
434 raise error.WireprotoCommandError(
434 'unsupported argument to command: %s' %
435 'unsupported argument to command: %s' %
435 ', '.join(sorted(extra)))
436 ', '.join(sorted(extra)))
436
437
437 # And look for required arguments that are missing.
438 # And look for required arguments that are missing.
438 missing = {a for a in args if args[a]['required']} - set(self._args)
439 missing = {a for a in args if args[a]['required']} - set(self._args)
439
440
440 if missing:
441 if missing:
441 raise error.WireprotoCommandError(
442 raise error.WireprotoCommandError(
442 'missing required arguments: %s' % ', '.join(sorted(missing)))
443 'missing required arguments: %s' % ', '.join(sorted(missing)))
443
444
444 # Now derive the arguments to pass to the command, taking into
445 # Now derive the arguments to pass to the command, taking into
445 # account the arguments specified by the client.
446 # account the arguments specified by the client.
446 data = {}
447 data = {}
447 for k, meta in sorted(args.items()):
448 for k, meta in sorted(args.items()):
448 # This argument wasn't passed by the client.
449 # This argument wasn't passed by the client.
449 if k not in self._args:
450 if k not in self._args:
450 data[k] = meta['default']()
451 data[k] = meta['default']()
451 continue
452 continue
452
453
453 v = self._args[k]
454 v = self._args[k]
454
455
455 # Sets may be expressed as lists. Silently normalize.
456 # Sets may be expressed as lists. Silently normalize.
456 if meta['type'] == 'set' and isinstance(v, list):
457 if meta['type'] == 'set' and isinstance(v, list):
457 v = set(v)
458 v = set(v)
458
459
459 # TODO consider more/stronger type validation.
460 # TODO consider more/stronger type validation.
460
461
461 data[k] = v
462 data[k] = v
462
463
463 return data
464 return data
464
465
465 def getprotocaps(self):
466 def getprotocaps(self):
466 # Protocol capabilities are currently not implemented for HTTP V2.
467 # Protocol capabilities are currently not implemented for HTTP V2.
467 return set()
468 return set()
468
469
469 def getpayload(self):
470 def getpayload(self):
470 raise NotImplementedError
471 raise NotImplementedError
471
472
472 @contextlib.contextmanager
473 @contextlib.contextmanager
473 def mayberedirectstdio(self):
474 def mayberedirectstdio(self):
474 raise NotImplementedError
475 raise NotImplementedError
475
476
476 def client(self):
477 def client(self):
477 raise NotImplementedError
478 raise NotImplementedError
478
479
479 def addcapabilities(self, repo, caps):
480 def addcapabilities(self, repo, caps):
480 return caps
481 return caps
481
482
482 def checkperm(self, perm):
483 def checkperm(self, perm):
483 raise NotImplementedError
484 raise NotImplementedError
484
485
485 def httpv2apidescriptor(req, repo):
486 def httpv2apidescriptor(req, repo):
486 proto = httpv2protocolhandler(req, repo.ui)
487 proto = httpv2protocolhandler(req, repo.ui)
487
488
488 return _capabilitiesv2(repo, proto)
489 return _capabilitiesv2(repo, proto)
489
490
490 def _capabilitiesv2(repo, proto):
491 def _capabilitiesv2(repo, proto):
491 """Obtain the set of capabilities for version 2 transports.
492 """Obtain the set of capabilities for version 2 transports.
492
493
493 These capabilities are distinct from the capabilities for version 1
494 These capabilities are distinct from the capabilities for version 1
494 transports.
495 transports.
495 """
496 """
496 caps = {
497 caps = {
497 'commands': {},
498 'commands': {},
498 'framingmediatypes': [FRAMINGTYPE],
499 'framingmediatypes': [FRAMINGTYPE],
499 'pathfilterprefixes': set(narrowspec.VALID_PREFIXES),
500 'pathfilterprefixes': set(narrowspec.VALID_PREFIXES),
500 }
501 }
501
502
502 for command, entry in COMMANDS.items():
503 for command, entry in COMMANDS.items():
503 args = {}
504 args = {}
504
505
505 for arg, meta in entry.args.items():
506 for arg, meta in entry.args.items():
506 args[arg] = {
507 args[arg] = {
507 # TODO should this be a normalized type using CBOR's
508 # TODO should this be a normalized type using CBOR's
508 # terminology?
509 # terminology?
509 b'type': meta['type'],
510 b'type': meta['type'],
510 b'required': meta['required'],
511 b'required': meta['required'],
511 }
512 }
512
513
513 if not meta['required']:
514 if not meta['required']:
514 args[arg][b'default'] = meta['default']()
515 args[arg][b'default'] = meta['default']()
515
516
516 if meta['validvalues']:
517 if meta['validvalues']:
517 args[arg][b'validvalues'] = meta['validvalues']
518 args[arg][b'validvalues'] = meta['validvalues']
518
519
519 # TODO this type of check should be defined in a per-command callback.
520 # TODO this type of check should be defined in a per-command callback.
520 if (command == b'rawstorefiledata'
521 if (command == b'rawstorefiledata'
521 and not streamclone.allowservergeneration(repo)):
522 and not streamclone.allowservergeneration(repo)):
522 continue
523 continue
523
524
524 caps['commands'][command] = {
525 caps['commands'][command] = {
525 'args': args,
526 'args': args,
526 'permissions': [entry.permission],
527 'permissions': [entry.permission],
527 }
528 }
528
529
529 if entry.extracapabilitiesfn:
530 if entry.extracapabilitiesfn:
530 extracaps = entry.extracapabilitiesfn(repo, proto)
531 extracaps = entry.extracapabilitiesfn(repo, proto)
531 caps['commands'][command].update(extracaps)
532 caps['commands'][command].update(extracaps)
532
533
533 caps['rawrepoformats'] = sorted(repo.requirements &
534 caps['rawrepoformats'] = sorted(repo.requirements &
534 repo.supportedformats)
535 repo.supportedformats)
535
536
536 targets = getadvertisedredirecttargets(repo, proto)
537 targets = getadvertisedredirecttargets(repo, proto)
537 if targets:
538 if targets:
538 caps[b'redirect'] = {
539 caps[b'redirect'] = {
539 b'targets': [],
540 b'targets': [],
540 b'hashes': [b'sha256', b'sha1'],
541 b'hashes': [b'sha256', b'sha1'],
541 }
542 }
542
543
543 for target in targets:
544 for target in targets:
544 entry = {
545 entry = {
545 b'name': target['name'],
546 b'name': target['name'],
546 b'protocol': target['protocol'],
547 b'protocol': target['protocol'],
547 b'uris': target['uris'],
548 b'uris': target['uris'],
548 }
549 }
549
550
550 for key in ('snirequired', 'tlsversions'):
551 for key in ('snirequired', 'tlsversions'):
551 if key in target:
552 if key in target:
552 entry[key] = target[key]
553 entry[key] = target[key]
553
554
554 caps[b'redirect'][b'targets'].append(entry)
555 caps[b'redirect'][b'targets'].append(entry)
555
556
556 return proto.addcapabilities(repo, caps)
557 return proto.addcapabilities(repo, caps)
557
558
558 def getadvertisedredirecttargets(repo, proto):
559 def getadvertisedredirecttargets(repo, proto):
559 """Obtain a list of content redirect targets.
560 """Obtain a list of content redirect targets.
560
561
561 Returns a list containing potential redirect targets that will be
562 Returns a list containing potential redirect targets that will be
562 advertised in capabilities data. Each dict MUST have the following
563 advertised in capabilities data. Each dict MUST have the following
563 keys:
564 keys:
564
565
565 name
566 name
566 The name of this redirect target. This is the identifier clients use
567 The name of this redirect target. This is the identifier clients use
567 to refer to a target. It is transferred as part of every command
568 to refer to a target. It is transferred as part of every command
568 request.
569 request.
569
570
570 protocol
571 protocol
571 Network protocol used by this target. Typically this is the string
572 Network protocol used by this target. Typically this is the string
572 in front of the ``://`` in a URL. e.g. ``https``.
573 in front of the ``://`` in a URL. e.g. ``https``.
573
574
574 uris
575 uris
575 List of representative URIs for this target. Clients can use the
576 List of representative URIs for this target. Clients can use the
576 URIs to test parsing for compatibility or for ordering preference
577 URIs to test parsing for compatibility or for ordering preference
577 for which target to use.
578 for which target to use.
578
579
579 The following optional keys are recognized:
580 The following optional keys are recognized:
580
581
581 snirequired
582 snirequired
582 Bool indicating if Server Name Indication (SNI) is required to
583 Bool indicating if Server Name Indication (SNI) is required to
583 connect to this target.
584 connect to this target.
584
585
585 tlsversions
586 tlsversions
586 List of bytes indicating which TLS versions are supported by this
587 List of bytes indicating which TLS versions are supported by this
587 target.
588 target.
588
589
589 By default, clients reflect the target order advertised by servers
590 By default, clients reflect the target order advertised by servers
590 and servers will use the first client-advertised target when picking
591 and servers will use the first client-advertised target when picking
591 a redirect target. So targets should be advertised in the order the
592 a redirect target. So targets should be advertised in the order the
592 server prefers they be used.
593 server prefers they be used.
593 """
594 """
594 return []
595 return []
595
596
596 def wireprotocommand(name, args=None, permission='push', cachekeyfn=None,
597 def wireprotocommand(name, args=None, permission='push', cachekeyfn=None,
597 extracapabilitiesfn=None):
598 extracapabilitiesfn=None):
598 """Decorator to declare a wire protocol command.
599 """Decorator to declare a wire protocol command.
599
600
600 ``name`` is the name of the wire protocol command being provided.
601 ``name`` is the name of the wire protocol command being provided.
601
602
602 ``args`` is a dict defining arguments accepted by the command. Keys are
603 ``args`` is a dict defining arguments accepted by the command. Keys are
603 the argument name. Values are dicts with the following keys:
604 the argument name. Values are dicts with the following keys:
604
605
605 ``type``
606 ``type``
606 The argument data type. Must be one of the following string
607 The argument data type. Must be one of the following string
607 literals: ``bytes``, ``int``, ``list``, ``dict``, ``set``,
608 literals: ``bytes``, ``int``, ``list``, ``dict``, ``set``,
608 or ``bool``.
609 or ``bool``.
609
610
610 ``default``
611 ``default``
611 A callable returning the default value for this argument. If not
612 A callable returning the default value for this argument. If not
612 specified, ``None`` will be the default value.
613 specified, ``None`` will be the default value.
613
614
614 ``example``
615 ``example``
615 An example value for this argument.
616 An example value for this argument.
616
617
617 ``validvalues``
618 ``validvalues``
618 Set of recognized values for this argument.
619 Set of recognized values for this argument.
619
620
620 ``permission`` defines the permission type needed to run this command.
621 ``permission`` defines the permission type needed to run this command.
621 Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
622 Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
622 respectively. Default is to assume command requires ``push`` permissions
623 respectively. Default is to assume command requires ``push`` permissions
623 because otherwise commands not declaring their permissions could modify
624 because otherwise commands not declaring their permissions could modify
624 a repository that is supposed to be read-only.
625 a repository that is supposed to be read-only.
625
626
626 ``cachekeyfn`` defines an optional callable that can derive the
627 ``cachekeyfn`` defines an optional callable that can derive the
627 cache key for this request.
628 cache key for this request.
628
629
629 ``extracapabilitiesfn`` defines an optional callable that defines extra
630 ``extracapabilitiesfn`` defines an optional callable that defines extra
630 command capabilities/parameters that are advertised next to the command
631 command capabilities/parameters that are advertised next to the command
631 in the capabilities data structure describing the server. The callable
632 in the capabilities data structure describing the server. The callable
632 receives as arguments the repository and protocol objects. It returns
633 receives as arguments the repository and protocol objects. It returns
633 a dict of extra fields to add to the command descriptor.
634 a dict of extra fields to add to the command descriptor.
634
635
635 Wire protocol commands are generators of objects to be serialized and
636 Wire protocol commands are generators of objects to be serialized and
636 sent to the client.
637 sent to the client.
637
638
638 If a command raises an uncaught exception, this will be translated into
639 If a command raises an uncaught exception, this will be translated into
639 a command error.
640 a command error.
640
641
641 All commands can opt in to being cacheable by defining a function
642 All commands can opt in to being cacheable by defining a function
642 (``cachekeyfn``) that is called to derive a cache key. This function
643 (``cachekeyfn``) that is called to derive a cache key. This function
643 receives the same arguments as the command itself plus a ``cacher``
644 receives the same arguments as the command itself plus a ``cacher``
644 argument containing the active cacher for the request and returns a bytes
645 argument containing the active cacher for the request and returns a bytes
645 containing the key in a cache the response to this command may be cached
646 containing the key in a cache the response to this command may be cached
646 under.
647 under.
647 """
648 """
648 transports = {k for k, v in wireprototypes.TRANSPORTS.items()
649 transports = {k for k, v in wireprototypes.TRANSPORTS.items()
649 if v['version'] == 2}
650 if v['version'] == 2}
650
651
651 if permission not in ('push', 'pull'):
652 if permission not in ('push', 'pull'):
652 raise error.ProgrammingError('invalid wire protocol permission; '
653 raise error.ProgrammingError('invalid wire protocol permission; '
653 'got %s; expected "push" or "pull"' %
654 'got %s; expected "push" or "pull"' %
654 permission)
655 permission)
655
656
656 if args is None:
657 if args is None:
657 args = {}
658 args = {}
658
659
659 if not isinstance(args, dict):
660 if not isinstance(args, dict):
660 raise error.ProgrammingError('arguments for version 2 commands '
661 raise error.ProgrammingError('arguments for version 2 commands '
661 'must be declared as dicts')
662 'must be declared as dicts')
662
663
663 for arg, meta in args.items():
664 for arg, meta in args.items():
664 if arg == '*':
665 if arg == '*':
665 raise error.ProgrammingError('* argument name not allowed on '
666 raise error.ProgrammingError('* argument name not allowed on '
666 'version 2 commands')
667 'version 2 commands')
667
668
668 if not isinstance(meta, dict):
669 if not isinstance(meta, dict):
669 raise error.ProgrammingError('arguments for version 2 commands '
670 raise error.ProgrammingError('arguments for version 2 commands '
670 'must declare metadata as a dict')
671 'must declare metadata as a dict')
671
672
672 if 'type' not in meta:
673 if 'type' not in meta:
673 raise error.ProgrammingError('%s argument for command %s does not '
674 raise error.ProgrammingError('%s argument for command %s does not '
674 'declare type field' % (arg, name))
675 'declare type field' % (arg, name))
675
676
676 if meta['type'] not in ('bytes', 'int', 'list', 'dict', 'set', 'bool'):
677 if meta['type'] not in ('bytes', 'int', 'list', 'dict', 'set', 'bool'):
677 raise error.ProgrammingError('%s argument for command %s has '
678 raise error.ProgrammingError('%s argument for command %s has '
678 'illegal type: %s' % (arg, name,
679 'illegal type: %s' % (arg, name,
679 meta['type']))
680 meta['type']))
680
681
681 if 'example' not in meta:
682 if 'example' not in meta:
682 raise error.ProgrammingError('%s argument for command %s does not '
683 raise error.ProgrammingError('%s argument for command %s does not '
683 'declare example field' % (arg, name))
684 'declare example field' % (arg, name))
684
685
685 meta['required'] = 'default' not in meta
686 meta['required'] = 'default' not in meta
686
687
687 meta.setdefault('default', lambda: None)
688 meta.setdefault('default', lambda: None)
688 meta.setdefault('validvalues', None)
689 meta.setdefault('validvalues', None)
689
690
690 def register(func):
691 def register(func):
691 if name in COMMANDS:
692 if name in COMMANDS:
692 raise error.ProgrammingError('%s command already registered '
693 raise error.ProgrammingError('%s command already registered '
693 'for version 2' % name)
694 'for version 2' % name)
694
695
695 COMMANDS[name] = wireprototypes.commandentry(
696 COMMANDS[name] = wireprototypes.commandentry(
696 func, args=args, transports=transports, permission=permission,
697 func, args=args, transports=transports, permission=permission,
697 cachekeyfn=cachekeyfn, extracapabilitiesfn=extracapabilitiesfn)
698 cachekeyfn=cachekeyfn, extracapabilitiesfn=extracapabilitiesfn)
698
699
699 return func
700 return func
700
701
701 return register
702 return register
702
703
703 def makecommandcachekeyfn(command, localversion=None, allargs=False):
704 def makecommandcachekeyfn(command, localversion=None, allargs=False):
704 """Construct a cache key derivation function with common features.
705 """Construct a cache key derivation function with common features.
705
706
706 By default, the cache key is a hash of:
707 By default, the cache key is a hash of:
707
708
708 * The command name.
709 * The command name.
709 * A global cache version number.
710 * A global cache version number.
710 * A local cache version number (passed via ``localversion``).
711 * A local cache version number (passed via ``localversion``).
711 * All the arguments passed to the command.
712 * All the arguments passed to the command.
712 * The media type used.
713 * The media type used.
713 * Wire protocol version string.
714 * Wire protocol version string.
714 * The repository path.
715 * The repository path.
715 """
716 """
716 if not allargs:
717 if not allargs:
717 raise error.ProgrammingError('only allargs=True is currently supported')
718 raise error.ProgrammingError('only allargs=True is currently supported')
718
719
719 if localversion is None:
720 if localversion is None:
720 raise error.ProgrammingError('must set localversion argument value')
721 raise error.ProgrammingError('must set localversion argument value')
721
722
722 def cachekeyfn(repo, proto, cacher, **args):
723 def cachekeyfn(repo, proto, cacher, **args):
723 spec = COMMANDS[command]
724 spec = COMMANDS[command]
724
725
725 # Commands that mutate the repo can not be cached.
726 # Commands that mutate the repo can not be cached.
726 if spec.permission == 'push':
727 if spec.permission == 'push':
727 return None
728 return None
728
729
729 # TODO config option to disable caching.
730 # TODO config option to disable caching.
730
731
731 # Our key derivation strategy is to construct a data structure
732 # Our key derivation strategy is to construct a data structure
732 # holding everything that could influence cacheability and to hash
733 # holding everything that could influence cacheability and to hash
733 # the CBOR representation of that. Using CBOR seems like it might
734 # the CBOR representation of that. Using CBOR seems like it might
734 # be overkill. However, simpler hashing mechanisms are prone to
735 # be overkill. However, simpler hashing mechanisms are prone to
735 # duplicate input issues. e.g. if you just concatenate two values,
736 # duplicate input issues. e.g. if you just concatenate two values,
736 # "foo"+"bar" is identical to "fo"+"obar". Using CBOR provides
737 # "foo"+"bar" is identical to "fo"+"obar". Using CBOR provides
737 # "padding" between values and prevents these problems.
738 # "padding" between values and prevents these problems.
738
739
739 # Seed the hash with various data.
740 # Seed the hash with various data.
740 state = {
741 state = {
741 # To invalidate all cache keys.
742 # To invalidate all cache keys.
742 b'globalversion': GLOBAL_CACHE_VERSION,
743 b'globalversion': GLOBAL_CACHE_VERSION,
743 # More granular cache key invalidation.
744 # More granular cache key invalidation.
744 b'localversion': localversion,
745 b'localversion': localversion,
745 # Cache keys are segmented by command.
746 # Cache keys are segmented by command.
746 b'command': command,
747 b'command': command,
747 # Throw in the media type and API version strings so changes
748 # Throw in the media type and API version strings so changes
748 # to exchange semantics invalid cache.
749 # to exchange semantics invalid cache.
749 b'mediatype': FRAMINGTYPE,
750 b'mediatype': FRAMINGTYPE,
750 b'version': HTTP_WIREPROTO_V2,
751 b'version': HTTP_WIREPROTO_V2,
751 # So same requests for different repos don't share cache keys.
752 # So same requests for different repos don't share cache keys.
752 b'repo': repo.root,
753 b'repo': repo.root,
753 }
754 }
754
755
755 # The arguments passed to us will have already been normalized.
756 # The arguments passed to us will have already been normalized.
756 # Default values will be set, etc. This is important because it
757 # Default values will be set, etc. This is important because it
757 # means that it doesn't matter if clients send an explicit argument
758 # means that it doesn't matter if clients send an explicit argument
758 # or rely on the default value: it will all normalize to the same
759 # or rely on the default value: it will all normalize to the same
759 # set of arguments on the server and therefore the same cache key.
760 # set of arguments on the server and therefore the same cache key.
760 #
761 #
761 # Arguments by their very nature must support being encoded to CBOR.
762 # Arguments by their very nature must support being encoded to CBOR.
762 # And the CBOR encoder is deterministic. So we hash the arguments
763 # And the CBOR encoder is deterministic. So we hash the arguments
763 # by feeding the CBOR of their representation into the hasher.
764 # by feeding the CBOR of their representation into the hasher.
764 if allargs:
765 if allargs:
765 state[b'args'] = pycompat.byteskwargs(args)
766 state[b'args'] = pycompat.byteskwargs(args)
766
767
767 cacher.adjustcachekeystate(state)
768 cacher.adjustcachekeystate(state)
768
769
769 hasher = hashlib.sha1()
770 hasher = hashlib.sha1()
770 for chunk in cborutil.streamencode(state):
771 for chunk in cborutil.streamencode(state):
771 hasher.update(chunk)
772 hasher.update(chunk)
772
773
773 return pycompat.sysbytes(hasher.hexdigest())
774 return pycompat.sysbytes(hasher.hexdigest())
774
775
775 return cachekeyfn
776 return cachekeyfn
776
777
777 def makeresponsecacher(repo, proto, command, args, objencoderfn,
778 def makeresponsecacher(repo, proto, command, args, objencoderfn,
778 redirecttargets, redirecthashes):
779 redirecttargets, redirecthashes):
779 """Construct a cacher for a cacheable command.
780 """Construct a cacher for a cacheable command.
780
781
781 Returns an ``iwireprotocolcommandcacher`` instance.
782 Returns an ``iwireprotocolcommandcacher`` instance.
782
783
783 Extensions can monkeypatch this function to provide custom caching
784 Extensions can monkeypatch this function to provide custom caching
784 backends.
785 backends.
785 """
786 """
786 return None
787 return None
787
788
788 def resolvenodes(repo, revisions):
789 def resolvenodes(repo, revisions):
789 """Resolve nodes from a revisions specifier data structure."""
790 """Resolve nodes from a revisions specifier data structure."""
790 cl = repo.changelog
791 cl = repo.changelog
791 clhasnode = cl.hasnode
792 clhasnode = cl.hasnode
792
793
793 seen = set()
794 seen = set()
794 nodes = []
795 nodes = []
795
796
796 if not isinstance(revisions, list):
797 if not isinstance(revisions, list):
797 raise error.WireprotoCommandError('revisions must be defined as an '
798 raise error.WireprotoCommandError('revisions must be defined as an '
798 'array')
799 'array')
799
800
800 for spec in revisions:
801 for spec in revisions:
801 if b'type' not in spec:
802 if b'type' not in spec:
802 raise error.WireprotoCommandError(
803 raise error.WireprotoCommandError(
803 'type key not present in revision specifier')
804 'type key not present in revision specifier')
804
805
805 typ = spec[b'type']
806 typ = spec[b'type']
806
807
807 if typ == b'changesetexplicit':
808 if typ == b'changesetexplicit':
808 if b'nodes' not in spec:
809 if b'nodes' not in spec:
809 raise error.WireprotoCommandError(
810 raise error.WireprotoCommandError(
810 'nodes key not present in changesetexplicit revision '
811 'nodes key not present in changesetexplicit revision '
811 'specifier')
812 'specifier')
812
813
813 for node in spec[b'nodes']:
814 for node in spec[b'nodes']:
814 if node not in seen:
815 if node not in seen:
815 nodes.append(node)
816 nodes.append(node)
816 seen.add(node)
817 seen.add(node)
817
818
818 elif typ == b'changesetexplicitdepth':
819 elif typ == b'changesetexplicitdepth':
819 for key in (b'nodes', b'depth'):
820 for key in (b'nodes', b'depth'):
820 if key not in spec:
821 if key not in spec:
821 raise error.WireprotoCommandError(
822 raise error.WireprotoCommandError(
822 '%s key not present in changesetexplicitdepth revision '
823 '%s key not present in changesetexplicitdepth revision '
823 'specifier', (key,))
824 'specifier', (key,))
824
825
825 for rev in repo.revs(b'ancestors(%ln, %s)', spec[b'nodes'],
826 for rev in repo.revs(b'ancestors(%ln, %s)', spec[b'nodes'],
826 spec[b'depth'] - 1):
827 spec[b'depth'] - 1):
827 node = cl.node(rev)
828 node = cl.node(rev)
828
829
829 if node not in seen:
830 if node not in seen:
830 nodes.append(node)
831 nodes.append(node)
831 seen.add(node)
832 seen.add(node)
832
833
833 elif typ == b'changesetdagrange':
834 elif typ == b'changesetdagrange':
834 for key in (b'roots', b'heads'):
835 for key in (b'roots', b'heads'):
835 if key not in spec:
836 if key not in spec:
836 raise error.WireprotoCommandError(
837 raise error.WireprotoCommandError(
837 '%s key not present in changesetdagrange revision '
838 '%s key not present in changesetdagrange revision '
838 'specifier', (key,))
839 'specifier', (key,))
839
840
840 if not spec[b'heads']:
841 if not spec[b'heads']:
841 raise error.WireprotoCommandError(
842 raise error.WireprotoCommandError(
842 'heads key in changesetdagrange cannot be empty')
843 'heads key in changesetdagrange cannot be empty')
843
844
844 if spec[b'roots']:
845 if spec[b'roots']:
845 common = [n for n in spec[b'roots'] if clhasnode(n)]
846 common = [n for n in spec[b'roots'] if clhasnode(n)]
846 else:
847 else:
847 common = [nullid]
848 common = [nullid]
848
849
849 for n in discovery.outgoing(repo, common, spec[b'heads']).missing:
850 for n in discovery.outgoing(repo, common, spec[b'heads']).missing:
850 if n not in seen:
851 if n not in seen:
851 nodes.append(n)
852 nodes.append(n)
852 seen.add(n)
853 seen.add(n)
853
854
854 else:
855 else:
855 raise error.WireprotoCommandError(
856 raise error.WireprotoCommandError(
856 'unknown revision specifier type: %s', (typ,))
857 'unknown revision specifier type: %s', (typ,))
857
858
858 return nodes
859 return nodes
859
860
860 @wireprotocommand('branchmap', permission='pull')
861 @wireprotocommand('branchmap', permission='pull')
861 def branchmapv2(repo, proto):
862 def branchmapv2(repo, proto):
862 yield {encoding.fromlocal(k): v
863 yield {encoding.fromlocal(k): v
863 for k, v in repo.branchmap().iteritems()}
864 for k, v in repo.branchmap().iteritems()}
864
865
865 @wireprotocommand('capabilities', permission='pull')
866 @wireprotocommand('capabilities', permission='pull')
866 def capabilitiesv2(repo, proto):
867 def capabilitiesv2(repo, proto):
867 yield _capabilitiesv2(repo, proto)
868 yield _capabilitiesv2(repo, proto)
868
869
869 @wireprotocommand(
870 @wireprotocommand(
870 'changesetdata',
871 'changesetdata',
871 args={
872 args={
872 'revisions': {
873 'revisions': {
873 'type': 'list',
874 'type': 'list',
874 'example': [{
875 'example': [{
875 b'type': b'changesetexplicit',
876 b'type': b'changesetexplicit',
876 b'nodes': [b'abcdef...'],
877 b'nodes': [b'abcdef...'],
877 }],
878 }],
878 },
879 },
879 'fields': {
880 'fields': {
880 'type': 'set',
881 'type': 'set',
881 'default': set,
882 'default': set,
882 'example': {b'parents', b'revision'},
883 'example': {b'parents', b'revision'},
883 'validvalues': {b'bookmarks', b'parents', b'phase', b'revision'},
884 'validvalues': {b'bookmarks', b'parents', b'phase', b'revision'},
884 },
885 },
885 },
886 },
886 permission='pull')
887 permission='pull')
887 def changesetdata(repo, proto, revisions, fields):
888 def changesetdata(repo, proto, revisions, fields):
888 # TODO look for unknown fields and abort when they can't be serviced.
889 # TODO look for unknown fields and abort when they can't be serviced.
889 # This could probably be validated by dispatcher using validvalues.
890 # This could probably be validated by dispatcher using validvalues.
890
891
891 cl = repo.changelog
892 cl = repo.changelog
892 outgoing = resolvenodes(repo, revisions)
893 outgoing = resolvenodes(repo, revisions)
893 publishing = repo.publishing()
894 publishing = repo.publishing()
894
895
895 if outgoing:
896 if outgoing:
896 repo.hook('preoutgoing', throw=True, source='serve')
897 repo.hook('preoutgoing', throw=True, source='serve')
897
898
898 yield {
899 yield {
899 b'totalitems': len(outgoing),
900 b'totalitems': len(outgoing),
900 }
901 }
901
902
902 # The phases of nodes already transferred to the client may have changed
903 # The phases of nodes already transferred to the client may have changed
903 # since the client last requested data. We send phase-only records
904 # since the client last requested data. We send phase-only records
904 # for these revisions, if requested.
905 # for these revisions, if requested.
905 # TODO actually do this. We'll probably want to emit phase heads
906 # TODO actually do this. We'll probably want to emit phase heads
906 # in the ancestry set of the outgoing revisions. This will ensure
907 # in the ancestry set of the outgoing revisions. This will ensure
907 # that phase updates within that set are seen.
908 # that phase updates within that set are seen.
908 if b'phase' in fields:
909 if b'phase' in fields:
909 pass
910 pass
910
911
911 nodebookmarks = {}
912 nodebookmarks = {}
912 for mark, node in repo._bookmarks.items():
913 for mark, node in repo._bookmarks.items():
913 nodebookmarks.setdefault(node, set()).add(mark)
914 nodebookmarks.setdefault(node, set()).add(mark)
914
915
915 # It is already topologically sorted by revision number.
916 # It is already topologically sorted by revision number.
916 for node in outgoing:
917 for node in outgoing:
917 d = {
918 d = {
918 b'node': node,
919 b'node': node,
919 }
920 }
920
921
921 if b'parents' in fields:
922 if b'parents' in fields:
922 d[b'parents'] = cl.parents(node)
923 d[b'parents'] = cl.parents(node)
923
924
924 if b'phase' in fields:
925 if b'phase' in fields:
925 if publishing:
926 if publishing:
926 d[b'phase'] = b'public'
927 d[b'phase'] = b'public'
927 else:
928 else:
928 ctx = repo[node]
929 ctx = repo[node]
929 d[b'phase'] = ctx.phasestr()
930 d[b'phase'] = ctx.phasestr()
930
931
931 if b'bookmarks' in fields and node in nodebookmarks:
932 if b'bookmarks' in fields and node in nodebookmarks:
932 d[b'bookmarks'] = sorted(nodebookmarks[node])
933 d[b'bookmarks'] = sorted(nodebookmarks[node])
933 del nodebookmarks[node]
934 del nodebookmarks[node]
934
935
935 followingmeta = []
936 followingmeta = []
936 followingdata = []
937 followingdata = []
937
938
938 if b'revision' in fields:
939 if b'revision' in fields:
939 revisiondata = cl.revision(node, raw=True)
940 revisiondata = cl.revision(node, raw=True)
940 followingmeta.append((b'revision', len(revisiondata)))
941 followingmeta.append((b'revision', len(revisiondata)))
941 followingdata.append(revisiondata)
942 followingdata.append(revisiondata)
942
943
943 # TODO make it possible for extensions to wrap a function or register
944 # TODO make it possible for extensions to wrap a function or register
944 # a handler to service custom fields.
945 # a handler to service custom fields.
945
946
946 if followingmeta:
947 if followingmeta:
947 d[b'fieldsfollowing'] = followingmeta
948 d[b'fieldsfollowing'] = followingmeta
948
949
949 yield d
950 yield d
950
951
951 for extra in followingdata:
952 for extra in followingdata:
952 yield extra
953 yield extra
953
954
954 # If requested, send bookmarks from nodes that didn't have revision
955 # If requested, send bookmarks from nodes that didn't have revision
955 # data sent so receiver is aware of any bookmark updates.
956 # data sent so receiver is aware of any bookmark updates.
956 if b'bookmarks' in fields:
957 if b'bookmarks' in fields:
957 for node, marks in sorted(nodebookmarks.iteritems()):
958 for node, marks in sorted(nodebookmarks.iteritems()):
958 yield {
959 yield {
959 b'node': node,
960 b'node': node,
960 b'bookmarks': sorted(marks),
961 b'bookmarks': sorted(marks),
961 }
962 }
962
963
963 class FileAccessError(Exception):
964 class FileAccessError(Exception):
964 """Represents an error accessing a specific file."""
965 """Represents an error accessing a specific file."""
965
966
966 def __init__(self, path, msg, args):
967 def __init__(self, path, msg, args):
967 self.path = path
968 self.path = path
968 self.msg = msg
969 self.msg = msg
969 self.args = args
970 self.args = args
970
971
971 def getfilestore(repo, proto, path):
972 def getfilestore(repo, proto, path):
972 """Obtain a file storage object for use with wire protocol.
973 """Obtain a file storage object for use with wire protocol.
973
974
974 Exists as a standalone function so extensions can monkeypatch to add
975 Exists as a standalone function so extensions can monkeypatch to add
975 access control.
976 access control.
976 """
977 """
977 # This seems to work even if the file doesn't exist. So catch
978 # This seems to work even if the file doesn't exist. So catch
978 # "empty" files and return an error.
979 # "empty" files and return an error.
979 fl = repo.file(path)
980 fl = repo.file(path)
980
981
981 if not len(fl):
982 if not len(fl):
982 raise FileAccessError(path, 'unknown file: %s', (path,))
983 raise FileAccessError(path, 'unknown file: %s', (path,))
983
984
984 return fl
985 return fl
985
986
986 def emitfilerevisions(repo, path, revisions, linknodes, fields):
987 def emitfilerevisions(repo, path, revisions, linknodes, fields):
987 for revision in revisions:
988 for revision in revisions:
988 d = {
989 d = {
989 b'node': revision.node,
990 b'node': revision.node,
990 }
991 }
991
992
992 if b'parents' in fields:
993 if b'parents' in fields:
993 d[b'parents'] = [revision.p1node, revision.p2node]
994 d[b'parents'] = [revision.p1node, revision.p2node]
994
995
995 if b'linknode' in fields:
996 if b'linknode' in fields:
996 d[b'linknode'] = linknodes[revision.node]
997 d[b'linknode'] = linknodes[revision.node]
997
998
998 followingmeta = []
999 followingmeta = []
999 followingdata = []
1000 followingdata = []
1000
1001
1001 if b'revision' in fields:
1002 if b'revision' in fields:
1002 if revision.revision is not None:
1003 if revision.revision is not None:
1003 followingmeta.append((b'revision', len(revision.revision)))
1004 followingmeta.append((b'revision', len(revision.revision)))
1004 followingdata.append(revision.revision)
1005 followingdata.append(revision.revision)
1005 else:
1006 else:
1006 d[b'deltabasenode'] = revision.basenode
1007 d[b'deltabasenode'] = revision.basenode
1007 followingmeta.append((b'delta', len(revision.delta)))
1008 followingmeta.append((b'delta', len(revision.delta)))
1008 followingdata.append(revision.delta)
1009 followingdata.append(revision.delta)
1009
1010
1010 if followingmeta:
1011 if followingmeta:
1011 d[b'fieldsfollowing'] = followingmeta
1012 d[b'fieldsfollowing'] = followingmeta
1012
1013
1013 yield d
1014 yield d
1014
1015
1015 for extra in followingdata:
1016 for extra in followingdata:
1016 yield extra
1017 yield extra
1017
1018
1018 def makefilematcher(repo, pathfilter):
1019 def makefilematcher(repo, pathfilter):
1019 """Construct a matcher from a path filter dict."""
1020 """Construct a matcher from a path filter dict."""
1020
1021
1021 # Validate values.
1022 # Validate values.
1022 if pathfilter:
1023 if pathfilter:
1023 for key in (b'include', b'exclude'):
1024 for key in (b'include', b'exclude'):
1024 for pattern in pathfilter.get(key, []):
1025 for pattern in pathfilter.get(key, []):
1025 if not pattern.startswith((b'path:', b'rootfilesin:')):
1026 if not pattern.startswith((b'path:', b'rootfilesin:')):
1026 raise error.WireprotoCommandError(
1027 raise error.WireprotoCommandError(
1027 '%s pattern must begin with `path:` or `rootfilesin:`; '
1028 '%s pattern must begin with `path:` or `rootfilesin:`; '
1028 'got %s', (key, pattern))
1029 'got %s', (key, pattern))
1029
1030
1030 if pathfilter:
1031 if pathfilter:
1031 matcher = matchmod.match(repo.root, b'',
1032 matcher = matchmod.match(repo.root, b'',
1032 include=pathfilter.get(b'include', []),
1033 include=pathfilter.get(b'include', []),
1033 exclude=pathfilter.get(b'exclude', []))
1034 exclude=pathfilter.get(b'exclude', []))
1034 else:
1035 else:
1035 matcher = matchmod.match(repo.root, b'')
1036 matcher = matchmod.match(repo.root, b'')
1036
1037
1037 # Requested patterns could include files not in the local store. So
1038 # Requested patterns could include files not in the local store. So
1038 # filter those out.
1039 # filter those out.
1039 return repo.narrowmatch(matcher)
1040 return repo.narrowmatch(matcher)
1040
1041
1041 @wireprotocommand(
1042 @wireprotocommand(
1042 'filedata',
1043 'filedata',
1043 args={
1044 args={
1044 'haveparents': {
1045 'haveparents': {
1045 'type': 'bool',
1046 'type': 'bool',
1046 'default': lambda: False,
1047 'default': lambda: False,
1047 'example': True,
1048 'example': True,
1048 },
1049 },
1049 'nodes': {
1050 'nodes': {
1050 'type': 'list',
1051 'type': 'list',
1051 'example': [b'0123456...'],
1052 'example': [b'0123456...'],
1052 },
1053 },
1053 'fields': {
1054 'fields': {
1054 'type': 'set',
1055 'type': 'set',
1055 'default': set,
1056 'default': set,
1056 'example': {b'parents', b'revision'},
1057 'example': {b'parents', b'revision'},
1057 'validvalues': {b'parents', b'revision', b'linknode'},
1058 'validvalues': {b'parents', b'revision', b'linknode'},
1058 },
1059 },
1059 'path': {
1060 'path': {
1060 'type': 'bytes',
1061 'type': 'bytes',
1061 'example': b'foo.txt',
1062 'example': b'foo.txt',
1062 }
1063 }
1063 },
1064 },
1064 permission='pull',
1065 permission='pull',
1065 # TODO censoring a file revision won't invalidate the cache.
1066 # TODO censoring a file revision won't invalidate the cache.
1066 # Figure out a way to take censoring into account when deriving
1067 # Figure out a way to take censoring into account when deriving
1067 # the cache key.
1068 # the cache key.
1068 cachekeyfn=makecommandcachekeyfn('filedata', 1, allargs=True))
1069 cachekeyfn=makecommandcachekeyfn('filedata', 1, allargs=True))
1069 def filedata(repo, proto, haveparents, nodes, fields, path):
1070 def filedata(repo, proto, haveparents, nodes, fields, path):
1070 # TODO this API allows access to file revisions that are attached to
1071 # TODO this API allows access to file revisions that are attached to
1071 # secret changesets. filesdata does not have this problem. Maybe this
1072 # secret changesets. filesdata does not have this problem. Maybe this
1072 # API should be deleted?
1073 # API should be deleted?
1073
1074
1074 try:
1075 try:
1075 # Extensions may wish to access the protocol handler.
1076 # Extensions may wish to access the protocol handler.
1076 store = getfilestore(repo, proto, path)
1077 store = getfilestore(repo, proto, path)
1077 except FileAccessError as e:
1078 except FileAccessError as e:
1078 raise error.WireprotoCommandError(e.msg, e.args)
1079 raise error.WireprotoCommandError(e.msg, e.args)
1079
1080
1080 clnode = repo.changelog.node
1081 clnode = repo.changelog.node
1081 linknodes = {}
1082 linknodes = {}
1082
1083
1083 # Validate requested nodes.
1084 # Validate requested nodes.
1084 for node in nodes:
1085 for node in nodes:
1085 try:
1086 try:
1086 store.rev(node)
1087 store.rev(node)
1087 except error.LookupError:
1088 except error.LookupError:
1088 raise error.WireprotoCommandError('unknown file node: %s',
1089 raise error.WireprotoCommandError('unknown file node: %s',
1089 (hex(node),))
1090 (hex(node),))
1090
1091
1091 # TODO by creating the filectx against a specific file revision
1092 # TODO by creating the filectx against a specific file revision
1092 # instead of changeset, linkrev() is always used. This is wrong for
1093 # instead of changeset, linkrev() is always used. This is wrong for
1093 # cases where linkrev() may refer to a hidden changeset. But since this
1094 # cases where linkrev() may refer to a hidden changeset. But since this
1094 # API doesn't know anything about changesets, we're not sure how to
1095 # API doesn't know anything about changesets, we're not sure how to
1095 # disambiguate the linknode. Perhaps we should delete this API?
1096 # disambiguate the linknode. Perhaps we should delete this API?
1096 fctx = repo.filectx(path, fileid=node)
1097 fctx = repo.filectx(path, fileid=node)
1097 linknodes[node] = clnode(fctx.introrev())
1098 linknodes[node] = clnode(fctx.introrev())
1098
1099
1099 revisions = store.emitrevisions(nodes,
1100 revisions = store.emitrevisions(nodes,
1100 revisiondata=b'revision' in fields,
1101 revisiondata=b'revision' in fields,
1101 assumehaveparentrevisions=haveparents)
1102 assumehaveparentrevisions=haveparents)
1102
1103
1103 yield {
1104 yield {
1104 b'totalitems': len(nodes),
1105 b'totalitems': len(nodes),
1105 }
1106 }
1106
1107
1107 for o in emitfilerevisions(repo, path, revisions, linknodes, fields):
1108 for o in emitfilerevisions(repo, path, revisions, linknodes, fields):
1108 yield o
1109 yield o
1109
1110
1110 def filesdatacapabilities(repo, proto):
1111 def filesdatacapabilities(repo, proto):
1111 batchsize = repo.ui.configint(
1112 batchsize = repo.ui.configint(
1112 b'experimental', b'server.filesdata.recommended-batch-size')
1113 b'experimental', b'server.filesdata.recommended-batch-size')
1113 return {
1114 return {
1114 b'recommendedbatchsize': batchsize,
1115 b'recommendedbatchsize': batchsize,
1115 }
1116 }
1116
1117
1117 @wireprotocommand(
1118 @wireprotocommand(
1118 'filesdata',
1119 'filesdata',
1119 args={
1120 args={
1120 'haveparents': {
1121 'haveparents': {
1121 'type': 'bool',
1122 'type': 'bool',
1122 'default': lambda: False,
1123 'default': lambda: False,
1123 'example': True,
1124 'example': True,
1124 },
1125 },
1125 'fields': {
1126 'fields': {
1126 'type': 'set',
1127 'type': 'set',
1127 'default': set,
1128 'default': set,
1128 'example': {b'parents', b'revision'},
1129 'example': {b'parents', b'revision'},
1129 'validvalues': {b'firstchangeset', b'linknode', b'parents',
1130 'validvalues': {b'firstchangeset', b'linknode', b'parents',
1130 b'revision'},
1131 b'revision'},
1131 },
1132 },
1132 'pathfilter': {
1133 'pathfilter': {
1133 'type': 'dict',
1134 'type': 'dict',
1134 'default': lambda: None,
1135 'default': lambda: None,
1135 'example': {b'include': [b'path:tests']},
1136 'example': {b'include': [b'path:tests']},
1136 },
1137 },
1137 'revisions': {
1138 'revisions': {
1138 'type': 'list',
1139 'type': 'list',
1139 'example': [{
1140 'example': [{
1140 b'type': b'changesetexplicit',
1141 b'type': b'changesetexplicit',
1141 b'nodes': [b'abcdef...'],
1142 b'nodes': [b'abcdef...'],
1142 }],
1143 }],
1143 },
1144 },
1144 },
1145 },
1145 permission='pull',
1146 permission='pull',
1146 # TODO censoring a file revision won't invalidate the cache.
1147 # TODO censoring a file revision won't invalidate the cache.
1147 # Figure out a way to take censoring into account when deriving
1148 # Figure out a way to take censoring into account when deriving
1148 # the cache key.
1149 # the cache key.
1149 cachekeyfn=makecommandcachekeyfn('filesdata', 1, allargs=True),
1150 cachekeyfn=makecommandcachekeyfn('filesdata', 1, allargs=True),
1150 extracapabilitiesfn=filesdatacapabilities)
1151 extracapabilitiesfn=filesdatacapabilities)
1151 def filesdata(repo, proto, haveparents, fields, pathfilter, revisions):
1152 def filesdata(repo, proto, haveparents, fields, pathfilter, revisions):
1152 # TODO This should operate on a repo that exposes obsolete changesets. There
1153 # TODO This should operate on a repo that exposes obsolete changesets. There
1153 # is a race between a client making a push that obsoletes a changeset and
1154 # is a race between a client making a push that obsoletes a changeset and
1154 # another client fetching files data for that changeset. If a client has a
1155 # another client fetching files data for that changeset. If a client has a
1155 # changeset, it should probably be allowed to access files data for that
1156 # changeset, it should probably be allowed to access files data for that
1156 # changeset.
1157 # changeset.
1157
1158
1158 outgoing = resolvenodes(repo, revisions)
1159 outgoing = resolvenodes(repo, revisions)
1159 filematcher = makefilematcher(repo, pathfilter)
1160 filematcher = makefilematcher(repo, pathfilter)
1160
1161
1161 # path -> {fnode: linknode}
1162 # path -> {fnode: linknode}
1162 fnodes = collections.defaultdict(dict)
1163 fnodes = collections.defaultdict(dict)
1163
1164
1164 # We collect the set of relevant file revisions by iterating the changeset
1165 # We collect the set of relevant file revisions by iterating the changeset
1165 # revisions and either walking the set of files recorded in the changeset
1166 # revisions and either walking the set of files recorded in the changeset
1166 # or by walking the manifest at that revision. There is probably room for a
1167 # or by walking the manifest at that revision. There is probably room for a
1167 # storage-level API to request this data, as it can be expensive to compute
1168 # storage-level API to request this data, as it can be expensive to compute
1168 # and would benefit from caching or alternate storage from what revlogs
1169 # and would benefit from caching or alternate storage from what revlogs
1169 # provide.
1170 # provide.
1170 for node in outgoing:
1171 for node in outgoing:
1171 ctx = repo[node]
1172 ctx = repo[node]
1172 mctx = ctx.manifestctx()
1173 mctx = ctx.manifestctx()
1173 md = mctx.read()
1174 md = mctx.read()
1174
1175
1175 if haveparents:
1176 if haveparents:
1176 checkpaths = ctx.files()
1177 checkpaths = ctx.files()
1177 else:
1178 else:
1178 checkpaths = md.keys()
1179 checkpaths = md.keys()
1179
1180
1180 for path in checkpaths:
1181 for path in checkpaths:
1181 fnode = md[path]
1182 fnode = md[path]
1182
1183
1183 if path in fnodes and fnode in fnodes[path]:
1184 if path in fnodes and fnode in fnodes[path]:
1184 continue
1185 continue
1185
1186
1186 if not filematcher(path):
1187 if not filematcher(path):
1187 continue
1188 continue
1188
1189
1189 fnodes[path].setdefault(fnode, node)
1190 fnodes[path].setdefault(fnode, node)
1190
1191
1191 yield {
1192 yield {
1192 b'totalpaths': len(fnodes),
1193 b'totalpaths': len(fnodes),
1193 b'totalitems': sum(len(v) for v in fnodes.values())
1194 b'totalitems': sum(len(v) for v in fnodes.values())
1194 }
1195 }
1195
1196
1196 for path, filenodes in sorted(fnodes.items()):
1197 for path, filenodes in sorted(fnodes.items()):
1197 try:
1198 try:
1198 store = getfilestore(repo, proto, path)
1199 store = getfilestore(repo, proto, path)
1199 except FileAccessError as e:
1200 except FileAccessError as e:
1200 raise error.WireprotoCommandError(e.msg, e.args)
1201 raise error.WireprotoCommandError(e.msg, e.args)
1201
1202
1202 yield {
1203 yield {
1203 b'path': path,
1204 b'path': path,
1204 b'totalitems': len(filenodes),
1205 b'totalitems': len(filenodes),
1205 }
1206 }
1206
1207
1207 revisions = store.emitrevisions(filenodes.keys(),
1208 revisions = store.emitrevisions(filenodes.keys(),
1208 revisiondata=b'revision' in fields,
1209 revisiondata=b'revision' in fields,
1209 assumehaveparentrevisions=haveparents)
1210 assumehaveparentrevisions=haveparents)
1210
1211
1211 for o in emitfilerevisions(repo, path, revisions, filenodes, fields):
1212 for o in emitfilerevisions(repo, path, revisions, filenodes, fields):
1212 yield o
1213 yield o
1213
1214
1214 @wireprotocommand(
1215 @wireprotocommand(
1215 'heads',
1216 'heads',
1216 args={
1217 args={
1217 'publiconly': {
1218 'publiconly': {
1218 'type': 'bool',
1219 'type': 'bool',
1219 'default': lambda: False,
1220 'default': lambda: False,
1220 'example': False,
1221 'example': False,
1221 },
1222 },
1222 },
1223 },
1223 permission='pull')
1224 permission='pull')
1224 def headsv2(repo, proto, publiconly):
1225 def headsv2(repo, proto, publiconly):
1225 if publiconly:
1226 if publiconly:
1226 repo = repo.filtered('immutable')
1227 repo = repo.filtered('immutable')
1227
1228
1228 yield repo.heads()
1229 yield repo.heads()
1229
1230
1230 @wireprotocommand(
1231 @wireprotocommand(
1231 'known',
1232 'known',
1232 args={
1233 args={
1233 'nodes': {
1234 'nodes': {
1234 'type': 'list',
1235 'type': 'list',
1235 'default': list,
1236 'default': list,
1236 'example': [b'deadbeef'],
1237 'example': [b'deadbeef'],
1237 },
1238 },
1238 },
1239 },
1239 permission='pull')
1240 permission='pull')
1240 def knownv2(repo, proto, nodes):
1241 def knownv2(repo, proto, nodes):
1241 result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
1242 result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
1242 yield result
1243 yield result
1243
1244
1244 @wireprotocommand(
1245 @wireprotocommand(
1245 'listkeys',
1246 'listkeys',
1246 args={
1247 args={
1247 'namespace': {
1248 'namespace': {
1248 'type': 'bytes',
1249 'type': 'bytes',
1249 'example': b'ns',
1250 'example': b'ns',
1250 },
1251 },
1251 },
1252 },
1252 permission='pull')
1253 permission='pull')
1253 def listkeysv2(repo, proto, namespace):
1254 def listkeysv2(repo, proto, namespace):
1254 keys = repo.listkeys(encoding.tolocal(namespace))
1255 keys = repo.listkeys(encoding.tolocal(namespace))
1255 keys = {encoding.fromlocal(k): encoding.fromlocal(v)
1256 keys = {encoding.fromlocal(k): encoding.fromlocal(v)
1256 for k, v in keys.iteritems()}
1257 for k, v in keys.iteritems()}
1257
1258
1258 yield keys
1259 yield keys
1259
1260
1260 @wireprotocommand(
1261 @wireprotocommand(
1261 'lookup',
1262 'lookup',
1262 args={
1263 args={
1263 'key': {
1264 'key': {
1264 'type': 'bytes',
1265 'type': 'bytes',
1265 'example': b'foo',
1266 'example': b'foo',
1266 },
1267 },
1267 },
1268 },
1268 permission='pull')
1269 permission='pull')
1269 def lookupv2(repo, proto, key):
1270 def lookupv2(repo, proto, key):
1270 key = encoding.tolocal(key)
1271 key = encoding.tolocal(key)
1271
1272
1272 # TODO handle exception.
1273 # TODO handle exception.
1273 node = repo.lookup(key)
1274 node = repo.lookup(key)
1274
1275
1275 yield node
1276 yield node
1276
1277
1277 def manifestdatacapabilities(repo, proto):
1278 def manifestdatacapabilities(repo, proto):
1278 batchsize = repo.ui.configint(
1279 batchsize = repo.ui.configint(
1279 b'experimental', b'server.manifestdata.recommended-batch-size')
1280 b'experimental', b'server.manifestdata.recommended-batch-size')
1280
1281
1281 return {
1282 return {
1282 b'recommendedbatchsize': batchsize,
1283 b'recommendedbatchsize': batchsize,
1283 }
1284 }
1284
1285
1285 @wireprotocommand(
1286 @wireprotocommand(
1286 'manifestdata',
1287 'manifestdata',
1287 args={
1288 args={
1288 'nodes': {
1289 'nodes': {
1289 'type': 'list',
1290 'type': 'list',
1290 'example': [b'0123456...'],
1291 'example': [b'0123456...'],
1291 },
1292 },
1292 'haveparents': {
1293 'haveparents': {
1293 'type': 'bool',
1294 'type': 'bool',
1294 'default': lambda: False,
1295 'default': lambda: False,
1295 'example': True,
1296 'example': True,
1296 },
1297 },
1297 'fields': {
1298 'fields': {
1298 'type': 'set',
1299 'type': 'set',
1299 'default': set,
1300 'default': set,
1300 'example': {b'parents', b'revision'},
1301 'example': {b'parents', b'revision'},
1301 'validvalues': {b'parents', b'revision'},
1302 'validvalues': {b'parents', b'revision'},
1302 },
1303 },
1303 'tree': {
1304 'tree': {
1304 'type': 'bytes',
1305 'type': 'bytes',
1305 'example': b'',
1306 'example': b'',
1306 },
1307 },
1307 },
1308 },
1308 permission='pull',
1309 permission='pull',
1309 cachekeyfn=makecommandcachekeyfn('manifestdata', 1, allargs=True),
1310 cachekeyfn=makecommandcachekeyfn('manifestdata', 1, allargs=True),
1310 extracapabilitiesfn=manifestdatacapabilities)
1311 extracapabilitiesfn=manifestdatacapabilities)
1311 def manifestdata(repo, proto, haveparents, nodes, fields, tree):
1312 def manifestdata(repo, proto, haveparents, nodes, fields, tree):
1312 store = repo.manifestlog.getstorage(tree)
1313 store = repo.manifestlog.getstorage(tree)
1313
1314
1314 # Validate the node is known and abort on unknown revisions.
1315 # Validate the node is known and abort on unknown revisions.
1315 for node in nodes:
1316 for node in nodes:
1316 try:
1317 try:
1317 store.rev(node)
1318 store.rev(node)
1318 except error.LookupError:
1319 except error.LookupError:
1319 raise error.WireprotoCommandError(
1320 raise error.WireprotoCommandError(
1320 'unknown node: %s', (node,))
1321 'unknown node: %s', (node,))
1321
1322
1322 revisions = store.emitrevisions(nodes,
1323 revisions = store.emitrevisions(nodes,
1323 revisiondata=b'revision' in fields,
1324 revisiondata=b'revision' in fields,
1324 assumehaveparentrevisions=haveparents)
1325 assumehaveparentrevisions=haveparents)
1325
1326
1326 yield {
1327 yield {
1327 b'totalitems': len(nodes),
1328 b'totalitems': len(nodes),
1328 }
1329 }
1329
1330
1330 for revision in revisions:
1331 for revision in revisions:
1331 d = {
1332 d = {
1332 b'node': revision.node,
1333 b'node': revision.node,
1333 }
1334 }
1334
1335
1335 if b'parents' in fields:
1336 if b'parents' in fields:
1336 d[b'parents'] = [revision.p1node, revision.p2node]
1337 d[b'parents'] = [revision.p1node, revision.p2node]
1337
1338
1338 followingmeta = []
1339 followingmeta = []
1339 followingdata = []
1340 followingdata = []
1340
1341
1341 if b'revision' in fields:
1342 if b'revision' in fields:
1342 if revision.revision is not None:
1343 if revision.revision is not None:
1343 followingmeta.append((b'revision', len(revision.revision)))
1344 followingmeta.append((b'revision', len(revision.revision)))
1344 followingdata.append(revision.revision)
1345 followingdata.append(revision.revision)
1345 else:
1346 else:
1346 d[b'deltabasenode'] = revision.basenode
1347 d[b'deltabasenode'] = revision.basenode
1347 followingmeta.append((b'delta', len(revision.delta)))
1348 followingmeta.append((b'delta', len(revision.delta)))
1348 followingdata.append(revision.delta)
1349 followingdata.append(revision.delta)
1349
1350
1350 if followingmeta:
1351 if followingmeta:
1351 d[b'fieldsfollowing'] = followingmeta
1352 d[b'fieldsfollowing'] = followingmeta
1352
1353
1353 yield d
1354 yield d
1354
1355
1355 for extra in followingdata:
1356 for extra in followingdata:
1356 yield extra
1357 yield extra
1357
1358
1358 @wireprotocommand(
1359 @wireprotocommand(
1359 'pushkey',
1360 'pushkey',
1360 args={
1361 args={
1361 'namespace': {
1362 'namespace': {
1362 'type': 'bytes',
1363 'type': 'bytes',
1363 'example': b'ns',
1364 'example': b'ns',
1364 },
1365 },
1365 'key': {
1366 'key': {
1366 'type': 'bytes',
1367 'type': 'bytes',
1367 'example': b'key',
1368 'example': b'key',
1368 },
1369 },
1369 'old': {
1370 'old': {
1370 'type': 'bytes',
1371 'type': 'bytes',
1371 'example': b'old',
1372 'example': b'old',
1372 },
1373 },
1373 'new': {
1374 'new': {
1374 'type': 'bytes',
1375 'type': 'bytes',
1375 'example': 'new',
1376 'example': 'new',
1376 },
1377 },
1377 },
1378 },
1378 permission='push')
1379 permission='push')
1379 def pushkeyv2(repo, proto, namespace, key, old, new):
1380 def pushkeyv2(repo, proto, namespace, key, old, new):
1380 # TODO handle ui output redirection
1381 # TODO handle ui output redirection
1381 yield repo.pushkey(encoding.tolocal(namespace),
1382 yield repo.pushkey(encoding.tolocal(namespace),
1382 encoding.tolocal(key),
1383 encoding.tolocal(key),
1383 encoding.tolocal(old),
1384 encoding.tolocal(old),
1384 encoding.tolocal(new))
1385 encoding.tolocal(new))
1385
1386
1386
1387
1387 @wireprotocommand(
1388 @wireprotocommand(
1388 'rawstorefiledata',
1389 'rawstorefiledata',
1389 args={
1390 args={
1390 'files': {
1391 'files': {
1391 'type': 'list',
1392 'type': 'list',
1392 'example': [b'changelog', b'manifestlog'],
1393 'example': [b'changelog', b'manifestlog'],
1393 },
1394 },
1394 'pathfilter': {
1395 'pathfilter': {
1395 'type': 'list',
1396 'type': 'list',
1396 'default': lambda: None,
1397 'default': lambda: None,
1397 'example': {b'include': [b'path:tests']},
1398 'example': {b'include': [b'path:tests']},
1398 },
1399 },
1399 },
1400 },
1400 permission='pull')
1401 permission='pull')
1401 def rawstorefiledata(repo, proto, files, pathfilter):
1402 def rawstorefiledata(repo, proto, files, pathfilter):
1402 if not streamclone.allowservergeneration(repo):
1403 if not streamclone.allowservergeneration(repo):
1403 raise error.WireprotoCommandError(b'stream clone is disabled')
1404 raise error.WireprotoCommandError(b'stream clone is disabled')
1404
1405
1405 # TODO support dynamically advertising what store files "sets" are
1406 # TODO support dynamically advertising what store files "sets" are
1406 # available. For now, we support changelog, manifestlog, and files.
1407 # available. For now, we support changelog, manifestlog, and files.
1407 files = set(files)
1408 files = set(files)
1408 allowedfiles = {b'changelog', b'manifestlog'}
1409 allowedfiles = {b'changelog', b'manifestlog'}
1409
1410
1410 unsupported = files - allowedfiles
1411 unsupported = files - allowedfiles
1411 if unsupported:
1412 if unsupported:
1412 raise error.WireprotoCommandError(b'unknown file type: %s',
1413 raise error.WireprotoCommandError(b'unknown file type: %s',
1413 (b', '.join(sorted(unsupported)),))
1414 (b', '.join(sorted(unsupported)),))
1414
1415
1415 with repo.lock():
1416 with repo.lock():
1416 topfiles = list(repo.store.topfiles())
1417 topfiles = list(repo.store.topfiles())
1417
1418
1418 sendfiles = []
1419 sendfiles = []
1419 totalsize = 0
1420 totalsize = 0
1420
1421
1421 # TODO this is a bunch of storage layer interface abstractions because
1422 # TODO this is a bunch of storage layer interface abstractions because
1422 # it assumes revlogs.
1423 # it assumes revlogs.
1423 for name, encodedname, size in topfiles:
1424 for name, encodedname, size in topfiles:
1424 if b'changelog' in files and name.startswith(b'00changelog'):
1425 if b'changelog' in files and name.startswith(b'00changelog'):
1425 pass
1426 pass
1426 elif b'manifestlog' in files and name.startswith(b'00manifest'):
1427 elif b'manifestlog' in files and name.startswith(b'00manifest'):
1427 pass
1428 pass
1428 else:
1429 else:
1429 continue
1430 continue
1430
1431
1431 sendfiles.append((b'store', name, size))
1432 sendfiles.append((b'store', name, size))
1432 totalsize += size
1433 totalsize += size
1433
1434
1434 yield {
1435 yield {
1435 b'filecount': len(sendfiles),
1436 b'filecount': len(sendfiles),
1436 b'totalsize': totalsize,
1437 b'totalsize': totalsize,
1437 }
1438 }
1438
1439
1439 for location, name, size in sendfiles:
1440 for location, name, size in sendfiles:
1440 yield {
1441 yield {
1441 b'location': location,
1442 b'location': location,
1442 b'path': name,
1443 b'path': name,
1443 b'size': size,
1444 b'size': size,
1444 }
1445 }
1445
1446
1446 # We have to use a closure for this to ensure the context manager is
1447 # We have to use a closure for this to ensure the context manager is
1447 # closed only after sending the final chunk.
1448 # closed only after sending the final chunk.
1448 def getfiledata():
1449 def getfiledata():
1449 with repo.svfs(name, 'rb', auditpath=False) as fh:
1450 with repo.svfs(name, 'rb', auditpath=False) as fh:
1450 for chunk in util.filechunkiter(fh, limit=size):
1451 for chunk in util.filechunkiter(fh, limit=size):
1451 yield chunk
1452 yield chunk
1452
1453
1453 yield wireprototypes.indefinitebytestringresponse(
1454 yield wireprototypes.indefinitebytestringresponse(
1454 getfiledata())
1455 getfiledata())
@@ -1,112 +1,115
1 from __future__ import absolute_import, print_function
1 from __future__ import absolute_import, print_function
2
2
3 import sys
3 import sys
4
4
5 from mercurial import (
5 from mercurial import (
6 error,
6 error,
7 pycompat,
7 pycompat,
8 ui as uimod,
8 ui as uimod,
9 util,
9 util,
10 wireprototypes,
10 wireprototypes,
11 wireprotov1peer,
11 wireprotov1peer,
12 wireprotov1server,
12 wireprotov1server,
13 )
13 )
14 from mercurial.utils import (
14 from mercurial.utils import (
15 stringutil,
15 stringutil,
16 )
16 )
17 stringio = util.stringio
17 stringio = util.stringio
18
18
19 class proto(object):
19 class proto(object):
20 def __init__(self, args):
20 def __init__(self, args):
21 self.args = args
21 self.args = args
22 self.name = 'dummyproto'
22 self.name = 'dummyproto'
23
23
24 def getargs(self, spec):
24 def getargs(self, spec):
25 args = self.args
25 args = self.args
26 args.setdefault(b'*', {})
26 args.setdefault(b'*', {})
27 names = spec.split()
27 names = spec.split()
28 return [args[n] for n in names]
28 return [args[n] for n in names]
29
29
30 def checkperm(self, perm):
30 def checkperm(self, perm):
31 pass
31 pass
32
32
33 wireprototypes.TRANSPORTS['dummyproto'] = {
33 wireprototypes.TRANSPORTS['dummyproto'] = {
34 'transport': 'dummy',
34 'transport': 'dummy',
35 'version': 1,
35 'version': 1,
36 }
36 }
37
37
38 class clientpeer(wireprotov1peer.wirepeer):
38 class clientpeer(wireprotov1peer.wirepeer):
39 def __init__(self, serverrepo, ui):
39 def __init__(self, serverrepo, ui):
40 self.serverrepo = serverrepo
40 self.serverrepo = serverrepo
41 self.ui = ui
41 self.ui = ui
42
42
43 def url(self):
43 def url(self):
44 return b'test'
44 return b'test'
45
45
46 def local(self):
46 def local(self):
47 return None
47 return None
48
48
49 def peer(self):
49 def peer(self):
50 return self
50 return self
51
51
52 def canpush(self):
52 def canpush(self):
53 return True
53 return True
54
54
55 def close(self):
55 def close(self):
56 pass
56 pass
57
57
58 def capabilities(self):
58 def capabilities(self):
59 return [b'batch']
59 return [b'batch']
60
60
61 def _call(self, cmd, **args):
61 def _call(self, cmd, **args):
62 args = pycompat.byteskwargs(args)
62 args = pycompat.byteskwargs(args)
63 res = wireprotov1server.dispatch(self.serverrepo, proto(args), cmd)
63 res = wireprotov1server.dispatch(self.serverrepo, proto(args), cmd)
64 if isinstance(res, wireprototypes.bytesresponse):
64 if isinstance(res, wireprototypes.bytesresponse):
65 return res.data
65 return res.data
66 elif isinstance(res, bytes):
66 elif isinstance(res, bytes):
67 return res
67 return res
68 else:
68 else:
69 raise error.Abort('dummy client does not support response type')
69 raise error.Abort('dummy client does not support response type')
70
70
71 def _callstream(self, cmd, **args):
71 def _callstream(self, cmd, **args):
72 return stringio(self._call(cmd, **args))
72 return stringio(self._call(cmd, **args))
73
73
74 @wireprotov1peer.batchable
74 @wireprotov1peer.batchable
75 def greet(self, name):
75 def greet(self, name):
76 f = wireprotov1peer.future()
76 f = wireprotov1peer.future()
77 yield {b'name': mangle(name)}, f
77 yield {b'name': mangle(name)}, f
78 yield unmangle(f.value)
78 yield unmangle(f.value)
79
79
80 class serverrepo(object):
80 class serverrepo(object):
81 def __init__(self, ui):
82 self.ui = ui
83
81 def greet(self, name):
84 def greet(self, name):
82 return b"Hello, " + name
85 return b"Hello, " + name
83
86
84 def filtered(self, name):
87 def filtered(self, name):
85 return self
88 return self
86
89
87 def mangle(s):
90 def mangle(s):
88 return b''.join(pycompat.bytechr(ord(c) + 1) for c in pycompat.bytestr(s))
91 return b''.join(pycompat.bytechr(ord(c) + 1) for c in pycompat.bytestr(s))
89 def unmangle(s):
92 def unmangle(s):
90 return b''.join(pycompat.bytechr(ord(c) - 1) for c in pycompat.bytestr(s))
93 return b''.join(pycompat.bytechr(ord(c) - 1) for c in pycompat.bytestr(s))
91
94
92 def greet(repo, proto, name):
95 def greet(repo, proto, name):
93 return mangle(repo.greet(unmangle(name)))
96 return mangle(repo.greet(unmangle(name)))
94
97
95 wireprotov1server.commands[b'greet'] = (greet, b'name')
98 wireprotov1server.commands[b'greet'] = (greet, b'name')
96
99
97 srv = serverrepo()
100 srv = serverrepo(uimod.ui())
98 clt = clientpeer(srv, uimod.ui())
101 clt = clientpeer(srv, uimod.ui())
99
102
100 def printb(data, end=b'\n'):
103 def printb(data, end=b'\n'):
101 out = getattr(sys.stdout, 'buffer', sys.stdout)
104 out = getattr(sys.stdout, 'buffer', sys.stdout)
102 out.write(data + end)
105 out.write(data + end)
103 out.flush()
106 out.flush()
104
107
105 printb(clt.greet(b"Foobar"))
108 printb(clt.greet(b"Foobar"))
106
109
107 with clt.commandexecutor() as e:
110 with clt.commandexecutor() as e:
108 fgreet1 = e.callcommand(b'greet', {b'name': b'Fo, =;:<o'})
111 fgreet1 = e.callcommand(b'greet', {b'name': b'Fo, =;:<o'})
109 fgreet2 = e.callcommand(b'greet', {b'name': b'Bar'})
112 fgreet2 = e.callcommand(b'greet', {b'name': b'Bar'})
110
113
111 printb(stringutil.pprint([f.result() for f in (fgreet1, fgreet2)],
114 printb(stringutil.pprint([f.result() for f in (fgreet1, fgreet2)],
112 bprefix=True))
115 bprefix=True))
General Comments 0
You need to be logged in to leave comments. Login now