##// END OF EJS Templates
compression: introduce an official `format.revlog-compression` option...
marmoute -
r42213:4ee906aa default
parent child Browse files
Show More
@@ -1,1473 +1,1474 b''
1 # configitems.py - centralized declaration of configuration option
1 # configitems.py - centralized declaration of configuration option
2 #
2 #
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import functools
10 import functools
11 import re
11 import re
12
12
13 from . import (
13 from . import (
14 encoding,
14 encoding,
15 error,
15 error,
16 )
16 )
17
17
18 def loadconfigtable(ui, extname, configtable):
18 def loadconfigtable(ui, extname, configtable):
19 """update config item known to the ui with the extension ones"""
19 """update config item known to the ui with the extension ones"""
20 for section, items in sorted(configtable.items()):
20 for section, items in sorted(configtable.items()):
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
22 knownkeys = set(knownitems)
22 knownkeys = set(knownitems)
23 newkeys = set(items)
23 newkeys = set(items)
24 for key in sorted(knownkeys & newkeys):
24 for key in sorted(knownkeys & newkeys):
25 msg = "extension '%s' overwrite config item '%s.%s'"
25 msg = "extension '%s' overwrite config item '%s.%s'"
26 msg %= (extname, section, key)
26 msg %= (extname, section, key)
27 ui.develwarn(msg, config='warn-config')
27 ui.develwarn(msg, config='warn-config')
28
28
29 knownitems.update(items)
29 knownitems.update(items)
30
30
31 class configitem(object):
31 class configitem(object):
32 """represent a known config item
32 """represent a known config item
33
33
34 :section: the official config section where to find this item,
34 :section: the official config section where to find this item,
35 :name: the official name within the section,
35 :name: the official name within the section,
36 :default: default value for this item,
36 :default: default value for this item,
37 :alias: optional list of tuples as alternatives,
37 :alias: optional list of tuples as alternatives,
38 :generic: this is a generic definition, match name using regular expression.
38 :generic: this is a generic definition, match name using regular expression.
39 """
39 """
40
40
41 def __init__(self, section, name, default=None, alias=(),
41 def __init__(self, section, name, default=None, alias=(),
42 generic=False, priority=0):
42 generic=False, priority=0):
43 self.section = section
43 self.section = section
44 self.name = name
44 self.name = name
45 self.default = default
45 self.default = default
46 self.alias = list(alias)
46 self.alias = list(alias)
47 self.generic = generic
47 self.generic = generic
48 self.priority = priority
48 self.priority = priority
49 self._re = None
49 self._re = None
50 if generic:
50 if generic:
51 self._re = re.compile(self.name)
51 self._re = re.compile(self.name)
52
52
53 class itemregister(dict):
53 class itemregister(dict):
54 """A specialized dictionary that can handle wild-card selection"""
54 """A specialized dictionary that can handle wild-card selection"""
55
55
56 def __init__(self):
56 def __init__(self):
57 super(itemregister, self).__init__()
57 super(itemregister, self).__init__()
58 self._generics = set()
58 self._generics = set()
59
59
60 def update(self, other):
60 def update(self, other):
61 super(itemregister, self).update(other)
61 super(itemregister, self).update(other)
62 self._generics.update(other._generics)
62 self._generics.update(other._generics)
63
63
64 def __setitem__(self, key, item):
64 def __setitem__(self, key, item):
65 super(itemregister, self).__setitem__(key, item)
65 super(itemregister, self).__setitem__(key, item)
66 if item.generic:
66 if item.generic:
67 self._generics.add(item)
67 self._generics.add(item)
68
68
69 def get(self, key):
69 def get(self, key):
70 baseitem = super(itemregister, self).get(key)
70 baseitem = super(itemregister, self).get(key)
71 if baseitem is not None and not baseitem.generic:
71 if baseitem is not None and not baseitem.generic:
72 return baseitem
72 return baseitem
73
73
74 # search for a matching generic item
74 # search for a matching generic item
75 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
75 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
76 for item in generics:
76 for item in generics:
77 # we use 'match' instead of 'search' to make the matching simpler
77 # we use 'match' instead of 'search' to make the matching simpler
78 # for people unfamiliar with regular expression. Having the match
78 # for people unfamiliar with regular expression. Having the match
79 # rooted to the start of the string will produce less surprising
79 # rooted to the start of the string will produce less surprising
80 # result for user writing simple regex for sub-attribute.
80 # result for user writing simple regex for sub-attribute.
81 #
81 #
82 # For example using "color\..*" match produces an unsurprising
82 # For example using "color\..*" match produces an unsurprising
83 # result, while using search could suddenly match apparently
83 # result, while using search could suddenly match apparently
84 # unrelated configuration that happens to contains "color."
84 # unrelated configuration that happens to contains "color."
85 # anywhere. This is a tradeoff where we favor requiring ".*" on
85 # anywhere. This is a tradeoff where we favor requiring ".*" on
86 # some match to avoid the need to prefix most pattern with "^".
86 # some match to avoid the need to prefix most pattern with "^".
87 # The "^" seems more error prone.
87 # The "^" seems more error prone.
88 if item._re.match(key):
88 if item._re.match(key):
89 return item
89 return item
90
90
91 return None
91 return None
92
92
93 coreitems = {}
93 coreitems = {}
94
94
95 def _register(configtable, *args, **kwargs):
95 def _register(configtable, *args, **kwargs):
96 item = configitem(*args, **kwargs)
96 item = configitem(*args, **kwargs)
97 section = configtable.setdefault(item.section, itemregister())
97 section = configtable.setdefault(item.section, itemregister())
98 if item.name in section:
98 if item.name in section:
99 msg = "duplicated config item registration for '%s.%s'"
99 msg = "duplicated config item registration for '%s.%s'"
100 raise error.ProgrammingError(msg % (item.section, item.name))
100 raise error.ProgrammingError(msg % (item.section, item.name))
101 section[item.name] = item
101 section[item.name] = item
102
102
103 # special value for case where the default is derived from other values
103 # special value for case where the default is derived from other values
104 dynamicdefault = object()
104 dynamicdefault = object()
105
105
106 # Registering actual config items
106 # Registering actual config items
107
107
108 def getitemregister(configtable):
108 def getitemregister(configtable):
109 f = functools.partial(_register, configtable)
109 f = functools.partial(_register, configtable)
110 # export pseudo enum as configitem.*
110 # export pseudo enum as configitem.*
111 f.dynamicdefault = dynamicdefault
111 f.dynamicdefault = dynamicdefault
112 return f
112 return f
113
113
114 coreconfigitem = getitemregister(coreitems)
114 coreconfigitem = getitemregister(coreitems)
115
115
116 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',
557 default='zlib',
558 )
559 coreconfigitem('experimental', 'graphshorten',
556 coreconfigitem('experimental', 'graphshorten',
560 default=False,
557 default=False,
561 )
558 )
562 coreconfigitem('experimental', 'graphstyle.parent',
559 coreconfigitem('experimental', 'graphstyle.parent',
563 default=dynamicdefault,
560 default=dynamicdefault,
564 )
561 )
565 coreconfigitem('experimental', 'graphstyle.missing',
562 coreconfigitem('experimental', 'graphstyle.missing',
566 default=dynamicdefault,
563 default=dynamicdefault,
567 )
564 )
568 coreconfigitem('experimental', 'graphstyle.grandparent',
565 coreconfigitem('experimental', 'graphstyle.grandparent',
569 default=dynamicdefault,
566 default=dynamicdefault,
570 )
567 )
571 coreconfigitem('experimental', 'hook-track-tags',
568 coreconfigitem('experimental', 'hook-track-tags',
572 default=False,
569 default=False,
573 )
570 )
574 coreconfigitem('experimental', 'httppeer.advertise-v2',
571 coreconfigitem('experimental', 'httppeer.advertise-v2',
575 default=False,
572 default=False,
576 )
573 )
577 coreconfigitem('experimental', 'httppeer.v2-encoder-order',
574 coreconfigitem('experimental', 'httppeer.v2-encoder-order',
578 default=None,
575 default=None,
579 )
576 )
580 coreconfigitem('experimental', 'httppostargs',
577 coreconfigitem('experimental', 'httppostargs',
581 default=False,
578 default=False,
582 )
579 )
583 coreconfigitem('experimental', 'mergedriver',
580 coreconfigitem('experimental', 'mergedriver',
584 default=None,
581 default=None,
585 )
582 )
586 coreconfigitem('experimental', 'nointerrupt', default=False)
583 coreconfigitem('experimental', 'nointerrupt', default=False)
587 coreconfigitem('experimental', 'nointerrupt-interactiveonly', default=True)
584 coreconfigitem('experimental', 'nointerrupt-interactiveonly', default=True)
588
585
589 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
586 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
590 default=False,
587 default=False,
591 )
588 )
592 coreconfigitem('experimental', 'remotenames',
589 coreconfigitem('experimental', 'remotenames',
593 default=False,
590 default=False,
594 )
591 )
595 coreconfigitem('experimental', 'removeemptydirs',
592 coreconfigitem('experimental', 'removeemptydirs',
596 default=True,
593 default=True,
597 )
594 )
598 coreconfigitem('experimental', 'revert.interactive.select-to-keep',
595 coreconfigitem('experimental', 'revert.interactive.select-to-keep',
599 default=False,
596 default=False,
600 )
597 )
601 coreconfigitem('experimental', 'revisions.prefixhexnode',
598 coreconfigitem('experimental', 'revisions.prefixhexnode',
602 default=False,
599 default=False,
603 )
600 )
604 coreconfigitem('experimental', 'revlogv2',
601 coreconfigitem('experimental', 'revlogv2',
605 default=None,
602 default=None,
606 )
603 )
607 coreconfigitem('experimental', 'revisions.disambiguatewithin',
604 coreconfigitem('experimental', 'revisions.disambiguatewithin',
608 default=None,
605 default=None,
609 )
606 )
610 coreconfigitem('experimental', 'server.filesdata.recommended-batch-size',
607 coreconfigitem('experimental', 'server.filesdata.recommended-batch-size',
611 default=50000,
608 default=50000,
612 )
609 )
613 coreconfigitem('experimental', 'server.manifestdata.recommended-batch-size',
610 coreconfigitem('experimental', 'server.manifestdata.recommended-batch-size',
614 default=100000,
611 default=100000,
615 )
612 )
616 coreconfigitem('experimental', 'server.stream-narrow-clones',
613 coreconfigitem('experimental', 'server.stream-narrow-clones',
617 default=False,
614 default=False,
618 )
615 )
619 coreconfigitem('experimental', 'single-head-per-branch',
616 coreconfigitem('experimental', 'single-head-per-branch',
620 default=False,
617 default=False,
621 )
618 )
622 coreconfigitem('experimental', 'sshserver.support-v2',
619 coreconfigitem('experimental', 'sshserver.support-v2',
623 default=False,
620 default=False,
624 )
621 )
625 coreconfigitem('experimental', 'sparse-read',
622 coreconfigitem('experimental', 'sparse-read',
626 default=False,
623 default=False,
627 )
624 )
628 coreconfigitem('experimental', 'sparse-read.density-threshold',
625 coreconfigitem('experimental', 'sparse-read.density-threshold',
629 default=0.50,
626 default=0.50,
630 )
627 )
631 coreconfigitem('experimental', 'sparse-read.min-gap-size',
628 coreconfigitem('experimental', 'sparse-read.min-gap-size',
632 default='65K',
629 default='65K',
633 )
630 )
634 coreconfigitem('experimental', 'treemanifest',
631 coreconfigitem('experimental', 'treemanifest',
635 default=False,
632 default=False,
636 )
633 )
637 coreconfigitem('experimental', 'update.atomic-file',
634 coreconfigitem('experimental', 'update.atomic-file',
638 default=False,
635 default=False,
639 )
636 )
640 coreconfigitem('experimental', 'sshpeer.advertise-v2',
637 coreconfigitem('experimental', 'sshpeer.advertise-v2',
641 default=False,
638 default=False,
642 )
639 )
643 coreconfigitem('experimental', 'web.apiserver',
640 coreconfigitem('experimental', 'web.apiserver',
644 default=False,
641 default=False,
645 )
642 )
646 coreconfigitem('experimental', 'web.api.http-v2',
643 coreconfigitem('experimental', 'web.api.http-v2',
647 default=False,
644 default=False,
648 )
645 )
649 coreconfigitem('experimental', 'web.api.debugreflect',
646 coreconfigitem('experimental', 'web.api.debugreflect',
650 default=False,
647 default=False,
651 )
648 )
652 coreconfigitem('experimental', 'worker.wdir-get-thread-safe',
649 coreconfigitem('experimental', 'worker.wdir-get-thread-safe',
653 default=False,
650 default=False,
654 )
651 )
655 coreconfigitem('experimental', 'xdiff',
652 coreconfigitem('experimental', 'xdiff',
656 default=False,
653 default=False,
657 )
654 )
658 coreconfigitem('extensions', '.*',
655 coreconfigitem('extensions', '.*',
659 default=None,
656 default=None,
660 generic=True,
657 generic=True,
661 )
658 )
662 coreconfigitem('extdata', '.*',
659 coreconfigitem('extdata', '.*',
663 default=None,
660 default=None,
664 generic=True,
661 generic=True,
665 )
662 )
666 coreconfigitem('format', 'chunkcachesize',
663 coreconfigitem('format', 'chunkcachesize',
667 default=None,
664 default=None,
668 )
665 )
669 coreconfigitem('format', 'dotencode',
666 coreconfigitem('format', 'dotencode',
670 default=True,
667 default=True,
671 )
668 )
672 coreconfigitem('format', 'generaldelta',
669 coreconfigitem('format', 'generaldelta',
673 default=False,
670 default=False,
674 )
671 )
675 coreconfigitem('format', 'manifestcachesize',
672 coreconfigitem('format', 'manifestcachesize',
676 default=None,
673 default=None,
677 )
674 )
678 coreconfigitem('format', 'maxchainlen',
675 coreconfigitem('format', 'maxchainlen',
679 default=dynamicdefault,
676 default=dynamicdefault,
680 )
677 )
681 coreconfigitem('format', 'obsstore-version',
678 coreconfigitem('format', 'obsstore-version',
682 default=None,
679 default=None,
683 )
680 )
684 coreconfigitem('format', 'sparse-revlog',
681 coreconfigitem('format', 'sparse-revlog',
685 default=True,
682 default=True,
686 )
683 )
684 coreconfigitem('format', 'revlog-compression',
685 default='zlib',
686 alias=[('experimental', 'format.compression')]
687 )
687 coreconfigitem('format', 'usefncache',
688 coreconfigitem('format', 'usefncache',
688 default=True,
689 default=True,
689 )
690 )
690 coreconfigitem('format', 'usegeneraldelta',
691 coreconfigitem('format', 'usegeneraldelta',
691 default=True,
692 default=True,
692 )
693 )
693 coreconfigitem('format', 'usestore',
694 coreconfigitem('format', 'usestore',
694 default=True,
695 default=True,
695 )
696 )
696 coreconfigitem('format', 'internal-phase',
697 coreconfigitem('format', 'internal-phase',
697 default=False,
698 default=False,
698 )
699 )
699 coreconfigitem('fsmonitor', 'warn_when_unused',
700 coreconfigitem('fsmonitor', 'warn_when_unused',
700 default=True,
701 default=True,
701 )
702 )
702 coreconfigitem('fsmonitor', 'warn_update_file_count',
703 coreconfigitem('fsmonitor', 'warn_update_file_count',
703 default=50000,
704 default=50000,
704 )
705 )
705 coreconfigitem('help', br'hidden-command\..*',
706 coreconfigitem('help', br'hidden-command\..*',
706 default=False,
707 default=False,
707 generic=True,
708 generic=True,
708 )
709 )
709 coreconfigitem('help', br'hidden-topic\..*',
710 coreconfigitem('help', br'hidden-topic\..*',
710 default=False,
711 default=False,
711 generic=True,
712 generic=True,
712 )
713 )
713 coreconfigitem('hooks', '.*',
714 coreconfigitem('hooks', '.*',
714 default=dynamicdefault,
715 default=dynamicdefault,
715 generic=True,
716 generic=True,
716 )
717 )
717 coreconfigitem('hgweb-paths', '.*',
718 coreconfigitem('hgweb-paths', '.*',
718 default=list,
719 default=list,
719 generic=True,
720 generic=True,
720 )
721 )
721 coreconfigitem('hostfingerprints', '.*',
722 coreconfigitem('hostfingerprints', '.*',
722 default=list,
723 default=list,
723 generic=True,
724 generic=True,
724 )
725 )
725 coreconfigitem('hostsecurity', 'ciphers',
726 coreconfigitem('hostsecurity', 'ciphers',
726 default=None,
727 default=None,
727 )
728 )
728 coreconfigitem('hostsecurity', 'disabletls10warning',
729 coreconfigitem('hostsecurity', 'disabletls10warning',
729 default=False,
730 default=False,
730 )
731 )
731 coreconfigitem('hostsecurity', 'minimumprotocol',
732 coreconfigitem('hostsecurity', 'minimumprotocol',
732 default=dynamicdefault,
733 default=dynamicdefault,
733 )
734 )
734 coreconfigitem('hostsecurity', '.*:minimumprotocol$',
735 coreconfigitem('hostsecurity', '.*:minimumprotocol$',
735 default=dynamicdefault,
736 default=dynamicdefault,
736 generic=True,
737 generic=True,
737 )
738 )
738 coreconfigitem('hostsecurity', '.*:ciphers$',
739 coreconfigitem('hostsecurity', '.*:ciphers$',
739 default=dynamicdefault,
740 default=dynamicdefault,
740 generic=True,
741 generic=True,
741 )
742 )
742 coreconfigitem('hostsecurity', '.*:fingerprints$',
743 coreconfigitem('hostsecurity', '.*:fingerprints$',
743 default=list,
744 default=list,
744 generic=True,
745 generic=True,
745 )
746 )
746 coreconfigitem('hostsecurity', '.*:verifycertsfile$',
747 coreconfigitem('hostsecurity', '.*:verifycertsfile$',
747 default=None,
748 default=None,
748 generic=True,
749 generic=True,
749 )
750 )
750
751
751 coreconfigitem('http_proxy', 'always',
752 coreconfigitem('http_proxy', 'always',
752 default=False,
753 default=False,
753 )
754 )
754 coreconfigitem('http_proxy', 'host',
755 coreconfigitem('http_proxy', 'host',
755 default=None,
756 default=None,
756 )
757 )
757 coreconfigitem('http_proxy', 'no',
758 coreconfigitem('http_proxy', 'no',
758 default=list,
759 default=list,
759 )
760 )
760 coreconfigitem('http_proxy', 'passwd',
761 coreconfigitem('http_proxy', 'passwd',
761 default=None,
762 default=None,
762 )
763 )
763 coreconfigitem('http_proxy', 'user',
764 coreconfigitem('http_proxy', 'user',
764 default=None,
765 default=None,
765 )
766 )
766
767
767 coreconfigitem('http', 'timeout',
768 coreconfigitem('http', 'timeout',
768 default=None,
769 default=None,
769 )
770 )
770
771
771 coreconfigitem('logtoprocess', 'commandexception',
772 coreconfigitem('logtoprocess', 'commandexception',
772 default=None,
773 default=None,
773 )
774 )
774 coreconfigitem('logtoprocess', 'commandfinish',
775 coreconfigitem('logtoprocess', 'commandfinish',
775 default=None,
776 default=None,
776 )
777 )
777 coreconfigitem('logtoprocess', 'command',
778 coreconfigitem('logtoprocess', 'command',
778 default=None,
779 default=None,
779 )
780 )
780 coreconfigitem('logtoprocess', 'develwarn',
781 coreconfigitem('logtoprocess', 'develwarn',
781 default=None,
782 default=None,
782 )
783 )
783 coreconfigitem('logtoprocess', 'uiblocked',
784 coreconfigitem('logtoprocess', 'uiblocked',
784 default=None,
785 default=None,
785 )
786 )
786 coreconfigitem('merge', 'checkunknown',
787 coreconfigitem('merge', 'checkunknown',
787 default='abort',
788 default='abort',
788 )
789 )
789 coreconfigitem('merge', 'checkignored',
790 coreconfigitem('merge', 'checkignored',
790 default='abort',
791 default='abort',
791 )
792 )
792 coreconfigitem('experimental', 'merge.checkpathconflicts',
793 coreconfigitem('experimental', 'merge.checkpathconflicts',
793 default=False,
794 default=False,
794 )
795 )
795 coreconfigitem('merge', 'followcopies',
796 coreconfigitem('merge', 'followcopies',
796 default=True,
797 default=True,
797 )
798 )
798 coreconfigitem('merge', 'on-failure',
799 coreconfigitem('merge', 'on-failure',
799 default='continue',
800 default='continue',
800 )
801 )
801 coreconfigitem('merge', 'preferancestor',
802 coreconfigitem('merge', 'preferancestor',
802 default=lambda: ['*'],
803 default=lambda: ['*'],
803 )
804 )
804 coreconfigitem('merge', 'strict-capability-check',
805 coreconfigitem('merge', 'strict-capability-check',
805 default=False,
806 default=False,
806 )
807 )
807 coreconfigitem('merge-tools', '.*',
808 coreconfigitem('merge-tools', '.*',
808 default=None,
809 default=None,
809 generic=True,
810 generic=True,
810 )
811 )
811 coreconfigitem('merge-tools', br'.*\.args$',
812 coreconfigitem('merge-tools', br'.*\.args$',
812 default="$local $base $other",
813 default="$local $base $other",
813 generic=True,
814 generic=True,
814 priority=-1,
815 priority=-1,
815 )
816 )
816 coreconfigitem('merge-tools', br'.*\.binary$',
817 coreconfigitem('merge-tools', br'.*\.binary$',
817 default=False,
818 default=False,
818 generic=True,
819 generic=True,
819 priority=-1,
820 priority=-1,
820 )
821 )
821 coreconfigitem('merge-tools', br'.*\.check$',
822 coreconfigitem('merge-tools', br'.*\.check$',
822 default=list,
823 default=list,
823 generic=True,
824 generic=True,
824 priority=-1,
825 priority=-1,
825 )
826 )
826 coreconfigitem('merge-tools', br'.*\.checkchanged$',
827 coreconfigitem('merge-tools', br'.*\.checkchanged$',
827 default=False,
828 default=False,
828 generic=True,
829 generic=True,
829 priority=-1,
830 priority=-1,
830 )
831 )
831 coreconfigitem('merge-tools', br'.*\.executable$',
832 coreconfigitem('merge-tools', br'.*\.executable$',
832 default=dynamicdefault,
833 default=dynamicdefault,
833 generic=True,
834 generic=True,
834 priority=-1,
835 priority=-1,
835 )
836 )
836 coreconfigitem('merge-tools', br'.*\.fixeol$',
837 coreconfigitem('merge-tools', br'.*\.fixeol$',
837 default=False,
838 default=False,
838 generic=True,
839 generic=True,
839 priority=-1,
840 priority=-1,
840 )
841 )
841 coreconfigitem('merge-tools', br'.*\.gui$',
842 coreconfigitem('merge-tools', br'.*\.gui$',
842 default=False,
843 default=False,
843 generic=True,
844 generic=True,
844 priority=-1,
845 priority=-1,
845 )
846 )
846 coreconfigitem('merge-tools', br'.*\.mergemarkers$',
847 coreconfigitem('merge-tools', br'.*\.mergemarkers$',
847 default='basic',
848 default='basic',
848 generic=True,
849 generic=True,
849 priority=-1,
850 priority=-1,
850 )
851 )
851 coreconfigitem('merge-tools', br'.*\.mergemarkertemplate$',
852 coreconfigitem('merge-tools', br'.*\.mergemarkertemplate$',
852 default=dynamicdefault, # take from ui.mergemarkertemplate
853 default=dynamicdefault, # take from ui.mergemarkertemplate
853 generic=True,
854 generic=True,
854 priority=-1,
855 priority=-1,
855 )
856 )
856 coreconfigitem('merge-tools', br'.*\.priority$',
857 coreconfigitem('merge-tools', br'.*\.priority$',
857 default=0,
858 default=0,
858 generic=True,
859 generic=True,
859 priority=-1,
860 priority=-1,
860 )
861 )
861 coreconfigitem('merge-tools', br'.*\.premerge$',
862 coreconfigitem('merge-tools', br'.*\.premerge$',
862 default=dynamicdefault,
863 default=dynamicdefault,
863 generic=True,
864 generic=True,
864 priority=-1,
865 priority=-1,
865 )
866 )
866 coreconfigitem('merge-tools', br'.*\.symlink$',
867 coreconfigitem('merge-tools', br'.*\.symlink$',
867 default=False,
868 default=False,
868 generic=True,
869 generic=True,
869 priority=-1,
870 priority=-1,
870 )
871 )
871 coreconfigitem('pager', 'attend-.*',
872 coreconfigitem('pager', 'attend-.*',
872 default=dynamicdefault,
873 default=dynamicdefault,
873 generic=True,
874 generic=True,
874 )
875 )
875 coreconfigitem('pager', 'ignore',
876 coreconfigitem('pager', 'ignore',
876 default=list,
877 default=list,
877 )
878 )
878 coreconfigitem('pager', 'pager',
879 coreconfigitem('pager', 'pager',
879 default=dynamicdefault,
880 default=dynamicdefault,
880 )
881 )
881 coreconfigitem('patch', 'eol',
882 coreconfigitem('patch', 'eol',
882 default='strict',
883 default='strict',
883 )
884 )
884 coreconfigitem('patch', 'fuzz',
885 coreconfigitem('patch', 'fuzz',
885 default=2,
886 default=2,
886 )
887 )
887 coreconfigitem('paths', 'default',
888 coreconfigitem('paths', 'default',
888 default=None,
889 default=None,
889 )
890 )
890 coreconfigitem('paths', 'default-push',
891 coreconfigitem('paths', 'default-push',
891 default=None,
892 default=None,
892 )
893 )
893 coreconfigitem('paths', '.*',
894 coreconfigitem('paths', '.*',
894 default=None,
895 default=None,
895 generic=True,
896 generic=True,
896 )
897 )
897 coreconfigitem('phases', 'checksubrepos',
898 coreconfigitem('phases', 'checksubrepos',
898 default='follow',
899 default='follow',
899 )
900 )
900 coreconfigitem('phases', 'new-commit',
901 coreconfigitem('phases', 'new-commit',
901 default='draft',
902 default='draft',
902 )
903 )
903 coreconfigitem('phases', 'publish',
904 coreconfigitem('phases', 'publish',
904 default=True,
905 default=True,
905 )
906 )
906 coreconfigitem('profiling', 'enabled',
907 coreconfigitem('profiling', 'enabled',
907 default=False,
908 default=False,
908 )
909 )
909 coreconfigitem('profiling', 'format',
910 coreconfigitem('profiling', 'format',
910 default='text',
911 default='text',
911 )
912 )
912 coreconfigitem('profiling', 'freq',
913 coreconfigitem('profiling', 'freq',
913 default=1000,
914 default=1000,
914 )
915 )
915 coreconfigitem('profiling', 'limit',
916 coreconfigitem('profiling', 'limit',
916 default=30,
917 default=30,
917 )
918 )
918 coreconfigitem('profiling', 'nested',
919 coreconfigitem('profiling', 'nested',
919 default=0,
920 default=0,
920 )
921 )
921 coreconfigitem('profiling', 'output',
922 coreconfigitem('profiling', 'output',
922 default=None,
923 default=None,
923 )
924 )
924 coreconfigitem('profiling', 'showmax',
925 coreconfigitem('profiling', 'showmax',
925 default=0.999,
926 default=0.999,
926 )
927 )
927 coreconfigitem('profiling', 'showmin',
928 coreconfigitem('profiling', 'showmin',
928 default=dynamicdefault,
929 default=dynamicdefault,
929 )
930 )
930 coreconfigitem('profiling', 'sort',
931 coreconfigitem('profiling', 'sort',
931 default='inlinetime',
932 default='inlinetime',
932 )
933 )
933 coreconfigitem('profiling', 'statformat',
934 coreconfigitem('profiling', 'statformat',
934 default='hotpath',
935 default='hotpath',
935 )
936 )
936 coreconfigitem('profiling', 'time-track',
937 coreconfigitem('profiling', 'time-track',
937 default=dynamicdefault,
938 default=dynamicdefault,
938 )
939 )
939 coreconfigitem('profiling', 'type',
940 coreconfigitem('profiling', 'type',
940 default='stat',
941 default='stat',
941 )
942 )
942 coreconfigitem('progress', 'assume-tty',
943 coreconfigitem('progress', 'assume-tty',
943 default=False,
944 default=False,
944 )
945 )
945 coreconfigitem('progress', 'changedelay',
946 coreconfigitem('progress', 'changedelay',
946 default=1,
947 default=1,
947 )
948 )
948 coreconfigitem('progress', 'clear-complete',
949 coreconfigitem('progress', 'clear-complete',
949 default=True,
950 default=True,
950 )
951 )
951 coreconfigitem('progress', 'debug',
952 coreconfigitem('progress', 'debug',
952 default=False,
953 default=False,
953 )
954 )
954 coreconfigitem('progress', 'delay',
955 coreconfigitem('progress', 'delay',
955 default=3,
956 default=3,
956 )
957 )
957 coreconfigitem('progress', 'disable',
958 coreconfigitem('progress', 'disable',
958 default=False,
959 default=False,
959 )
960 )
960 coreconfigitem('progress', 'estimateinterval',
961 coreconfigitem('progress', 'estimateinterval',
961 default=60.0,
962 default=60.0,
962 )
963 )
963 coreconfigitem('progress', 'format',
964 coreconfigitem('progress', 'format',
964 default=lambda: ['topic', 'bar', 'number', 'estimate'],
965 default=lambda: ['topic', 'bar', 'number', 'estimate'],
965 )
966 )
966 coreconfigitem('progress', 'refresh',
967 coreconfigitem('progress', 'refresh',
967 default=0.1,
968 default=0.1,
968 )
969 )
969 coreconfigitem('progress', 'width',
970 coreconfigitem('progress', 'width',
970 default=dynamicdefault,
971 default=dynamicdefault,
971 )
972 )
972 coreconfigitem('push', 'pushvars.server',
973 coreconfigitem('push', 'pushvars.server',
973 default=False,
974 default=False,
974 )
975 )
975 coreconfigitem('rewrite', 'backup-bundle',
976 coreconfigitem('rewrite', 'backup-bundle',
976 default=True,
977 default=True,
977 alias=[('ui', 'history-editing-backup')],
978 alias=[('ui', 'history-editing-backup')],
978 )
979 )
979 coreconfigitem('rewrite', 'update-timestamp',
980 coreconfigitem('rewrite', 'update-timestamp',
980 default=False,
981 default=False,
981 )
982 )
982 coreconfigitem('storage', 'new-repo-backend',
983 coreconfigitem('storage', 'new-repo-backend',
983 default='revlogv1',
984 default='revlogv1',
984 )
985 )
985 coreconfigitem('storage', 'revlog.optimize-delta-parent-choice',
986 coreconfigitem('storage', 'revlog.optimize-delta-parent-choice',
986 default=True,
987 default=True,
987 alias=[('format', 'aggressivemergedeltas')],
988 alias=[('format', 'aggressivemergedeltas')],
988 )
989 )
989 coreconfigitem('storage', 'revlog.reuse-external-delta',
990 coreconfigitem('storage', 'revlog.reuse-external-delta',
990 default=True,
991 default=True,
991 )
992 )
992 coreconfigitem('storage', 'revlog.reuse-external-delta-parent',
993 coreconfigitem('storage', 'revlog.reuse-external-delta-parent',
993 default=None,
994 default=None,
994 )
995 )
995 coreconfigitem('storage', 'revlog.zlib.level',
996 coreconfigitem('storage', 'revlog.zlib.level',
996 default=None,
997 default=None,
997 )
998 )
998 coreconfigitem('storage', 'revlog.zstd.level',
999 coreconfigitem('storage', 'revlog.zstd.level',
999 default=None,
1000 default=None,
1000 )
1001 )
1001 coreconfigitem('server', 'bookmarks-pushkey-compat',
1002 coreconfigitem('server', 'bookmarks-pushkey-compat',
1002 default=True,
1003 default=True,
1003 )
1004 )
1004 coreconfigitem('server', 'bundle1',
1005 coreconfigitem('server', 'bundle1',
1005 default=True,
1006 default=True,
1006 )
1007 )
1007 coreconfigitem('server', 'bundle1gd',
1008 coreconfigitem('server', 'bundle1gd',
1008 default=None,
1009 default=None,
1009 )
1010 )
1010 coreconfigitem('server', 'bundle1.pull',
1011 coreconfigitem('server', 'bundle1.pull',
1011 default=None,
1012 default=None,
1012 )
1013 )
1013 coreconfigitem('server', 'bundle1gd.pull',
1014 coreconfigitem('server', 'bundle1gd.pull',
1014 default=None,
1015 default=None,
1015 )
1016 )
1016 coreconfigitem('server', 'bundle1.push',
1017 coreconfigitem('server', 'bundle1.push',
1017 default=None,
1018 default=None,
1018 )
1019 )
1019 coreconfigitem('server', 'bundle1gd.push',
1020 coreconfigitem('server', 'bundle1gd.push',
1020 default=None,
1021 default=None,
1021 )
1022 )
1022 coreconfigitem('server', 'bundle2.stream',
1023 coreconfigitem('server', 'bundle2.stream',
1023 default=True,
1024 default=True,
1024 alias=[('experimental', 'bundle2.stream')]
1025 alias=[('experimental', 'bundle2.stream')]
1025 )
1026 )
1026 coreconfigitem('server', 'compressionengines',
1027 coreconfigitem('server', 'compressionengines',
1027 default=list,
1028 default=list,
1028 )
1029 )
1029 coreconfigitem('server', 'concurrent-push-mode',
1030 coreconfigitem('server', 'concurrent-push-mode',
1030 default='strict',
1031 default='strict',
1031 )
1032 )
1032 coreconfigitem('server', 'disablefullbundle',
1033 coreconfigitem('server', 'disablefullbundle',
1033 default=False,
1034 default=False,
1034 )
1035 )
1035 coreconfigitem('server', 'maxhttpheaderlen',
1036 coreconfigitem('server', 'maxhttpheaderlen',
1036 default=1024,
1037 default=1024,
1037 )
1038 )
1038 coreconfigitem('server', 'pullbundle',
1039 coreconfigitem('server', 'pullbundle',
1039 default=False,
1040 default=False,
1040 )
1041 )
1041 coreconfigitem('server', 'preferuncompressed',
1042 coreconfigitem('server', 'preferuncompressed',
1042 default=False,
1043 default=False,
1043 )
1044 )
1044 coreconfigitem('server', 'streamunbundle',
1045 coreconfigitem('server', 'streamunbundle',
1045 default=False,
1046 default=False,
1046 )
1047 )
1047 coreconfigitem('server', 'uncompressed',
1048 coreconfigitem('server', 'uncompressed',
1048 default=True,
1049 default=True,
1049 )
1050 )
1050 coreconfigitem('server', 'uncompressedallowsecret',
1051 coreconfigitem('server', 'uncompressedallowsecret',
1051 default=False,
1052 default=False,
1052 )
1053 )
1053 coreconfigitem('server', 'view',
1054 coreconfigitem('server', 'view',
1054 default='served',
1055 default='served',
1055 )
1056 )
1056 coreconfigitem('server', 'validate',
1057 coreconfigitem('server', 'validate',
1057 default=False,
1058 default=False,
1058 )
1059 )
1059 coreconfigitem('server', 'zliblevel',
1060 coreconfigitem('server', 'zliblevel',
1060 default=-1,
1061 default=-1,
1061 )
1062 )
1062 coreconfigitem('server', 'zstdlevel',
1063 coreconfigitem('server', 'zstdlevel',
1063 default=3,
1064 default=3,
1064 )
1065 )
1065 coreconfigitem('share', 'pool',
1066 coreconfigitem('share', 'pool',
1066 default=None,
1067 default=None,
1067 )
1068 )
1068 coreconfigitem('share', 'poolnaming',
1069 coreconfigitem('share', 'poolnaming',
1069 default='identity',
1070 default='identity',
1070 )
1071 )
1071 coreconfigitem('smtp', 'host',
1072 coreconfigitem('smtp', 'host',
1072 default=None,
1073 default=None,
1073 )
1074 )
1074 coreconfigitem('smtp', 'local_hostname',
1075 coreconfigitem('smtp', 'local_hostname',
1075 default=None,
1076 default=None,
1076 )
1077 )
1077 coreconfigitem('smtp', 'password',
1078 coreconfigitem('smtp', 'password',
1078 default=None,
1079 default=None,
1079 )
1080 )
1080 coreconfigitem('smtp', 'port',
1081 coreconfigitem('smtp', 'port',
1081 default=dynamicdefault,
1082 default=dynamicdefault,
1082 )
1083 )
1083 coreconfigitem('smtp', 'tls',
1084 coreconfigitem('smtp', 'tls',
1084 default='none',
1085 default='none',
1085 )
1086 )
1086 coreconfigitem('smtp', 'username',
1087 coreconfigitem('smtp', 'username',
1087 default=None,
1088 default=None,
1088 )
1089 )
1089 coreconfigitem('sparse', 'missingwarning',
1090 coreconfigitem('sparse', 'missingwarning',
1090 default=True,
1091 default=True,
1091 )
1092 )
1092 coreconfigitem('subrepos', 'allowed',
1093 coreconfigitem('subrepos', 'allowed',
1093 default=dynamicdefault, # to make backporting simpler
1094 default=dynamicdefault, # to make backporting simpler
1094 )
1095 )
1095 coreconfigitem('subrepos', 'hg:allowed',
1096 coreconfigitem('subrepos', 'hg:allowed',
1096 default=dynamicdefault,
1097 default=dynamicdefault,
1097 )
1098 )
1098 coreconfigitem('subrepos', 'git:allowed',
1099 coreconfigitem('subrepos', 'git:allowed',
1099 default=dynamicdefault,
1100 default=dynamicdefault,
1100 )
1101 )
1101 coreconfigitem('subrepos', 'svn:allowed',
1102 coreconfigitem('subrepos', 'svn:allowed',
1102 default=dynamicdefault,
1103 default=dynamicdefault,
1103 )
1104 )
1104 coreconfigitem('templates', '.*',
1105 coreconfigitem('templates', '.*',
1105 default=None,
1106 default=None,
1106 generic=True,
1107 generic=True,
1107 )
1108 )
1108 coreconfigitem('templateconfig', '.*',
1109 coreconfigitem('templateconfig', '.*',
1109 default=dynamicdefault,
1110 default=dynamicdefault,
1110 generic=True,
1111 generic=True,
1111 )
1112 )
1112 coreconfigitem('trusted', 'groups',
1113 coreconfigitem('trusted', 'groups',
1113 default=list,
1114 default=list,
1114 )
1115 )
1115 coreconfigitem('trusted', 'users',
1116 coreconfigitem('trusted', 'users',
1116 default=list,
1117 default=list,
1117 )
1118 )
1118 coreconfigitem('ui', '_usedassubrepo',
1119 coreconfigitem('ui', '_usedassubrepo',
1119 default=False,
1120 default=False,
1120 )
1121 )
1121 coreconfigitem('ui', 'allowemptycommit',
1122 coreconfigitem('ui', 'allowemptycommit',
1122 default=False,
1123 default=False,
1123 )
1124 )
1124 coreconfigitem('ui', 'archivemeta',
1125 coreconfigitem('ui', 'archivemeta',
1125 default=True,
1126 default=True,
1126 )
1127 )
1127 coreconfigitem('ui', 'askusername',
1128 coreconfigitem('ui', 'askusername',
1128 default=False,
1129 default=False,
1129 )
1130 )
1130 coreconfigitem('ui', 'clonebundlefallback',
1131 coreconfigitem('ui', 'clonebundlefallback',
1131 default=False,
1132 default=False,
1132 )
1133 )
1133 coreconfigitem('ui', 'clonebundleprefers',
1134 coreconfigitem('ui', 'clonebundleprefers',
1134 default=list,
1135 default=list,
1135 )
1136 )
1136 coreconfigitem('ui', 'clonebundles',
1137 coreconfigitem('ui', 'clonebundles',
1137 default=True,
1138 default=True,
1138 )
1139 )
1139 coreconfigitem('ui', 'color',
1140 coreconfigitem('ui', 'color',
1140 default='auto',
1141 default='auto',
1141 )
1142 )
1142 coreconfigitem('ui', 'commitsubrepos',
1143 coreconfigitem('ui', 'commitsubrepos',
1143 default=False,
1144 default=False,
1144 )
1145 )
1145 coreconfigitem('ui', 'debug',
1146 coreconfigitem('ui', 'debug',
1146 default=False,
1147 default=False,
1147 )
1148 )
1148 coreconfigitem('ui', 'debugger',
1149 coreconfigitem('ui', 'debugger',
1149 default=None,
1150 default=None,
1150 )
1151 )
1151 coreconfigitem('ui', 'editor',
1152 coreconfigitem('ui', 'editor',
1152 default=dynamicdefault,
1153 default=dynamicdefault,
1153 )
1154 )
1154 coreconfigitem('ui', 'fallbackencoding',
1155 coreconfigitem('ui', 'fallbackencoding',
1155 default=None,
1156 default=None,
1156 )
1157 )
1157 coreconfigitem('ui', 'forcecwd',
1158 coreconfigitem('ui', 'forcecwd',
1158 default=None,
1159 default=None,
1159 )
1160 )
1160 coreconfigitem('ui', 'forcemerge',
1161 coreconfigitem('ui', 'forcemerge',
1161 default=None,
1162 default=None,
1162 )
1163 )
1163 coreconfigitem('ui', 'formatdebug',
1164 coreconfigitem('ui', 'formatdebug',
1164 default=False,
1165 default=False,
1165 )
1166 )
1166 coreconfigitem('ui', 'formatjson',
1167 coreconfigitem('ui', 'formatjson',
1167 default=False,
1168 default=False,
1168 )
1169 )
1169 coreconfigitem('ui', 'formatted',
1170 coreconfigitem('ui', 'formatted',
1170 default=None,
1171 default=None,
1171 )
1172 )
1172 coreconfigitem('ui', 'graphnodetemplate',
1173 coreconfigitem('ui', 'graphnodetemplate',
1173 default=None,
1174 default=None,
1174 )
1175 )
1175 coreconfigitem('ui', 'interactive',
1176 coreconfigitem('ui', 'interactive',
1176 default=None,
1177 default=None,
1177 )
1178 )
1178 coreconfigitem('ui', 'interface',
1179 coreconfigitem('ui', 'interface',
1179 default=None,
1180 default=None,
1180 )
1181 )
1181 coreconfigitem('ui', 'interface.chunkselector',
1182 coreconfigitem('ui', 'interface.chunkselector',
1182 default=None,
1183 default=None,
1183 )
1184 )
1184 coreconfigitem('ui', 'large-file-limit',
1185 coreconfigitem('ui', 'large-file-limit',
1185 default=10000000,
1186 default=10000000,
1186 )
1187 )
1187 coreconfigitem('ui', 'logblockedtimes',
1188 coreconfigitem('ui', 'logblockedtimes',
1188 default=False,
1189 default=False,
1189 )
1190 )
1190 coreconfigitem('ui', 'logtemplate',
1191 coreconfigitem('ui', 'logtemplate',
1191 default=None,
1192 default=None,
1192 )
1193 )
1193 coreconfigitem('ui', 'merge',
1194 coreconfigitem('ui', 'merge',
1194 default=None,
1195 default=None,
1195 )
1196 )
1196 coreconfigitem('ui', 'mergemarkers',
1197 coreconfigitem('ui', 'mergemarkers',
1197 default='basic',
1198 default='basic',
1198 )
1199 )
1199 coreconfigitem('ui', 'mergemarkertemplate',
1200 coreconfigitem('ui', 'mergemarkertemplate',
1200 default=('{node|short} '
1201 default=('{node|short} '
1201 '{ifeq(tags, "tip", "", '
1202 '{ifeq(tags, "tip", "", '
1202 'ifeq(tags, "", "", "{tags} "))}'
1203 'ifeq(tags, "", "", "{tags} "))}'
1203 '{if(bookmarks, "{bookmarks} ")}'
1204 '{if(bookmarks, "{bookmarks} ")}'
1204 '{ifeq(branch, "default", "", "{branch} ")}'
1205 '{ifeq(branch, "default", "", "{branch} ")}'
1205 '- {author|user}: {desc|firstline}')
1206 '- {author|user}: {desc|firstline}')
1206 )
1207 )
1207 coreconfigitem('ui', 'message-output',
1208 coreconfigitem('ui', 'message-output',
1208 default='stdio',
1209 default='stdio',
1209 )
1210 )
1210 coreconfigitem('ui', 'nontty',
1211 coreconfigitem('ui', 'nontty',
1211 default=False,
1212 default=False,
1212 )
1213 )
1213 coreconfigitem('ui', 'origbackuppath',
1214 coreconfigitem('ui', 'origbackuppath',
1214 default=None,
1215 default=None,
1215 )
1216 )
1216 coreconfigitem('ui', 'paginate',
1217 coreconfigitem('ui', 'paginate',
1217 default=True,
1218 default=True,
1218 )
1219 )
1219 coreconfigitem('ui', 'patch',
1220 coreconfigitem('ui', 'patch',
1220 default=None,
1221 default=None,
1221 )
1222 )
1222 coreconfigitem('ui', 'pre-merge-tool-output-template',
1223 coreconfigitem('ui', 'pre-merge-tool-output-template',
1223 default=None,
1224 default=None,
1224 )
1225 )
1225 coreconfigitem('ui', 'portablefilenames',
1226 coreconfigitem('ui', 'portablefilenames',
1226 default='warn',
1227 default='warn',
1227 )
1228 )
1228 coreconfigitem('ui', 'promptecho',
1229 coreconfigitem('ui', 'promptecho',
1229 default=False,
1230 default=False,
1230 )
1231 )
1231 coreconfigitem('ui', 'quiet',
1232 coreconfigitem('ui', 'quiet',
1232 default=False,
1233 default=False,
1233 )
1234 )
1234 coreconfigitem('ui', 'quietbookmarkmove',
1235 coreconfigitem('ui', 'quietbookmarkmove',
1235 default=False,
1236 default=False,
1236 )
1237 )
1237 coreconfigitem('ui', 'relative-paths',
1238 coreconfigitem('ui', 'relative-paths',
1238 default='legacy',
1239 default='legacy',
1239 )
1240 )
1240 coreconfigitem('ui', 'remotecmd',
1241 coreconfigitem('ui', 'remotecmd',
1241 default='hg',
1242 default='hg',
1242 )
1243 )
1243 coreconfigitem('ui', 'report_untrusted',
1244 coreconfigitem('ui', 'report_untrusted',
1244 default=True,
1245 default=True,
1245 )
1246 )
1246 coreconfigitem('ui', 'rollback',
1247 coreconfigitem('ui', 'rollback',
1247 default=True,
1248 default=True,
1248 )
1249 )
1249 coreconfigitem('ui', 'signal-safe-lock',
1250 coreconfigitem('ui', 'signal-safe-lock',
1250 default=True,
1251 default=True,
1251 )
1252 )
1252 coreconfigitem('ui', 'slash',
1253 coreconfigitem('ui', 'slash',
1253 default=False,
1254 default=False,
1254 )
1255 )
1255 coreconfigitem('ui', 'ssh',
1256 coreconfigitem('ui', 'ssh',
1256 default='ssh',
1257 default='ssh',
1257 )
1258 )
1258 coreconfigitem('ui', 'ssherrorhint',
1259 coreconfigitem('ui', 'ssherrorhint',
1259 default=None,
1260 default=None,
1260 )
1261 )
1261 coreconfigitem('ui', 'statuscopies',
1262 coreconfigitem('ui', 'statuscopies',
1262 default=False,
1263 default=False,
1263 )
1264 )
1264 coreconfigitem('ui', 'strict',
1265 coreconfigitem('ui', 'strict',
1265 default=False,
1266 default=False,
1266 )
1267 )
1267 coreconfigitem('ui', 'style',
1268 coreconfigitem('ui', 'style',
1268 default='',
1269 default='',
1269 )
1270 )
1270 coreconfigitem('ui', 'supportcontact',
1271 coreconfigitem('ui', 'supportcontact',
1271 default=None,
1272 default=None,
1272 )
1273 )
1273 coreconfigitem('ui', 'textwidth',
1274 coreconfigitem('ui', 'textwidth',
1274 default=78,
1275 default=78,
1275 )
1276 )
1276 coreconfigitem('ui', 'timeout',
1277 coreconfigitem('ui', 'timeout',
1277 default='600',
1278 default='600',
1278 )
1279 )
1279 coreconfigitem('ui', 'timeout.warn',
1280 coreconfigitem('ui', 'timeout.warn',
1280 default=0,
1281 default=0,
1281 )
1282 )
1282 coreconfigitem('ui', 'traceback',
1283 coreconfigitem('ui', 'traceback',
1283 default=False,
1284 default=False,
1284 )
1285 )
1285 coreconfigitem('ui', 'tweakdefaults',
1286 coreconfigitem('ui', 'tweakdefaults',
1286 default=False,
1287 default=False,
1287 )
1288 )
1288 coreconfigitem('ui', 'username',
1289 coreconfigitem('ui', 'username',
1289 alias=[('ui', 'user')]
1290 alias=[('ui', 'user')]
1290 )
1291 )
1291 coreconfigitem('ui', 'verbose',
1292 coreconfigitem('ui', 'verbose',
1292 default=False,
1293 default=False,
1293 )
1294 )
1294 coreconfigitem('verify', 'skipflags',
1295 coreconfigitem('verify', 'skipflags',
1295 default=None,
1296 default=None,
1296 )
1297 )
1297 coreconfigitem('web', 'allowbz2',
1298 coreconfigitem('web', 'allowbz2',
1298 default=False,
1299 default=False,
1299 )
1300 )
1300 coreconfigitem('web', 'allowgz',
1301 coreconfigitem('web', 'allowgz',
1301 default=False,
1302 default=False,
1302 )
1303 )
1303 coreconfigitem('web', 'allow-pull',
1304 coreconfigitem('web', 'allow-pull',
1304 alias=[('web', 'allowpull')],
1305 alias=[('web', 'allowpull')],
1305 default=True,
1306 default=True,
1306 )
1307 )
1307 coreconfigitem('web', 'allow-push',
1308 coreconfigitem('web', 'allow-push',
1308 alias=[('web', 'allow_push')],
1309 alias=[('web', 'allow_push')],
1309 default=list,
1310 default=list,
1310 )
1311 )
1311 coreconfigitem('web', 'allowzip',
1312 coreconfigitem('web', 'allowzip',
1312 default=False,
1313 default=False,
1313 )
1314 )
1314 coreconfigitem('web', 'archivesubrepos',
1315 coreconfigitem('web', 'archivesubrepos',
1315 default=False,
1316 default=False,
1316 )
1317 )
1317 coreconfigitem('web', 'cache',
1318 coreconfigitem('web', 'cache',
1318 default=True,
1319 default=True,
1319 )
1320 )
1320 coreconfigitem('web', 'comparisoncontext',
1321 coreconfigitem('web', 'comparisoncontext',
1321 default=5,
1322 default=5,
1322 )
1323 )
1323 coreconfigitem('web', 'contact',
1324 coreconfigitem('web', 'contact',
1324 default=None,
1325 default=None,
1325 )
1326 )
1326 coreconfigitem('web', 'deny_push',
1327 coreconfigitem('web', 'deny_push',
1327 default=list,
1328 default=list,
1328 )
1329 )
1329 coreconfigitem('web', 'guessmime',
1330 coreconfigitem('web', 'guessmime',
1330 default=False,
1331 default=False,
1331 )
1332 )
1332 coreconfigitem('web', 'hidden',
1333 coreconfigitem('web', 'hidden',
1333 default=False,
1334 default=False,
1334 )
1335 )
1335 coreconfigitem('web', 'labels',
1336 coreconfigitem('web', 'labels',
1336 default=list,
1337 default=list,
1337 )
1338 )
1338 coreconfigitem('web', 'logoimg',
1339 coreconfigitem('web', 'logoimg',
1339 default='hglogo.png',
1340 default='hglogo.png',
1340 )
1341 )
1341 coreconfigitem('web', 'logourl',
1342 coreconfigitem('web', 'logourl',
1342 default='https://mercurial-scm.org/',
1343 default='https://mercurial-scm.org/',
1343 )
1344 )
1344 coreconfigitem('web', 'accesslog',
1345 coreconfigitem('web', 'accesslog',
1345 default='-',
1346 default='-',
1346 )
1347 )
1347 coreconfigitem('web', 'address',
1348 coreconfigitem('web', 'address',
1348 default='',
1349 default='',
1349 )
1350 )
1350 coreconfigitem('web', 'allow-archive',
1351 coreconfigitem('web', 'allow-archive',
1351 alias=[('web', 'allow_archive')],
1352 alias=[('web', 'allow_archive')],
1352 default=list,
1353 default=list,
1353 )
1354 )
1354 coreconfigitem('web', 'allow_read',
1355 coreconfigitem('web', 'allow_read',
1355 default=list,
1356 default=list,
1356 )
1357 )
1357 coreconfigitem('web', 'baseurl',
1358 coreconfigitem('web', 'baseurl',
1358 default=None,
1359 default=None,
1359 )
1360 )
1360 coreconfigitem('web', 'cacerts',
1361 coreconfigitem('web', 'cacerts',
1361 default=None,
1362 default=None,
1362 )
1363 )
1363 coreconfigitem('web', 'certificate',
1364 coreconfigitem('web', 'certificate',
1364 default=None,
1365 default=None,
1365 )
1366 )
1366 coreconfigitem('web', 'collapse',
1367 coreconfigitem('web', 'collapse',
1367 default=False,
1368 default=False,
1368 )
1369 )
1369 coreconfigitem('web', 'csp',
1370 coreconfigitem('web', 'csp',
1370 default=None,
1371 default=None,
1371 )
1372 )
1372 coreconfigitem('web', 'deny_read',
1373 coreconfigitem('web', 'deny_read',
1373 default=list,
1374 default=list,
1374 )
1375 )
1375 coreconfigitem('web', 'descend',
1376 coreconfigitem('web', 'descend',
1376 default=True,
1377 default=True,
1377 )
1378 )
1378 coreconfigitem('web', 'description',
1379 coreconfigitem('web', 'description',
1379 default="",
1380 default="",
1380 )
1381 )
1381 coreconfigitem('web', 'encoding',
1382 coreconfigitem('web', 'encoding',
1382 default=lambda: encoding.encoding,
1383 default=lambda: encoding.encoding,
1383 )
1384 )
1384 coreconfigitem('web', 'errorlog',
1385 coreconfigitem('web', 'errorlog',
1385 default='-',
1386 default='-',
1386 )
1387 )
1387 coreconfigitem('web', 'ipv6',
1388 coreconfigitem('web', 'ipv6',
1388 default=False,
1389 default=False,
1389 )
1390 )
1390 coreconfigitem('web', 'maxchanges',
1391 coreconfigitem('web', 'maxchanges',
1391 default=10,
1392 default=10,
1392 )
1393 )
1393 coreconfigitem('web', 'maxfiles',
1394 coreconfigitem('web', 'maxfiles',
1394 default=10,
1395 default=10,
1395 )
1396 )
1396 coreconfigitem('web', 'maxshortchanges',
1397 coreconfigitem('web', 'maxshortchanges',
1397 default=60,
1398 default=60,
1398 )
1399 )
1399 coreconfigitem('web', 'motd',
1400 coreconfigitem('web', 'motd',
1400 default='',
1401 default='',
1401 )
1402 )
1402 coreconfigitem('web', 'name',
1403 coreconfigitem('web', 'name',
1403 default=dynamicdefault,
1404 default=dynamicdefault,
1404 )
1405 )
1405 coreconfigitem('web', 'port',
1406 coreconfigitem('web', 'port',
1406 default=8000,
1407 default=8000,
1407 )
1408 )
1408 coreconfigitem('web', 'prefix',
1409 coreconfigitem('web', 'prefix',
1409 default='',
1410 default='',
1410 )
1411 )
1411 coreconfigitem('web', 'push_ssl',
1412 coreconfigitem('web', 'push_ssl',
1412 default=True,
1413 default=True,
1413 )
1414 )
1414 coreconfigitem('web', 'refreshinterval',
1415 coreconfigitem('web', 'refreshinterval',
1415 default=20,
1416 default=20,
1416 )
1417 )
1417 coreconfigitem('web', 'server-header',
1418 coreconfigitem('web', 'server-header',
1418 default=None,
1419 default=None,
1419 )
1420 )
1420 coreconfigitem('web', 'static',
1421 coreconfigitem('web', 'static',
1421 default=None,
1422 default=None,
1422 )
1423 )
1423 coreconfigitem('web', 'staticurl',
1424 coreconfigitem('web', 'staticurl',
1424 default=None,
1425 default=None,
1425 )
1426 )
1426 coreconfigitem('web', 'stripes',
1427 coreconfigitem('web', 'stripes',
1427 default=1,
1428 default=1,
1428 )
1429 )
1429 coreconfigitem('web', 'style',
1430 coreconfigitem('web', 'style',
1430 default='paper',
1431 default='paper',
1431 )
1432 )
1432 coreconfigitem('web', 'templates',
1433 coreconfigitem('web', 'templates',
1433 default=None,
1434 default=None,
1434 )
1435 )
1435 coreconfigitem('web', 'view',
1436 coreconfigitem('web', 'view',
1436 default='served',
1437 default='served',
1437 )
1438 )
1438 coreconfigitem('worker', 'backgroundclose',
1439 coreconfigitem('worker', 'backgroundclose',
1439 default=dynamicdefault,
1440 default=dynamicdefault,
1440 )
1441 )
1441 # Windows defaults to a limit of 512 open files. A buffer of 128
1442 # Windows defaults to a limit of 512 open files. A buffer of 128
1442 # should give us enough headway.
1443 # should give us enough headway.
1443 coreconfigitem('worker', 'backgroundclosemaxqueue',
1444 coreconfigitem('worker', 'backgroundclosemaxqueue',
1444 default=384,
1445 default=384,
1445 )
1446 )
1446 coreconfigitem('worker', 'backgroundcloseminfilecount',
1447 coreconfigitem('worker', 'backgroundcloseminfilecount',
1447 default=2048,
1448 default=2048,
1448 )
1449 )
1449 coreconfigitem('worker', 'backgroundclosethreadcount',
1450 coreconfigitem('worker', 'backgroundclosethreadcount',
1450 default=4,
1451 default=4,
1451 )
1452 )
1452 coreconfigitem('worker', 'enabled',
1453 coreconfigitem('worker', 'enabled',
1453 default=True,
1454 default=True,
1454 )
1455 )
1455 coreconfigitem('worker', 'numcpus',
1456 coreconfigitem('worker', 'numcpus',
1456 default=None,
1457 default=None,
1457 )
1458 )
1458
1459
1459 # Rebase related configuration moved to core because other extension are doing
1460 # Rebase related configuration moved to core because other extension are doing
1460 # strange things. For example, shelve import the extensions to reuse some bit
1461 # strange things. For example, shelve import the extensions to reuse some bit
1461 # without formally loading it.
1462 # without formally loading it.
1462 coreconfigitem('commands', 'rebase.requiredest',
1463 coreconfigitem('commands', 'rebase.requiredest',
1463 default=False,
1464 default=False,
1464 )
1465 )
1465 coreconfigitem('experimental', 'rebaseskipobsolete',
1466 coreconfigitem('experimental', 'rebaseskipobsolete',
1466 default=True,
1467 default=True,
1467 )
1468 )
1468 coreconfigitem('rebase', 'singletransaction',
1469 coreconfigitem('rebase', 'singletransaction',
1469 default=False,
1470 default=False,
1470 )
1471 )
1471 coreconfigitem('rebase', 'experimental.inmemory',
1472 coreconfigitem('rebase', 'experimental.inmemory',
1472 default=False,
1473 default=False,
1473 )
1474 )
@@ -1,2834 +1,2841 b''
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 ``revlog-compression``
870 Compression algorithm used by revlog. Supported value are `zlib` and `zstd`.
871 The `zlib` engine is the historical default of Mercurial. `zstd` is a newer
872 format that is usually a net win over `zlib` operating faster at better
873 compression rate. Use `zstd` to reduce CPU usage.
874
875 On some system, Mercurial installation may lack `zstd` supports. Default is `zlib`.
869
876
870 ``graph``
877 ``graph``
871 ---------
878 ---------
872
879
873 Web graph view configuration. This section let you change graph
880 Web graph view configuration. This section let you change graph
874 elements display properties by branches, for instance to make the
881 elements display properties by branches, for instance to make the
875 ``default`` branch stand out.
882 ``default`` branch stand out.
876
883
877 Each line has the following format::
884 Each line has the following format::
878
885
879 <branch>.<argument> = <value>
886 <branch>.<argument> = <value>
880
887
881 where ``<branch>`` is the name of the branch being
888 where ``<branch>`` is the name of the branch being
882 customized. Example::
889 customized. Example::
883
890
884 [graph]
891 [graph]
885 # 2px width
892 # 2px width
886 default.width = 2
893 default.width = 2
887 # red color
894 # red color
888 default.color = FF0000
895 default.color = FF0000
889
896
890 Supported arguments:
897 Supported arguments:
891
898
892 ``width``
899 ``width``
893 Set branch edges width in pixels.
900 Set branch edges width in pixels.
894
901
895 ``color``
902 ``color``
896 Set branch edges color in hexadecimal RGB notation.
903 Set branch edges color in hexadecimal RGB notation.
897
904
898 ``hooks``
905 ``hooks``
899 ---------
906 ---------
900
907
901 Commands or Python functions that get automatically executed by
908 Commands or Python functions that get automatically executed by
902 various actions such as starting or finishing a commit. Multiple
909 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
910 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
911 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
912 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
913 by adding a prefix of ``priority.`` to the hook name on a new line
907 and setting the priority. The default priority is 0.
914 and setting the priority. The default priority is 0.
908
915
909 Example ``.hg/hgrc``::
916 Example ``.hg/hgrc``::
910
917
911 [hooks]
918 [hooks]
912 # update working directory after adding changesets
919 # update working directory after adding changesets
913 changegroup.update = hg update
920 changegroup.update = hg update
914 # do not use the site-wide hook
921 # do not use the site-wide hook
915 incoming =
922 incoming =
916 incoming.email = /my/email/hook
923 incoming.email = /my/email/hook
917 incoming.autobuild = /my/build/hook
924 incoming.autobuild = /my/build/hook
918 # force autobuild hook to run before other incoming hooks
925 # force autobuild hook to run before other incoming hooks
919 priority.incoming.autobuild = 1
926 priority.incoming.autobuild = 1
920
927
921 Most hooks are run with environment variables set that give useful
928 Most hooks are run with environment variables set that give useful
922 additional information. For each hook below, the environment variables
929 additional information. For each hook below, the environment variables
923 it is passed are listed with names in the form ``$HG_foo``. The
930 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.
931 ``$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
932 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
933 of the hook in the config, respectively. In the example above, this will
927 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
934 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
928
935
929 .. container:: windows
936 .. container:: windows
930
937
931 Some basic Unix syntax can be enabled for portability, including ``$VAR``
938 Some basic Unix syntax can be enabled for portability, including ``$VAR``
932 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
939 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
933 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
940 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
941 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
942 slash or inside of a strong quote. Strong quotes will be replaced by
936 double quotes after processing.
943 double quotes after processing.
937
944
938 This feature is enabled by adding a prefix of ``tonative.`` to the hook
945 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::
946 name on a new line, and setting it to ``True``. For example::
940
947
941 [hooks]
948 [hooks]
942 incoming.autobuild = /my/build/hook
949 incoming.autobuild = /my/build/hook
943 # enable translation to cmd.exe syntax for autobuild hook
950 # enable translation to cmd.exe syntax for autobuild hook
944 tonative.incoming.autobuild = True
951 tonative.incoming.autobuild = True
945
952
946 ``changegroup``
953 ``changegroup``
947 Run after a changegroup has been added via push, pull or unbundle. The ID of
954 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``.
955 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``.
956 The URL from which changes came is in ``$HG_URL``.
950
957
951 ``commit``
958 ``commit``
952 Run after a changeset has been created in the local repository. The ID
959 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
960 of the newly created changeset is in ``$HG_NODE``. Parent changeset
954 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
961 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
955
962
956 ``incoming``
963 ``incoming``
957 Run after a changeset has been pulled, pushed, or unbundled into
964 Run after a changeset has been pulled, pushed, or unbundled into
958 the local repository. The ID of the newly arrived changeset is in
965 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``.
966 ``$HG_NODE``. The URL that was source of the changes is in ``$HG_URL``.
960
967
961 ``outgoing``
968 ``outgoing``
962 Run after sending changes from the local repository to another. The ID of
969 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
970 first changeset sent is in ``$HG_NODE``. The source of operation is in
964 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
971 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
965
972
966 ``post-<command>``
973 ``post-<command>``
967 Run after successful invocations of the associated command. The
974 Run after successful invocations of the associated command. The
968 contents of the command line are passed as ``$HG_ARGS`` and the result
975 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
976 code in ``$HG_RESULT``. Parsed command line arguments are passed as
970 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
977 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
971 the python data internally passed to <command>. ``$HG_OPTS`` is a
978 the python data internally passed to <command>. ``$HG_OPTS`` is a
972 dictionary of options (with unspecified options set to their defaults).
979 dictionary of options (with unspecified options set to their defaults).
973 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
980 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
974
981
975 ``fail-<command>``
982 ``fail-<command>``
976 Run after a failed invocation of an associated command. The contents
983 Run after a failed invocation of an associated command. The contents
977 of the command line are passed as ``$HG_ARGS``. Parsed command line
984 of the command line are passed as ``$HG_ARGS``. Parsed command line
978 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
985 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
979 string representations of the python data internally passed to
986 string representations of the python data internally passed to
980 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
987 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
981 options set to their defaults). ``$HG_PATS`` is a list of arguments.
988 options set to their defaults). ``$HG_PATS`` is a list of arguments.
982 Hook failure is ignored.
989 Hook failure is ignored.
983
990
984 ``pre-<command>``
991 ``pre-<command>``
985 Run before executing the associated command. The contents of the
992 Run before executing the associated command. The contents of the
986 command line are passed as ``$HG_ARGS``. Parsed command line arguments
993 command line are passed as ``$HG_ARGS``. Parsed command line arguments
987 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
994 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
988 representations of the data internally passed to <command>. ``$HG_OPTS``
995 representations of the data internally passed to <command>. ``$HG_OPTS``
989 is a dictionary of options (with unspecified options set to their
996 is a dictionary of options (with unspecified options set to their
990 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
997 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
991 failure, the command doesn't execute and Mercurial returns the failure
998 failure, the command doesn't execute and Mercurial returns the failure
992 code.
999 code.
993
1000
994 ``prechangegroup``
1001 ``prechangegroup``
995 Run before a changegroup is added via push, pull or unbundle. Exit
1002 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
1003 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
1004 cause the push, pull or unbundle to fail. The URL from which changes
998 will come is in ``$HG_URL``.
1005 will come is in ``$HG_URL``.
999
1006
1000 ``precommit``
1007 ``precommit``
1001 Run before starting a local commit. Exit status 0 allows the
1008 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.
1009 commit to proceed. A non-zero status will cause the commit to fail.
1003 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1010 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1004
1011
1005 ``prelistkeys``
1012 ``prelistkeys``
1006 Run before listing pushkeys (like bookmarks) in the
1013 Run before listing pushkeys (like bookmarks) in the
1007 repository. A non-zero status will cause failure. The key namespace is
1014 repository. A non-zero status will cause failure. The key namespace is
1008 in ``$HG_NAMESPACE``.
1015 in ``$HG_NAMESPACE``.
1009
1016
1010 ``preoutgoing``
1017 ``preoutgoing``
1011 Run before collecting changes to send from the local repository to
1018 Run before collecting changes to send from the local repository to
1012 another. A non-zero status will cause failure. This lets you prevent
1019 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
1020 pull over HTTP or SSH. It can also prevent propagating commits (via
1014 local pull, push (outbound) or bundle commands), but not completely,
1021 local pull, push (outbound) or bundle commands), but not completely,
1015 since you can just copy files instead. The source of operation is in
1022 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
1023 ``$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
1024 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1018 is happening on behalf of a repository on same system.
1025 is happening on behalf of a repository on same system.
1019
1026
1020 ``prepushkey``
1027 ``prepushkey``
1021 Run before a pushkey (like a bookmark) is added to the
1028 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
1029 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``,
1030 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
1031 the old value (if any) is in ``$HG_OLD``, and the new value is in
1025 ``$HG_NEW``.
1032 ``$HG_NEW``.
1026
1033
1027 ``pretag``
1034 ``pretag``
1028 Run before creating a tag. Exit status 0 allows the tag to be
1035 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
1036 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
1037 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``.
1038 tag is local if ``$HG_LOCAL=1``, or in the repository if ``$HG_LOCAL=0``.
1032
1039
1033 ``pretxnopen``
1040 ``pretxnopen``
1034 Run before any new repository transaction is open. The reason for the
1041 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
1042 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
1043 transaction will be in ``HG_TXNID``. A non-zero status will prevent the
1037 transaction from being opened.
1044 transaction from being opened.
1038
1045
1039 ``pretxnclose``
1046 ``pretxnclose``
1040 Run right before the transaction is actually finalized. Any repository change
1047 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
1048 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
1049 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
1050 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
1051 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
1052 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``
1053 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
1054 (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
1055 added changeset), ``$HG_URL`` and ``$HG_SOURCE`` variables. Bookmark and
1049 phase changes will set ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``
1056 phase changes will set ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``
1050 respectively, etc.
1057 respectively, etc.
1051
1058
1052 ``pretxnclose-bookmark``
1059 ``pretxnclose-bookmark``
1053 Run right before a bookmark change is actually finalized. Any repository
1060 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
1061 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
1062 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.
1063 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
1064 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
1065 bookmark location will be available in ``$HG_NODE`` while the previous
1059 location will be available in ``$HG_OLDNODE``. In case of a bookmark
1066 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``
1067 creation ``$HG_OLDNODE`` will be empty. In case of deletion ``$HG_NODE``
1061 will be empty.
1068 will be empty.
1062 In addition, the reason for the transaction opening will be in
1069 In addition, the reason for the transaction opening will be in
1063 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1070 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1064 ``HG_TXNID``.
1071 ``HG_TXNID``.
1065
1072
1066 ``pretxnclose-phase``
1073 ``pretxnclose-phase``
1067 Run right before a phase change is actually finalized. Any repository change
1074 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
1075 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
1076 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
1077 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.
1078 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``
1079 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``
1080 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
1081 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
1082 ``$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
1083 ``HG_TXNID``. The hook is also run for newly added revisions. In this case
1077 the ``$HG_OLDPHASE`` entry will be empty.
1084 the ``$HG_OLDPHASE`` entry will be empty.
1078
1085
1079 ``txnclose``
1086 ``txnclose``
1080 Run after any repository transaction has been committed. At this
1087 Run after any repository transaction has been committed. At this
1081 point, the transaction can no longer be rolled back. The hook will run
1088 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
1089 after the lock is released. See :hg:`help config.hooks.pretxnclose` for
1083 details about available variables.
1090 details about available variables.
1084
1091
1085 ``txnclose-bookmark``
1092 ``txnclose-bookmark``
1086 Run after any bookmark change has been committed. At this point, the
1093 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
1094 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
1095 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1089 about available variables.
1096 about available variables.
1090
1097
1091 ``txnclose-phase``
1098 ``txnclose-phase``
1092 Run after any phase change has been committed. At this point, the
1099 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
1100 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
1101 is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
1095 available variables.
1102 available variables.
1096
1103
1097 ``txnabort``
1104 ``txnabort``
1098 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
1105 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
1099 for details about available variables.
1106 for details about available variables.
1100
1107
1101 ``pretxnchangegroup``
1108 ``pretxnchangegroup``
1102 Run after a changegroup has been added via push, pull or unbundle, but before
1109 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
1110 the transaction has been committed. The changegroup is visible to the hook
1104 program. This allows validation of incoming changes before accepting them.
1111 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
1112 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
1113 ``$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
1114 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``.
1115 unbundle will fail. The URL that was the source of changes is in ``$HG_URL``.
1109
1116
1110 ``pretxncommit``
1117 ``pretxncommit``
1111 Run after a changeset has been created, but before the transaction is
1118 Run after a changeset has been created, but before the transaction is
1112 committed. The changeset is visible to the hook program. This allows
1119 committed. The changeset is visible to the hook program. This allows
1113 validation of the commit message and changes. Exit status 0 allows the
1120 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
1121 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
1122 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``.
1123 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1117
1124
1118 ``preupdate``
1125 ``preupdate``
1119 Run before updating the working directory. Exit status 0 allows
1126 Run before updating the working directory. Exit status 0 allows
1120 the update to proceed. A non-zero status will prevent the update.
1127 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
1128 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``.
1129 merge, the ID of second new parent is in ``$HG_PARENT2``.
1123
1130
1124 ``listkeys``
1131 ``listkeys``
1125 Run after listing pushkeys (like bookmarks) in the repository. The
1132 Run after listing pushkeys (like bookmarks) in the repository. The
1126 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1133 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1127 dictionary containing the keys and values.
1134 dictionary containing the keys and values.
1128
1135
1129 ``pushkey``
1136 ``pushkey``
1130 Run after a pushkey (like a bookmark) is added to the
1137 Run after a pushkey (like a bookmark) is added to the
1131 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
1138 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
1139 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
1133 value is in ``$HG_NEW``.
1140 value is in ``$HG_NEW``.
1134
1141
1135 ``tag``
1142 ``tag``
1136 Run after a tag is created. The ID of the tagged changeset is in ``$HG_NODE``.
1143 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
1144 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``.
1145 the repository if ``$HG_LOCAL=0``.
1139
1146
1140 ``update``
1147 ``update``
1141 Run after updating the working directory. The changeset ID of first
1148 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
1149 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
1150 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``.
1151 update failed (e.g. because conflicts were not resolved), ``$HG_ERROR=1``.
1145
1152
1146 .. note::
1153 .. note::
1147
1154
1148 It is generally better to use standard hooks rather than the
1155 It is generally better to use standard hooks rather than the
1149 generic pre- and post- command hooks, as they are guaranteed to be
1156 generic pre- and post- command hooks, as they are guaranteed to be
1150 called in the appropriate contexts for influencing transactions.
1157 called in the appropriate contexts for influencing transactions.
1151 Also, hooks like "commit" will be called in all contexts that
1158 Also, hooks like "commit" will be called in all contexts that
1152 generate a commit (e.g. tag) and not just the commit command.
1159 generate a commit (e.g. tag) and not just the commit command.
1153
1160
1154 .. note::
1161 .. note::
1155
1162
1156 Environment variables with empty values may not be passed to
1163 Environment variables with empty values may not be passed to
1157 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1164 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1158 will have an empty value under Unix-like platforms for non-merge
1165 will have an empty value under Unix-like platforms for non-merge
1159 changesets, while it will not be available at all under Windows.
1166 changesets, while it will not be available at all under Windows.
1160
1167
1161 The syntax for Python hooks is as follows::
1168 The syntax for Python hooks is as follows::
1162
1169
1163 hookname = python:modulename.submodule.callable
1170 hookname = python:modulename.submodule.callable
1164 hookname = python:/path/to/python/module.py:callable
1171 hookname = python:/path/to/python/module.py:callable
1165
1172
1166 Python hooks are run within the Mercurial process. Each hook is
1173 Python hooks are run within the Mercurial process. Each hook is
1167 called with at least three keyword arguments: a ui object (keyword
1174 called with at least three keyword arguments: a ui object (keyword
1168 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1175 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1169 keyword that tells what kind of hook is used. Arguments listed as
1176 keyword that tells what kind of hook is used. Arguments listed as
1170 environment variables above are passed as keyword arguments, with no
1177 environment variables above are passed as keyword arguments, with no
1171 ``HG_`` prefix, and names in lower case.
1178 ``HG_`` prefix, and names in lower case.
1172
1179
1173 If a Python hook returns a "true" value or raises an exception, this
1180 If a Python hook returns a "true" value or raises an exception, this
1174 is treated as a failure.
1181 is treated as a failure.
1175
1182
1176
1183
1177 ``hostfingerprints``
1184 ``hostfingerprints``
1178 --------------------
1185 --------------------
1179
1186
1180 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1187 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1181
1188
1182 Fingerprints of the certificates of known HTTPS servers.
1189 Fingerprints of the certificates of known HTTPS servers.
1183
1190
1184 A HTTPS connection to a server with a fingerprint configured here will
1191 A HTTPS connection to a server with a fingerprint configured here will
1185 only succeed if the servers certificate matches the fingerprint.
1192 only succeed if the servers certificate matches the fingerprint.
1186 This is very similar to how ssh known hosts works.
1193 This is very similar to how ssh known hosts works.
1187
1194
1188 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
1195 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
1196 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
1197 be used to define both old and new fingerprints while a host transitions
1191 to a new certificate.
1198 to a new certificate.
1192
1199
1193 The CA chain and web.cacerts is not used for servers with a fingerprint.
1200 The CA chain and web.cacerts is not used for servers with a fingerprint.
1194
1201
1195 For example::
1202 For example::
1196
1203
1197 [hostfingerprints]
1204 [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
1205 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
1206 hg.intevation.org = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1200
1207
1201 ``hostsecurity``
1208 ``hostsecurity``
1202 ----------------
1209 ----------------
1203
1210
1204 Used to specify global and per-host security settings for connecting to
1211 Used to specify global and per-host security settings for connecting to
1205 other machines.
1212 other machines.
1206
1213
1207 The following options control default behavior for all hosts.
1214 The following options control default behavior for all hosts.
1208
1215
1209 ``ciphers``
1216 ``ciphers``
1210 Defines the cryptographic ciphers to use for connections.
1217 Defines the cryptographic ciphers to use for connections.
1211
1218
1212 Value must be a valid OpenSSL Cipher List Format as documented at
1219 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.
1220 https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
1214
1221
1215 This setting is for advanced users only. Setting to incorrect values
1222 This setting is for advanced users only. Setting to incorrect values
1216 can significantly lower connection security or decrease performance.
1223 can significantly lower connection security or decrease performance.
1217 You have been warned.
1224 You have been warned.
1218
1225
1219 This option requires Python 2.7.
1226 This option requires Python 2.7.
1220
1227
1221 ``minimumprotocol``
1228 ``minimumprotocol``
1222 Defines the minimum channel encryption protocol to use.
1229 Defines the minimum channel encryption protocol to use.
1223
1230
1224 By default, the highest version of TLS supported by both client and server
1231 By default, the highest version of TLS supported by both client and server
1225 is used.
1232 is used.
1226
1233
1227 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1234 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1228
1235
1229 When running on an old Python version, only ``tls1.0`` is allowed since
1236 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.
1237 old versions of Python only support up to TLS 1.0.
1231
1238
1232 When running a Python that supports modern TLS versions, the default is
1239 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
1240 ``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
1241 weakens security and should only be used as a feature of last resort if
1235 a server does not support TLS 1.1+.
1242 a server does not support TLS 1.1+.
1236
1243
1237 Options in the ``[hostsecurity]`` section can have the form
1244 Options in the ``[hostsecurity]`` section can have the form
1238 ``hostname``:``setting``. This allows multiple settings to be defined on a
1245 ``hostname``:``setting``. This allows multiple settings to be defined on a
1239 per-host basis.
1246 per-host basis.
1240
1247
1241 The following per-host settings can be defined.
1248 The following per-host settings can be defined.
1242
1249
1243 ``ciphers``
1250 ``ciphers``
1244 This behaves like ``ciphers`` as described above except it only applies
1251 This behaves like ``ciphers`` as described above except it only applies
1245 to the host on which it is defined.
1252 to the host on which it is defined.
1246
1253
1247 ``fingerprints``
1254 ``fingerprints``
1248 A list of hashes of the DER encoded peer/remote certificate. Values have
1255 A list of hashes of the DER encoded peer/remote certificate. Values have
1249 the form ``algorithm``:``fingerprint``. e.g.
1256 the form ``algorithm``:``fingerprint``. e.g.
1250 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1257 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1251 In addition, colons (``:``) can appear in the fingerprint part.
1258 In addition, colons (``:``) can appear in the fingerprint part.
1252
1259
1253 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1260 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1254 ``sha512``.
1261 ``sha512``.
1255
1262
1256 Use of ``sha256`` or ``sha512`` is preferred.
1263 Use of ``sha256`` or ``sha512`` is preferred.
1257
1264
1258 If a fingerprint is specified, the CA chain is not validated for this
1265 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
1266 host and Mercurial will require the remote certificate to match one
1260 of the fingerprints specified. This means if the server updates its
1267 of the fingerprints specified. This means if the server updates its
1261 certificate, Mercurial will abort until a new fingerprint is defined.
1268 certificate, Mercurial will abort until a new fingerprint is defined.
1262 This can provide stronger security than traditional CA-based validation
1269 This can provide stronger security than traditional CA-based validation
1263 at the expense of convenience.
1270 at the expense of convenience.
1264
1271
1265 This option takes precedence over ``verifycertsfile``.
1272 This option takes precedence over ``verifycertsfile``.
1266
1273
1267 ``minimumprotocol``
1274 ``minimumprotocol``
1268 This behaves like ``minimumprotocol`` as described above except it
1275 This behaves like ``minimumprotocol`` as described above except it
1269 only applies to the host on which it is defined.
1276 only applies to the host on which it is defined.
1270
1277
1271 ``verifycertsfile``
1278 ``verifycertsfile``
1272 Path to file a containing a list of PEM encoded certificates used to
1279 Path to file a containing a list of PEM encoded certificates used to
1273 verify the server certificate. Environment variables and ``~user``
1280 verify the server certificate. Environment variables and ``~user``
1274 constructs are expanded in the filename.
1281 constructs are expanded in the filename.
1275
1282
1276 The server certificate or the certificate's certificate authority (CA)
1283 The server certificate or the certificate's certificate authority (CA)
1277 must match a certificate from this file or certificate verification
1284 must match a certificate from this file or certificate verification
1278 will fail and connections to the server will be refused.
1285 will fail and connections to the server will be refused.
1279
1286
1280 If defined, only certificates provided by this file will be used:
1287 If defined, only certificates provided by this file will be used:
1281 ``web.cacerts`` and any system/default certificates will not be
1288 ``web.cacerts`` and any system/default certificates will not be
1282 used.
1289 used.
1283
1290
1284 This option has no effect if the per-host ``fingerprints`` option
1291 This option has no effect if the per-host ``fingerprints`` option
1285 is set.
1292 is set.
1286
1293
1287 The format of the file is as follows::
1294 The format of the file is as follows::
1288
1295
1289 -----BEGIN CERTIFICATE-----
1296 -----BEGIN CERTIFICATE-----
1290 ... (certificate in base64 PEM encoding) ...
1297 ... (certificate in base64 PEM encoding) ...
1291 -----END CERTIFICATE-----
1298 -----END CERTIFICATE-----
1292 -----BEGIN CERTIFICATE-----
1299 -----BEGIN CERTIFICATE-----
1293 ... (certificate in base64 PEM encoding) ...
1300 ... (certificate in base64 PEM encoding) ...
1294 -----END CERTIFICATE-----
1301 -----END CERTIFICATE-----
1295
1302
1296 For example::
1303 For example::
1297
1304
1298 [hostsecurity]
1305 [hostsecurity]
1299 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
1306 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
1307 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
1308 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
1309 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1303
1310
1304 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1311 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1305 when connecting to ``hg.example.com``::
1312 when connecting to ``hg.example.com``::
1306
1313
1307 [hostsecurity]
1314 [hostsecurity]
1308 minimumprotocol = tls1.2
1315 minimumprotocol = tls1.2
1309 hg.example.com:minimumprotocol = tls1.1
1316 hg.example.com:minimumprotocol = tls1.1
1310
1317
1311 ``http_proxy``
1318 ``http_proxy``
1312 --------------
1319 --------------
1313
1320
1314 Used to access web-based Mercurial repositories through a HTTP
1321 Used to access web-based Mercurial repositories through a HTTP
1315 proxy.
1322 proxy.
1316
1323
1317 ``host``
1324 ``host``
1318 Host name and (optional) port of the proxy server, for example
1325 Host name and (optional) port of the proxy server, for example
1319 "myproxy:8000".
1326 "myproxy:8000".
1320
1327
1321 ``no``
1328 ``no``
1322 Optional. Comma-separated list of host names that should bypass
1329 Optional. Comma-separated list of host names that should bypass
1323 the proxy.
1330 the proxy.
1324
1331
1325 ``passwd``
1332 ``passwd``
1326 Optional. Password to authenticate with at the proxy server.
1333 Optional. Password to authenticate with at the proxy server.
1327
1334
1328 ``user``
1335 ``user``
1329 Optional. User name to authenticate with at the proxy server.
1336 Optional. User name to authenticate with at the proxy server.
1330
1337
1331 ``always``
1338 ``always``
1332 Optional. Always use the proxy, even for localhost and any entries
1339 Optional. Always use the proxy, even for localhost and any entries
1333 in ``http_proxy.no``. (default: False)
1340 in ``http_proxy.no``. (default: False)
1334
1341
1335 ``http``
1342 ``http``
1336 ----------
1343 ----------
1337
1344
1338 Used to configure access to Mercurial repositories via HTTP.
1345 Used to configure access to Mercurial repositories via HTTP.
1339
1346
1340 ``timeout``
1347 ``timeout``
1341 If set, blocking operations will timeout after that many seconds.
1348 If set, blocking operations will timeout after that many seconds.
1342 (default: None)
1349 (default: None)
1343
1350
1344 ``merge``
1351 ``merge``
1345 ---------
1352 ---------
1346
1353
1347 This section specifies behavior during merges and updates.
1354 This section specifies behavior during merges and updates.
1348
1355
1349 ``checkignored``
1356 ``checkignored``
1350 Controls behavior when an ignored file on disk has the same name as a tracked
1357 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
1358 file in the changeset being merged or updated to, and has different
1352 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1359 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
1360 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
1361 ``.orig``. With ``ignore``, don't print a warning and back them up as
1355 ``.orig``. (default: ``abort``)
1362 ``.orig``. (default: ``abort``)
1356
1363
1357 ``checkunknown``
1364 ``checkunknown``
1358 Controls behavior when an unknown file that isn't ignored has the same name
1365 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
1366 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
1367 different contents. Similar to ``merge.checkignored``, except for files that
1361 are not ignored. (default: ``abort``)
1368 are not ignored. (default: ``abort``)
1362
1369
1363 ``on-failure``
1370 ``on-failure``
1364 When set to ``continue`` (the default), the merge process attempts to
1371 When set to ``continue`` (the default), the merge process attempts to
1365 merge all unresolved files using the merge chosen tool, regardless of
1372 merge all unresolved files using the merge chosen tool, regardless of
1366 whether previous file merge attempts during the process succeeded or not.
1373 whether previous file merge attempts during the process succeeded or not.
1367 Setting this to ``prompt`` will prompt after any merge failure continue
1374 Setting this to ``prompt`` will prompt after any merge failure continue
1368 or halt the merge process. Setting this to ``halt`` will automatically
1375 or halt the merge process. Setting this to ``halt`` will automatically
1369 halt the merge process on any merge tool failure. The merge process
1376 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
1377 can be restarted by using the ``resolve`` command. When a merge is
1371 halted, the repository is left in a normal ``unresolved`` merge state.
1378 halted, the repository is left in a normal ``unresolved`` merge state.
1372 (default: ``continue``)
1379 (default: ``continue``)
1373
1380
1374 ``strict-capability-check``
1381 ``strict-capability-check``
1375 Whether capabilities of internal merge tools are checked strictly
1382 Whether capabilities of internal merge tools are checked strictly
1376 or not, while examining rules to decide merge tool to be used.
1383 or not, while examining rules to decide merge tool to be used.
1377 (default: False)
1384 (default: False)
1378
1385
1379 ``merge-patterns``
1386 ``merge-patterns``
1380 ------------------
1387 ------------------
1381
1388
1382 This section specifies merge tools to associate with particular file
1389 This section specifies merge tools to associate with particular file
1383 patterns. Tools matched here will take precedence over the default
1390 patterns. Tools matched here will take precedence over the default
1384 merge tool. Patterns are globs by default, rooted at the repository
1391 merge tool. Patterns are globs by default, rooted at the repository
1385 root.
1392 root.
1386
1393
1387 Example::
1394 Example::
1388
1395
1389 [merge-patterns]
1396 [merge-patterns]
1390 **.c = kdiff3
1397 **.c = kdiff3
1391 **.jpg = myimgmerge
1398 **.jpg = myimgmerge
1392
1399
1393 ``merge-tools``
1400 ``merge-tools``
1394 ---------------
1401 ---------------
1395
1402
1396 This section configures external merge tools to use for file-level
1403 This section configures external merge tools to use for file-level
1397 merges. This section has likely been preconfigured at install time.
1404 merges. This section has likely been preconfigured at install time.
1398 Use :hg:`config merge-tools` to check the existing configuration.
1405 Use :hg:`config merge-tools` to check the existing configuration.
1399 Also see :hg:`help merge-tools` for more details.
1406 Also see :hg:`help merge-tools` for more details.
1400
1407
1401 Example ``~/.hgrc``::
1408 Example ``~/.hgrc``::
1402
1409
1403 [merge-tools]
1410 [merge-tools]
1404 # Override stock tool location
1411 # Override stock tool location
1405 kdiff3.executable = ~/bin/kdiff3
1412 kdiff3.executable = ~/bin/kdiff3
1406 # Specify command line
1413 # Specify command line
1407 kdiff3.args = $base $local $other -o $output
1414 kdiff3.args = $base $local $other -o $output
1408 # Give higher priority
1415 # Give higher priority
1409 kdiff3.priority = 1
1416 kdiff3.priority = 1
1410
1417
1411 # Changing the priority of preconfigured tool
1418 # Changing the priority of preconfigured tool
1412 meld.priority = 0
1419 meld.priority = 0
1413
1420
1414 # Disable a preconfigured tool
1421 # Disable a preconfigured tool
1415 vimdiff.disabled = yes
1422 vimdiff.disabled = yes
1416
1423
1417 # Define new tool
1424 # Define new tool
1418 myHtmlTool.args = -m $local $other $base $output
1425 myHtmlTool.args = -m $local $other $base $output
1419 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1426 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1420 myHtmlTool.priority = 1
1427 myHtmlTool.priority = 1
1421
1428
1422 Supported arguments:
1429 Supported arguments:
1423
1430
1424 ``priority``
1431 ``priority``
1425 The priority in which to evaluate this tool.
1432 The priority in which to evaluate this tool.
1426 (default: 0)
1433 (default: 0)
1427
1434
1428 ``executable``
1435 ``executable``
1429 Either just the name of the executable or its pathname.
1436 Either just the name of the executable or its pathname.
1430
1437
1431 .. container:: windows
1438 .. container:: windows
1432
1439
1433 On Windows, the path can use environment variables with ${ProgramFiles}
1440 On Windows, the path can use environment variables with ${ProgramFiles}
1434 syntax.
1441 syntax.
1435
1442
1436 (default: the tool name)
1443 (default: the tool name)
1437
1444
1438 ``args``
1445 ``args``
1439 The arguments to pass to the tool executable. You can refer to the
1446 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
1447 files being merged as well as the output file through these
1441 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1448 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1442
1449
1443 The meaning of ``$local`` and ``$other`` can vary depending on which action is
1450 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
1451 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
1452 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
1453 the commit you are merging with. During a rebase, ``$local`` represents the
1447 destination of the rebase, and ``$other`` represents the commit being rebased.
1454 destination of the rebase, and ``$other`` represents the commit being rebased.
1448
1455
1449 Some operations define custom labels to assist with identifying the revisions,
1456 Some operations define custom labels to assist with identifying the revisions,
1450 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1457 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1451 labels are not available, these will be ``local``, ``other``, and ``base``,
1458 labels are not available, these will be ``local``, ``other``, and ``base``,
1452 respectively.
1459 respectively.
1453 (default: ``$local $base $other``)
1460 (default: ``$local $base $other``)
1454
1461
1455 ``premerge``
1462 ``premerge``
1456 Attempt to run internal non-interactive 3-way merge tool before
1463 Attempt to run internal non-interactive 3-way merge tool before
1457 launching external tool. Options are ``true``, ``false``, ``keep`` or
1464 launching external tool. Options are ``true``, ``false``, ``keep`` or
1458 ``keep-merge3``. The ``keep`` option will leave markers in the file if the
1465 ``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
1466 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
1467 about the base of the merge in the marker (see internal :merge3 in
1461 :hg:`help merge-tools`).
1468 :hg:`help merge-tools`).
1462 (default: True)
1469 (default: True)
1463
1470
1464 ``binary``
1471 ``binary``
1465 This tool can merge binary files. (default: False, unless tool
1472 This tool can merge binary files. (default: False, unless tool
1466 was selected by file pattern match)
1473 was selected by file pattern match)
1467
1474
1468 ``symlink``
1475 ``symlink``
1469 This tool can merge symlinks. (default: False)
1476 This tool can merge symlinks. (default: False)
1470
1477
1471 ``check``
1478 ``check``
1472 A list of merge success-checking options:
1479 A list of merge success-checking options:
1473
1480
1474 ``changed``
1481 ``changed``
1475 Ask whether merge was successful when the merged file shows no changes.
1482 Ask whether merge was successful when the merged file shows no changes.
1476 ``conflicts``
1483 ``conflicts``
1477 Check whether there are conflicts even though the tool reported success.
1484 Check whether there are conflicts even though the tool reported success.
1478 ``prompt``
1485 ``prompt``
1479 Always prompt for merge success, regardless of success reported by tool.
1486 Always prompt for merge success, regardless of success reported by tool.
1480
1487
1481 ``fixeol``
1488 ``fixeol``
1482 Attempt to fix up EOL changes caused by the merge tool.
1489 Attempt to fix up EOL changes caused by the merge tool.
1483 (default: False)
1490 (default: False)
1484
1491
1485 ``gui``
1492 ``gui``
1486 This tool requires a graphical interface to run. (default: False)
1493 This tool requires a graphical interface to run. (default: False)
1487
1494
1488 ``mergemarkers``
1495 ``mergemarkers``
1489 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1496 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1490 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1497 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1491 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1498 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1492 markers generated during premerge will be ``detailed`` if either this option or
1499 markers generated during premerge will be ``detailed`` if either this option or
1493 the corresponding option in the ``[ui]`` section is ``detailed``.
1500 the corresponding option in the ``[ui]`` section is ``detailed``.
1494 (default: ``basic``)
1501 (default: ``basic``)
1495
1502
1496 ``mergemarkertemplate``
1503 ``mergemarkertemplate``
1497 This setting can be used to override ``mergemarkertemplate`` from the ``[ui]``
1504 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
1505 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
1506 and to the conflict markers that are generated if ``premerge`` is ``keep` or
1500 ``keep-merge3``. See the corresponding variable in ``[ui]`` for more
1507 ``keep-merge3``. See the corresponding variable in ``[ui]`` for more
1501 information.
1508 information.
1502
1509
1503 .. container:: windows
1510 .. container:: windows
1504
1511
1505 ``regkey``
1512 ``regkey``
1506 Windows registry key which describes install location of this
1513 Windows registry key which describes install location of this
1507 tool. Mercurial will search for this key first under
1514 tool. Mercurial will search for this key first under
1508 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1515 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1509 (default: None)
1516 (default: None)
1510
1517
1511 ``regkeyalt``
1518 ``regkeyalt``
1512 An alternate Windows registry key to try if the first key is not
1519 An alternate Windows registry key to try if the first key is not
1513 found. The alternate key uses the same ``regname`` and ``regappend``
1520 found. The alternate key uses the same ``regname`` and ``regappend``
1514 semantics of the primary key. The most common use for this key
1521 semantics of the primary key. The most common use for this key
1515 is to search for 32bit applications on 64bit operating systems.
1522 is to search for 32bit applications on 64bit operating systems.
1516 (default: None)
1523 (default: None)
1517
1524
1518 ``regname``
1525 ``regname``
1519 Name of value to read from specified registry key.
1526 Name of value to read from specified registry key.
1520 (default: the unnamed (default) value)
1527 (default: the unnamed (default) value)
1521
1528
1522 ``regappend``
1529 ``regappend``
1523 String to append to the value read from the registry, typically
1530 String to append to the value read from the registry, typically
1524 the executable name of the tool.
1531 the executable name of the tool.
1525 (default: None)
1532 (default: None)
1526
1533
1527 ``pager``
1534 ``pager``
1528 ---------
1535 ---------
1529
1536
1530 Setting used to control when to paginate and with what external tool. See
1537 Setting used to control when to paginate and with what external tool. See
1531 :hg:`help pager` for details.
1538 :hg:`help pager` for details.
1532
1539
1533 ``pager``
1540 ``pager``
1534 Define the external tool used as pager.
1541 Define the external tool used as pager.
1535
1542
1536 If no pager is set, Mercurial uses the environment variable $PAGER.
1543 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
1544 If neither pager.pager, nor $PAGER is set, a default pager will be
1538 used, typically `less` on Unix and `more` on Windows. Example::
1545 used, typically `less` on Unix and `more` on Windows. Example::
1539
1546
1540 [pager]
1547 [pager]
1541 pager = less -FRX
1548 pager = less -FRX
1542
1549
1543 ``ignore``
1550 ``ignore``
1544 List of commands to disable the pager for. Example::
1551 List of commands to disable the pager for. Example::
1545
1552
1546 [pager]
1553 [pager]
1547 ignore = version, help, update
1554 ignore = version, help, update
1548
1555
1549 ``patch``
1556 ``patch``
1550 ---------
1557 ---------
1551
1558
1552 Settings used when applying patches, for instance through the 'import'
1559 Settings used when applying patches, for instance through the 'import'
1553 command or with Mercurial Queues extension.
1560 command or with Mercurial Queues extension.
1554
1561
1555 ``eol``
1562 ``eol``
1556 When set to 'strict' patch content and patched files end of lines
1563 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
1564 are preserved. When set to ``lf`` or ``crlf``, both files end of
1558 lines are ignored when patching and the result line endings are
1565 lines are ignored when patching and the result line endings are
1559 normalized to either LF (Unix) or CRLF (Windows). When set to
1566 normalized to either LF (Unix) or CRLF (Windows). When set to
1560 ``auto``, end of lines are again ignored while patching but line
1567 ``auto``, end of lines are again ignored while patching but line
1561 endings in patched files are normalized to their original setting
1568 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
1569 on a per-file basis. If target file does not exist or has no end
1563 of line, patch line endings are preserved.
1570 of line, patch line endings are preserved.
1564 (default: strict)
1571 (default: strict)
1565
1572
1566 ``fuzz``
1573 ``fuzz``
1567 The number of lines of 'fuzz' to allow when applying patches. This
1574 The number of lines of 'fuzz' to allow when applying patches. This
1568 controls how much context the patcher is allowed to ignore when
1575 controls how much context the patcher is allowed to ignore when
1569 trying to apply a patch.
1576 trying to apply a patch.
1570 (default: 2)
1577 (default: 2)
1571
1578
1572 ``paths``
1579 ``paths``
1573 ---------
1580 ---------
1574
1581
1575 Assigns symbolic names and behavior to repositories.
1582 Assigns symbolic names and behavior to repositories.
1576
1583
1577 Options are symbolic names defining the URL or directory that is the
1584 Options are symbolic names defining the URL or directory that is the
1578 location of the repository. Example::
1585 location of the repository. Example::
1579
1586
1580 [paths]
1587 [paths]
1581 my_server = https://example.com/my_repo
1588 my_server = https://example.com/my_repo
1582 local_path = /home/me/repo
1589 local_path = /home/me/repo
1583
1590
1584 These symbolic names can be used from the command line. To pull
1591 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``:
1592 from ``my_server``: :hg:`pull my_server`. To push to ``local_path``:
1586 :hg:`push local_path`.
1593 :hg:`push local_path`.
1587
1594
1588 Options containing colons (``:``) denote sub-options that can influence
1595 Options containing colons (``:``) denote sub-options that can influence
1589 behavior for that specific path. Example::
1596 behavior for that specific path. Example::
1590
1597
1591 [paths]
1598 [paths]
1592 my_server = https://example.com/my_path
1599 my_server = https://example.com/my_path
1593 my_server:pushurl = ssh://example.com/my_path
1600 my_server:pushurl = ssh://example.com/my_path
1594
1601
1595 The following sub-options can be defined:
1602 The following sub-options can be defined:
1596
1603
1597 ``pushurl``
1604 ``pushurl``
1598 The URL to use for push operations. If not defined, the location
1605 The URL to use for push operations. If not defined, the location
1599 defined by the path's main entry is used.
1606 defined by the path's main entry is used.
1600
1607
1601 ``pushrev``
1608 ``pushrev``
1602 A revset defining which revisions to push by default.
1609 A revset defining which revisions to push by default.
1603
1610
1604 When :hg:`push` is executed without a ``-r`` argument, the revset
1611 When :hg:`push` is executed without a ``-r`` argument, the revset
1605 defined by this sub-option is evaluated to determine what to push.
1612 defined by this sub-option is evaluated to determine what to push.
1606
1613
1607 For example, a value of ``.`` will push the working directory's
1614 For example, a value of ``.`` will push the working directory's
1608 revision by default.
1615 revision by default.
1609
1616
1610 Revsets specifying bookmarks will not result in the bookmark being
1617 Revsets specifying bookmarks will not result in the bookmark being
1611 pushed.
1618 pushed.
1612
1619
1613 The following special named paths exist:
1620 The following special named paths exist:
1614
1621
1615 ``default``
1622 ``default``
1616 The URL or directory to use when no source or remote is specified.
1623 The URL or directory to use when no source or remote is specified.
1617
1624
1618 :hg:`clone` will automatically define this path to the location the
1625 :hg:`clone` will automatically define this path to the location the
1619 repository was cloned from.
1626 repository was cloned from.
1620
1627
1621 ``default-push``
1628 ``default-push``
1622 (deprecated) The URL or directory for the default :hg:`push` location.
1629 (deprecated) The URL or directory for the default :hg:`push` location.
1623 ``default:pushurl`` should be used instead.
1630 ``default:pushurl`` should be used instead.
1624
1631
1625 ``phases``
1632 ``phases``
1626 ----------
1633 ----------
1627
1634
1628 Specifies default handling of phases. See :hg:`help phases` for more
1635 Specifies default handling of phases. See :hg:`help phases` for more
1629 information about working with phases.
1636 information about working with phases.
1630
1637
1631 ``publish``
1638 ``publish``
1632 Controls draft phase behavior when working as a server. When true,
1639 Controls draft phase behavior when working as a server. When true,
1633 pushed changesets are set to public in both client and server and
1640 pushed changesets are set to public in both client and server and
1634 pulled or cloned changesets are set to public in the client.
1641 pulled or cloned changesets are set to public in the client.
1635 (default: True)
1642 (default: True)
1636
1643
1637 ``new-commit``
1644 ``new-commit``
1638 Phase of newly-created commits.
1645 Phase of newly-created commits.
1639 (default: draft)
1646 (default: draft)
1640
1647
1641 ``checksubrepos``
1648 ``checksubrepos``
1642 Check the phase of the current revision of each subrepository. Allowed
1649 Check the phase of the current revision of each subrepository. Allowed
1643 values are "ignore", "follow" and "abort". For settings other than
1650 values are "ignore", "follow" and "abort". For settings other than
1644 "ignore", the phase of the current revision of each subrepository is
1651 "ignore", the phase of the current revision of each subrepository is
1645 checked before committing the parent repository. If any of those phases is
1652 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
1653 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
1654 "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
1655 either aborted (if checksubrepos is set to "abort") or the higher phase is
1649 used for the parent repository commit (if set to "follow").
1656 used for the parent repository commit (if set to "follow").
1650 (default: follow)
1657 (default: follow)
1651
1658
1652
1659
1653 ``profiling``
1660 ``profiling``
1654 -------------
1661 -------------
1655
1662
1656 Specifies profiling type, format, and file output. Two profilers are
1663 Specifies profiling type, format, and file output. Two profilers are
1657 supported: an instrumenting profiler (named ``ls``), and a sampling
1664 supported: an instrumenting profiler (named ``ls``), and a sampling
1658 profiler (named ``stat``).
1665 profiler (named ``stat``).
1659
1666
1660 In this section description, 'profiling data' stands for the raw data
1667 In this section description, 'profiling data' stands for the raw data
1661 collected during profiling, while 'profiling report' stands for a
1668 collected during profiling, while 'profiling report' stands for a
1662 statistical text report generated from the profiling data.
1669 statistical text report generated from the profiling data.
1663
1670
1664 ``enabled``
1671 ``enabled``
1665 Enable the profiler.
1672 Enable the profiler.
1666 (default: false)
1673 (default: false)
1667
1674
1668 This is equivalent to passing ``--profile`` on the command line.
1675 This is equivalent to passing ``--profile`` on the command line.
1669
1676
1670 ``type``
1677 ``type``
1671 The type of profiler to use.
1678 The type of profiler to use.
1672 (default: stat)
1679 (default: stat)
1673
1680
1674 ``ls``
1681 ``ls``
1675 Use Python's built-in instrumenting profiler. This profiler
1682 Use Python's built-in instrumenting profiler. This profiler
1676 works on all platforms, but each line number it reports is the
1683 works on all platforms, but each line number it reports is the
1677 first line of a function. This restriction makes it difficult to
1684 first line of a function. This restriction makes it difficult to
1678 identify the expensive parts of a non-trivial function.
1685 identify the expensive parts of a non-trivial function.
1679 ``stat``
1686 ``stat``
1680 Use a statistical profiler, statprof. This profiler is most
1687 Use a statistical profiler, statprof. This profiler is most
1681 useful for profiling commands that run for longer than about 0.1
1688 useful for profiling commands that run for longer than about 0.1
1682 seconds.
1689 seconds.
1683
1690
1684 ``format``
1691 ``format``
1685 Profiling format. Specific to the ``ls`` instrumenting profiler.
1692 Profiling format. Specific to the ``ls`` instrumenting profiler.
1686 (default: text)
1693 (default: text)
1687
1694
1688 ``text``
1695 ``text``
1689 Generate a profiling report. When saving to a file, it should be
1696 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
1697 noted that only the report is saved, and the profiling data is
1691 not kept.
1698 not kept.
1692 ``kcachegrind``
1699 ``kcachegrind``
1693 Format profiling data for kcachegrind use: when saving to a
1700 Format profiling data for kcachegrind use: when saving to a
1694 file, the generated file can directly be loaded into
1701 file, the generated file can directly be loaded into
1695 kcachegrind.
1702 kcachegrind.
1696
1703
1697 ``statformat``
1704 ``statformat``
1698 Profiling format for the ``stat`` profiler.
1705 Profiling format for the ``stat`` profiler.
1699 (default: hotpath)
1706 (default: hotpath)
1700
1707
1701 ``hotpath``
1708 ``hotpath``
1702 Show a tree-based display containing the hot path of execution (where
1709 Show a tree-based display containing the hot path of execution (where
1703 most time was spent).
1710 most time was spent).
1704 ``bymethod``
1711 ``bymethod``
1705 Show a table of methods ordered by how frequently they are active.
1712 Show a table of methods ordered by how frequently they are active.
1706 ``byline``
1713 ``byline``
1707 Show a table of lines in files ordered by how frequently they are active.
1714 Show a table of lines in files ordered by how frequently they are active.
1708 ``json``
1715 ``json``
1709 Render profiling data as JSON.
1716 Render profiling data as JSON.
1710
1717
1711 ``frequency``
1718 ``frequency``
1712 Sampling frequency. Specific to the ``stat`` sampling profiler.
1719 Sampling frequency. Specific to the ``stat`` sampling profiler.
1713 (default: 1000)
1720 (default: 1000)
1714
1721
1715 ``output``
1722 ``output``
1716 File path where profiling data or report should be saved. If the
1723 File path where profiling data or report should be saved. If the
1717 file exists, it is replaced. (default: None, data is printed on
1724 file exists, it is replaced. (default: None, data is printed on
1718 stderr)
1725 stderr)
1719
1726
1720 ``sort``
1727 ``sort``
1721 Sort field. Specific to the ``ls`` instrumenting profiler.
1728 Sort field. Specific to the ``ls`` instrumenting profiler.
1722 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1729 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1723 ``inlinetime``.
1730 ``inlinetime``.
1724 (default: inlinetime)
1731 (default: inlinetime)
1725
1732
1726 ``time-track``
1733 ``time-track``
1727 Control if the stat profiler track ``cpu`` or ``real`` time.
1734 Control if the stat profiler track ``cpu`` or ``real`` time.
1728 (default: ``cpu`` on Windows, otherwise ``real``)
1735 (default: ``cpu`` on Windows, otherwise ``real``)
1729
1736
1730 ``limit``
1737 ``limit``
1731 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1738 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1732 (default: 30)
1739 (default: 30)
1733
1740
1734 ``nested``
1741 ``nested``
1735 Show at most this number of lines of drill-down info after each main entry.
1742 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.
1743 This can help explain the difference between Total and Inline.
1737 Specific to the ``ls`` instrumenting profiler.
1744 Specific to the ``ls`` instrumenting profiler.
1738 (default: 0)
1745 (default: 0)
1739
1746
1740 ``showmin``
1747 ``showmin``
1741 Minimum fraction of samples an entry must have for it to be displayed.
1748 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
1749 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%``.
1750 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
1744
1751
1745 Only used by the ``stat`` profiler.
1752 Only used by the ``stat`` profiler.
1746
1753
1747 For the ``hotpath`` format, default is ``0.05``.
1754 For the ``hotpath`` format, default is ``0.05``.
1748 For the ``chrome`` format, default is ``0.005``.
1755 For the ``chrome`` format, default is ``0.005``.
1749
1756
1750 The option is unused on other formats.
1757 The option is unused on other formats.
1751
1758
1752 ``showmax``
1759 ``showmax``
1753 Maximum fraction of samples an entry can have before it is ignored in
1760 Maximum fraction of samples an entry can have before it is ignored in
1754 display. Values format is the same as ``showmin``.
1761 display. Values format is the same as ``showmin``.
1755
1762
1756 Only used by the ``stat`` profiler.
1763 Only used by the ``stat`` profiler.
1757
1764
1758 For the ``chrome`` format, default is ``0.999``.
1765 For the ``chrome`` format, default is ``0.999``.
1759
1766
1760 The option is unused on other formats.
1767 The option is unused on other formats.
1761
1768
1762 ``progress``
1769 ``progress``
1763 ------------
1770 ------------
1764
1771
1765 Mercurial commands can draw progress bars that are as informative as
1772 Mercurial commands can draw progress bars that are as informative as
1766 possible. Some progress bars only offer indeterminate information, while others
1773 possible. Some progress bars only offer indeterminate information, while others
1767 have a definite end point.
1774 have a definite end point.
1768
1775
1769 ``debug``
1776 ``debug``
1770 Whether to print debug info when updating the progress bar. (default: False)
1777 Whether to print debug info when updating the progress bar. (default: False)
1771
1778
1772 ``delay``
1779 ``delay``
1773 Number of seconds (float) before showing the progress bar. (default: 3)
1780 Number of seconds (float) before showing the progress bar. (default: 3)
1774
1781
1775 ``changedelay``
1782 ``changedelay``
1776 Minimum delay before showing a new topic. When set to less than 3 * refresh,
1783 Minimum delay before showing a new topic. When set to less than 3 * refresh,
1777 that value will be used instead. (default: 1)
1784 that value will be used instead. (default: 1)
1778
1785
1779 ``estimateinterval``
1786 ``estimateinterval``
1780 Maximum sampling interval in seconds for speed and estimated time
1787 Maximum sampling interval in seconds for speed and estimated time
1781 calculation. (default: 60)
1788 calculation. (default: 60)
1782
1789
1783 ``refresh``
1790 ``refresh``
1784 Time in seconds between refreshes of the progress bar. (default: 0.1)
1791 Time in seconds between refreshes of the progress bar. (default: 0.1)
1785
1792
1786 ``format``
1793 ``format``
1787 Format of the progress bar.
1794 Format of the progress bar.
1788
1795
1789 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1796 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1790 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1797 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1791 last 20 characters of the item, but this can be changed by adding either
1798 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
1799 ``-<num>`` which would take the last num characters, or ``+<num>`` for the
1793 first num characters.
1800 first num characters.
1794
1801
1795 (default: topic bar number estimate)
1802 (default: topic bar number estimate)
1796
1803
1797 ``width``
1804 ``width``
1798 If set, the maximum width of the progress information (that is, min(width,
1805 If set, the maximum width of the progress information (that is, min(width,
1799 term width) will be used).
1806 term width) will be used).
1800
1807
1801 ``clear-complete``
1808 ``clear-complete``
1802 Clear the progress bar after it's done. (default: True)
1809 Clear the progress bar after it's done. (default: True)
1803
1810
1804 ``disable``
1811 ``disable``
1805 If true, don't show a progress bar.
1812 If true, don't show a progress bar.
1806
1813
1807 ``assume-tty``
1814 ``assume-tty``
1808 If true, ALWAYS show a progress bar, unless disable is given.
1815 If true, ALWAYS show a progress bar, unless disable is given.
1809
1816
1810 ``rebase``
1817 ``rebase``
1811 ----------
1818 ----------
1812
1819
1813 ``evolution.allowdivergence``
1820 ``evolution.allowdivergence``
1814 Default to False, when True allow creating divergence when performing
1821 Default to False, when True allow creating divergence when performing
1815 rebase of obsolete changesets.
1822 rebase of obsolete changesets.
1816
1823
1817 ``revsetalias``
1824 ``revsetalias``
1818 ---------------
1825 ---------------
1819
1826
1820 Alias definitions for revsets. See :hg:`help revsets` for details.
1827 Alias definitions for revsets. See :hg:`help revsets` for details.
1821
1828
1822 ``rewrite``
1829 ``rewrite``
1823 -----------
1830 -----------
1824
1831
1825 ``backup-bundle``
1832 ``backup-bundle``
1826 Whether to save stripped changesets to a bundle file. (default: True)
1833 Whether to save stripped changesets to a bundle file. (default: True)
1827
1834
1828 ``update-timestamp``
1835 ``update-timestamp``
1829 If true, updates the date and time of the changeset to current. It is only
1836 If true, updates the date and time of the changeset to current. It is only
1830 applicable for hg amend in current version.
1837 applicable for hg amend in current version.
1831
1838
1832 ``storage``
1839 ``storage``
1833 -----------
1840 -----------
1834
1841
1835 Control the strategy Mercurial uses internally to store history. Options in this
1842 Control the strategy Mercurial uses internally to store history. Options in this
1836 category impact performance and repository size.
1843 category impact performance and repository size.
1837
1844
1838 ``revlog.optimize-delta-parent-choice``
1845 ``revlog.optimize-delta-parent-choice``
1839 When storing a merge revision, both parents will be equally considered as
1846 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
1847 a possible delta base. This results in better delta selection and improved
1841 revlog compression. This option is enabled by default.
1848 revlog compression. This option is enabled by default.
1842
1849
1843 Turning this option off can result in large increase of repository size for
1850 Turning this option off can result in large increase of repository size for
1844 repository with many merges.
1851 repository with many merges.
1845
1852
1846 ``revlog.reuse-external-delta-parent``
1853 ``revlog.reuse-external-delta-parent``
1847 Control the order in which delta parents are considered when adding new
1854 Control the order in which delta parents are considered when adding new
1848 revisions from an external source.
1855 revisions from an external source.
1849 (typically: apply bundle from `hg pull` or `hg push`).
1856 (typically: apply bundle from `hg pull` or `hg push`).
1850
1857
1851 New revisions are usually provided as a delta against other revisions. By
1858 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
1859 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
1860 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,
1861 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
1862 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
1863 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
1864 delta's parent that the server want to optimize. (lack of general delta, bad
1858 parents, choice, lack of sparse-revlog, etc).
1865 parents, choice, lack of sparse-revlog, etc).
1859
1866
1860 This option is enabled by default. Turning it off will ensure bad delta
1867 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
1868 parent choices from older client do not propagate to this repository, at
1862 the cost of a small increase in CPU consumption.
1869 the cost of a small increase in CPU consumption.
1863
1870
1864 Note: this option only control the order in which delta parents are
1871 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
1872 considered. Even when disabled, the existing delta from the source will be
1866 reused if the same delta parent is selected.
1873 reused if the same delta parent is selected.
1867
1874
1868 ``revlog.reuse-external-delta``
1875 ``revlog.reuse-external-delta``
1869 Control the reuse of delta from external source.
1876 Control the reuse of delta from external source.
1870 (typically: apply bundle from `hg pull` or `hg push`).
1877 (typically: apply bundle from `hg pull` or `hg push`).
1871
1878
1872 New revisions are usually provided as a delta against another revision. By
1879 New revisions are usually provided as a delta against another revision. By
1873 default, Mercurial will not recompute the same delta again, trusting
1880 default, Mercurial will not recompute the same delta again, trusting
1874 externally provided deltas. There have been rare cases of small adjustment
1881 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
1882 to the diffing algorithm in the past. So in some rare case, recomputing
1876 delta provided by ancient clients can provides better results. Disabling
1883 delta provided by ancient clients can provides better results. Disabling
1877 this option means going through a full delta recomputation for all incoming
1884 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
1885 revisions. It means a large increase in CPU usage and will slow operations
1879 down.
1886 down.
1880
1887
1881 This option is enabled by default. When disabled, it also disables the
1888 This option is enabled by default. When disabled, it also disables the
1882 related ``storage.revlog.reuse-external-delta-parent`` option.
1889 related ``storage.revlog.reuse-external-delta-parent`` option.
1883
1890
1884 ``revlog.zlib.level``
1891 ``revlog.zlib.level``
1885 Zlib compression level used when storing data into the repository. Accepted
1892 Zlib compression level used when storing data into the repository. Accepted
1886 Value range from 1 (lowest compression) to 9 (highest compression). Zlib
1893 Value range from 1 (lowest compression) to 9 (highest compression). Zlib
1887 default value is 6.
1894 default value is 6.
1888
1895
1889
1896
1890 ``revlog.zstd.level``
1897 ``revlog.zstd.level``
1891 zstd compression level used when storing data into the repository. Accepted
1898 zstd compression level used when storing data into the repository. Accepted
1892 Value range from 1 (lowest compression) to 22 (highest compression).
1899 Value range from 1 (lowest compression) to 22 (highest compression).
1893 (default 3)
1900 (default 3)
1894
1901
1895 ``server``
1902 ``server``
1896 ----------
1903 ----------
1897
1904
1898 Controls generic server settings.
1905 Controls generic server settings.
1899
1906
1900 ``bookmarks-pushkey-compat``
1907 ``bookmarks-pushkey-compat``
1901 Trigger pushkey hook when being pushed bookmark updates. This config exist
1908 Trigger pushkey hook when being pushed bookmark updates. This config exist
1902 for compatibility purpose (default to True)
1909 for compatibility purpose (default to True)
1903
1910
1904 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
1911 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
1905 movement we recommend you migrate them to ``txnclose-bookmark`` and
1912 movement we recommend you migrate them to ``txnclose-bookmark`` and
1906 ``pretxnclose-bookmark``.
1913 ``pretxnclose-bookmark``.
1907
1914
1908 ``compressionengines``
1915 ``compressionengines``
1909 List of compression engines and their relative priority to advertise
1916 List of compression engines and their relative priority to advertise
1910 to clients.
1917 to clients.
1911
1918
1912 The order of compression engines determines their priority, the first
1919 The order of compression engines determines their priority, the first
1913 having the highest priority. If a compression engine is not listed
1920 having the highest priority. If a compression engine is not listed
1914 here, it won't be advertised to clients.
1921 here, it won't be advertised to clients.
1915
1922
1916 If not set (the default), built-in defaults are used. Run
1923 If not set (the default), built-in defaults are used. Run
1917 :hg:`debuginstall` to list available compression engines and their
1924 :hg:`debuginstall` to list available compression engines and their
1918 default wire protocol priority.
1925 default wire protocol priority.
1919
1926
1920 Older Mercurial clients only support zlib compression and this setting
1927 Older Mercurial clients only support zlib compression and this setting
1921 has no effect for legacy clients.
1928 has no effect for legacy clients.
1922
1929
1923 ``uncompressed``
1930 ``uncompressed``
1924 Whether to allow clients to clone a repository using the
1931 Whether to allow clients to clone a repository using the
1925 uncompressed streaming protocol. This transfers about 40% more
1932 uncompressed streaming protocol. This transfers about 40% more
1926 data than a regular clone, but uses less memory and CPU on both
1933 data than a regular clone, but uses less memory and CPU on both
1927 server and client. Over a LAN (100 Mbps or better) or a very fast
1934 server and client. Over a LAN (100 Mbps or better) or a very fast
1928 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
1935 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
1929 regular clone. Over most WAN connections (anything slower than
1936 regular clone. Over most WAN connections (anything slower than
1930 about 6 Mbps), uncompressed streaming is slower, because of the
1937 about 6 Mbps), uncompressed streaming is slower, because of the
1931 extra data transfer overhead. This mode will also temporarily hold
1938 extra data transfer overhead. This mode will also temporarily hold
1932 the write lock while determining what data to transfer.
1939 the write lock while determining what data to transfer.
1933 (default: True)
1940 (default: True)
1934
1941
1935 ``uncompressedallowsecret``
1942 ``uncompressedallowsecret``
1936 Whether to allow stream clones when the repository contains secret
1943 Whether to allow stream clones when the repository contains secret
1937 changesets. (default: False)
1944 changesets. (default: False)
1938
1945
1939 ``preferuncompressed``
1946 ``preferuncompressed``
1940 When set, clients will try to use the uncompressed streaming
1947 When set, clients will try to use the uncompressed streaming
1941 protocol. (default: False)
1948 protocol. (default: False)
1942
1949
1943 ``disablefullbundle``
1950 ``disablefullbundle``
1944 When set, servers will refuse attempts to do pull-based clones.
1951 When set, servers will refuse attempts to do pull-based clones.
1945 If this option is set, ``preferuncompressed`` and/or clone bundles
1952 If this option is set, ``preferuncompressed`` and/or clone bundles
1946 are highly recommended. Partial clones will still be allowed.
1953 are highly recommended. Partial clones will still be allowed.
1947 (default: False)
1954 (default: False)
1948
1955
1949 ``streamunbundle``
1956 ``streamunbundle``
1950 When set, servers will apply data sent from the client directly,
1957 When set, servers will apply data sent from the client directly,
1951 otherwise it will be written to a temporary file first. This option
1958 otherwise it will be written to a temporary file first. This option
1952 effectively prevents concurrent pushes.
1959 effectively prevents concurrent pushes.
1953
1960
1954 ``pullbundle``
1961 ``pullbundle``
1955 When set, the server will check pullbundle.manifest for bundles
1962 When set, the server will check pullbundle.manifest for bundles
1956 covering the requested heads and common nodes. The first matching
1963 covering the requested heads and common nodes. The first matching
1957 entry will be streamed to the client.
1964 entry will be streamed to the client.
1958
1965
1959 For HTTP transport, the stream will still use zlib compression
1966 For HTTP transport, the stream will still use zlib compression
1960 for older clients.
1967 for older clients.
1961
1968
1962 ``concurrent-push-mode``
1969 ``concurrent-push-mode``
1963 Level of allowed race condition between two pushing clients.
1970 Level of allowed race condition between two pushing clients.
1964
1971
1965 - 'strict': push is abort if another client touched the repository
1972 - 'strict': push is abort if another client touched the repository
1966 while the push was preparing. (default)
1973 while the push was preparing. (default)
1967 - 'check-related': push is only aborted if it affects head that got also
1974 - 'check-related': push is only aborted if it affects head that got also
1968 affected while the push was preparing.
1975 affected while the push was preparing.
1969
1976
1970 This requires compatible client (version 4.3 and later). Old client will
1977 This requires compatible client (version 4.3 and later). Old client will
1971 use 'strict'.
1978 use 'strict'.
1972
1979
1973 ``validate``
1980 ``validate``
1974 Whether to validate the completeness of pushed changesets by
1981 Whether to validate the completeness of pushed changesets by
1975 checking that all new file revisions specified in manifests are
1982 checking that all new file revisions specified in manifests are
1976 present. (default: False)
1983 present. (default: False)
1977
1984
1978 ``maxhttpheaderlen``
1985 ``maxhttpheaderlen``
1979 Instruct HTTP clients not to send request headers longer than this
1986 Instruct HTTP clients not to send request headers longer than this
1980 many bytes. (default: 1024)
1987 many bytes. (default: 1024)
1981
1988
1982 ``bundle1``
1989 ``bundle1``
1983 Whether to allow clients to push and pull using the legacy bundle1
1990 Whether to allow clients to push and pull using the legacy bundle1
1984 exchange format. (default: True)
1991 exchange format. (default: True)
1985
1992
1986 ``bundle1gd``
1993 ``bundle1gd``
1987 Like ``bundle1`` but only used if the repository is using the
1994 Like ``bundle1`` but only used if the repository is using the
1988 *generaldelta* storage format. (default: True)
1995 *generaldelta* storage format. (default: True)
1989
1996
1990 ``bundle1.push``
1997 ``bundle1.push``
1991 Whether to allow clients to push using the legacy bundle1 exchange
1998 Whether to allow clients to push using the legacy bundle1 exchange
1992 format. (default: True)
1999 format. (default: True)
1993
2000
1994 ``bundle1gd.push``
2001 ``bundle1gd.push``
1995 Like ``bundle1.push`` but only used if the repository is using the
2002 Like ``bundle1.push`` but only used if the repository is using the
1996 *generaldelta* storage format. (default: True)
2003 *generaldelta* storage format. (default: True)
1997
2004
1998 ``bundle1.pull``
2005 ``bundle1.pull``
1999 Whether to allow clients to pull using the legacy bundle1 exchange
2006 Whether to allow clients to pull using the legacy bundle1 exchange
2000 format. (default: True)
2007 format. (default: True)
2001
2008
2002 ``bundle1gd.pull``
2009 ``bundle1gd.pull``
2003 Like ``bundle1.pull`` but only used if the repository is using the
2010 Like ``bundle1.pull`` but only used if the repository is using the
2004 *generaldelta* storage format. (default: True)
2011 *generaldelta* storage format. (default: True)
2005
2012
2006 Large repositories using the *generaldelta* storage format should
2013 Large repositories using the *generaldelta* storage format should
2007 consider setting this option because converting *generaldelta*
2014 consider setting this option because converting *generaldelta*
2008 repositories to the exchange format required by the bundle1 data
2015 repositories to the exchange format required by the bundle1 data
2009 format can consume a lot of CPU.
2016 format can consume a lot of CPU.
2010
2017
2011 ``bundle2.stream``
2018 ``bundle2.stream``
2012 Whether to allow clients to pull using the bundle2 streaming protocol.
2019 Whether to allow clients to pull using the bundle2 streaming protocol.
2013 (default: True)
2020 (default: True)
2014
2021
2015 ``zliblevel``
2022 ``zliblevel``
2016 Integer between ``-1`` and ``9`` that controls the zlib compression level
2023 Integer between ``-1`` and ``9`` that controls the zlib compression level
2017 for wire protocol commands that send zlib compressed output (notably the
2024 for wire protocol commands that send zlib compressed output (notably the
2018 commands that send repository history data).
2025 commands that send repository history data).
2019
2026
2020 The default (``-1``) uses the default zlib compression level, which is
2027 The default (``-1``) uses the default zlib compression level, which is
2021 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2028 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2022 maximum compression.
2029 maximum compression.
2023
2030
2024 Setting this option allows server operators to make trade-offs between
2031 Setting this option allows server operators to make trade-offs between
2025 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2032 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2026 but sends more bytes to clients.
2033 but sends more bytes to clients.
2027
2034
2028 This option only impacts the HTTP server.
2035 This option only impacts the HTTP server.
2029
2036
2030 ``zstdlevel``
2037 ``zstdlevel``
2031 Integer between ``1`` and ``22`` that controls the zstd compression level
2038 Integer between ``1`` and ``22`` that controls the zstd compression level
2032 for wire protocol commands. ``1`` is the minimal amount of compression and
2039 for wire protocol commands. ``1`` is the minimal amount of compression and
2033 ``22`` is the highest amount of compression.
2040 ``22`` is the highest amount of compression.
2034
2041
2035 The default (``3``) should be significantly faster than zlib while likely
2042 The default (``3``) should be significantly faster than zlib while likely
2036 delivering better compression ratios.
2043 delivering better compression ratios.
2037
2044
2038 This option only impacts the HTTP server.
2045 This option only impacts the HTTP server.
2039
2046
2040 See also ``server.zliblevel``.
2047 See also ``server.zliblevel``.
2041
2048
2042 ``view``
2049 ``view``
2043 Repository filter used when exchanging revisions with the peer.
2050 Repository filter used when exchanging revisions with the peer.
2044
2051
2045 The default view (``served``) excludes secret and hidden changesets.
2052 The default view (``served``) excludes secret and hidden changesets.
2046 Another useful value is ``immutable`` (no draft, secret or hidden changesets).
2053 Another useful value is ``immutable`` (no draft, secret or hidden changesets).
2047
2054
2048 ``smtp``
2055 ``smtp``
2049 --------
2056 --------
2050
2057
2051 Configuration for extensions that need to send email messages.
2058 Configuration for extensions that need to send email messages.
2052
2059
2053 ``host``
2060 ``host``
2054 Host name of mail server, e.g. "mail.example.com".
2061 Host name of mail server, e.g. "mail.example.com".
2055
2062
2056 ``port``
2063 ``port``
2057 Optional. Port to connect to on mail server. (default: 465 if
2064 Optional. Port to connect to on mail server. (default: 465 if
2058 ``tls`` is smtps; 25 otherwise)
2065 ``tls`` is smtps; 25 otherwise)
2059
2066
2060 ``tls``
2067 ``tls``
2061 Optional. Method to enable TLS when connecting to mail server: starttls,
2068 Optional. Method to enable TLS when connecting to mail server: starttls,
2062 smtps or none. (default: none)
2069 smtps or none. (default: none)
2063
2070
2064 ``username``
2071 ``username``
2065 Optional. User name for authenticating with the SMTP server.
2072 Optional. User name for authenticating with the SMTP server.
2066 (default: None)
2073 (default: None)
2067
2074
2068 ``password``
2075 ``password``
2069 Optional. Password for authenticating with the SMTP server. If not
2076 Optional. Password for authenticating with the SMTP server. If not
2070 specified, interactive sessions will prompt the user for a
2077 specified, interactive sessions will prompt the user for a
2071 password; non-interactive sessions will fail. (default: None)
2078 password; non-interactive sessions will fail. (default: None)
2072
2079
2073 ``local_hostname``
2080 ``local_hostname``
2074 Optional. The hostname that the sender can use to identify
2081 Optional. The hostname that the sender can use to identify
2075 itself to the MTA.
2082 itself to the MTA.
2076
2083
2077
2084
2078 ``subpaths``
2085 ``subpaths``
2079 ------------
2086 ------------
2080
2087
2081 Subrepository source URLs can go stale if a remote server changes name
2088 Subrepository source URLs can go stale if a remote server changes name
2082 or becomes temporarily unavailable. This section lets you define
2089 or becomes temporarily unavailable. This section lets you define
2083 rewrite rules of the form::
2090 rewrite rules of the form::
2084
2091
2085 <pattern> = <replacement>
2092 <pattern> = <replacement>
2086
2093
2087 where ``pattern`` is a regular expression matching a subrepository
2094 where ``pattern`` is a regular expression matching a subrepository
2088 source URL and ``replacement`` is the replacement string used to
2095 source URL and ``replacement`` is the replacement string used to
2089 rewrite it. Groups can be matched in ``pattern`` and referenced in
2096 rewrite it. Groups can be matched in ``pattern`` and referenced in
2090 ``replacements``. For instance::
2097 ``replacements``. For instance::
2091
2098
2092 http://server/(.*)-hg/ = http://hg.server/\1/
2099 http://server/(.*)-hg/ = http://hg.server/\1/
2093
2100
2094 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2101 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2095
2102
2096 Relative subrepository paths are first made absolute, and the
2103 Relative subrepository paths are first made absolute, and the
2097 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2104 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2098 doesn't match the full path, an attempt is made to apply it on the
2105 doesn't match the full path, an attempt is made to apply it on the
2099 relative path alone. The rules are applied in definition order.
2106 relative path alone. The rules are applied in definition order.
2100
2107
2101 ``subrepos``
2108 ``subrepos``
2102 ------------
2109 ------------
2103
2110
2104 This section contains options that control the behavior of the
2111 This section contains options that control the behavior of the
2105 subrepositories feature. See also :hg:`help subrepos`.
2112 subrepositories feature. See also :hg:`help subrepos`.
2106
2113
2107 Security note: auditing in Mercurial is known to be insufficient to
2114 Security note: auditing in Mercurial is known to be insufficient to
2108 prevent clone-time code execution with carefully constructed Git
2115 prevent clone-time code execution with carefully constructed Git
2109 subrepos. It is unknown if a similar detect is present in Subversion
2116 subrepos. It is unknown if a similar detect is present in Subversion
2110 subrepos. Both Git and Subversion subrepos are disabled by default
2117 subrepos. Both Git and Subversion subrepos are disabled by default
2111 out of security concerns. These subrepo types can be enabled using
2118 out of security concerns. These subrepo types can be enabled using
2112 the respective options below.
2119 the respective options below.
2113
2120
2114 ``allowed``
2121 ``allowed``
2115 Whether subrepositories are allowed in the working directory.
2122 Whether subrepositories are allowed in the working directory.
2116
2123
2117 When false, commands involving subrepositories (like :hg:`update`)
2124 When false, commands involving subrepositories (like :hg:`update`)
2118 will fail for all subrepository types.
2125 will fail for all subrepository types.
2119 (default: true)
2126 (default: true)
2120
2127
2121 ``hg:allowed``
2128 ``hg:allowed``
2122 Whether Mercurial subrepositories are allowed in the working
2129 Whether Mercurial subrepositories are allowed in the working
2123 directory. This option only has an effect if ``subrepos.allowed``
2130 directory. This option only has an effect if ``subrepos.allowed``
2124 is true.
2131 is true.
2125 (default: true)
2132 (default: true)
2126
2133
2127 ``git:allowed``
2134 ``git:allowed``
2128 Whether Git subrepositories are allowed in the working directory.
2135 Whether Git subrepositories are allowed in the working directory.
2129 This option only has an effect if ``subrepos.allowed`` is true.
2136 This option only has an effect if ``subrepos.allowed`` is true.
2130
2137
2131 See the security note above before enabling Git subrepos.
2138 See the security note above before enabling Git subrepos.
2132 (default: false)
2139 (default: false)
2133
2140
2134 ``svn:allowed``
2141 ``svn:allowed``
2135 Whether Subversion subrepositories are allowed in the working
2142 Whether Subversion subrepositories are allowed in the working
2136 directory. This option only has an effect if ``subrepos.allowed``
2143 directory. This option only has an effect if ``subrepos.allowed``
2137 is true.
2144 is true.
2138
2145
2139 See the security note above before enabling Subversion subrepos.
2146 See the security note above before enabling Subversion subrepos.
2140 (default: false)
2147 (default: false)
2141
2148
2142 ``templatealias``
2149 ``templatealias``
2143 -----------------
2150 -----------------
2144
2151
2145 Alias definitions for templates. See :hg:`help templates` for details.
2152 Alias definitions for templates. See :hg:`help templates` for details.
2146
2153
2147 ``templates``
2154 ``templates``
2148 -------------
2155 -------------
2149
2156
2150 Use the ``[templates]`` section to define template strings.
2157 Use the ``[templates]`` section to define template strings.
2151 See :hg:`help templates` for details.
2158 See :hg:`help templates` for details.
2152
2159
2153 ``trusted``
2160 ``trusted``
2154 -----------
2161 -----------
2155
2162
2156 Mercurial will not use the settings in the
2163 Mercurial will not use the settings in the
2157 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2164 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2158 user or to a trusted group, as various hgrc features allow arbitrary
2165 user or to a trusted group, as various hgrc features allow arbitrary
2159 commands to be run. This issue is often encountered when configuring
2166 commands to be run. This issue is often encountered when configuring
2160 hooks or extensions for shared repositories or servers. However,
2167 hooks or extensions for shared repositories or servers. However,
2161 the web interface will use some safe settings from the ``[web]``
2168 the web interface will use some safe settings from the ``[web]``
2162 section.
2169 section.
2163
2170
2164 This section specifies what users and groups are trusted. The
2171 This section specifies what users and groups are trusted. The
2165 current user is always trusted. To trust everybody, list a user or a
2172 current user is always trusted. To trust everybody, list a user or a
2166 group with name ``*``. These settings must be placed in an
2173 group with name ``*``. These settings must be placed in an
2167 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2174 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2168 user or service running Mercurial.
2175 user or service running Mercurial.
2169
2176
2170 ``users``
2177 ``users``
2171 Comma-separated list of trusted users.
2178 Comma-separated list of trusted users.
2172
2179
2173 ``groups``
2180 ``groups``
2174 Comma-separated list of trusted groups.
2181 Comma-separated list of trusted groups.
2175
2182
2176
2183
2177 ``ui``
2184 ``ui``
2178 ------
2185 ------
2179
2186
2180 User interface controls.
2187 User interface controls.
2181
2188
2182 ``archivemeta``
2189 ``archivemeta``
2183 Whether to include the .hg_archival.txt file containing meta data
2190 Whether to include the .hg_archival.txt file containing meta data
2184 (hashes for the repository base and for tip) in archives created
2191 (hashes for the repository base and for tip) in archives created
2185 by the :hg:`archive` command or downloaded via hgweb.
2192 by the :hg:`archive` command or downloaded via hgweb.
2186 (default: True)
2193 (default: True)
2187
2194
2188 ``askusername``
2195 ``askusername``
2189 Whether to prompt for a username when committing. If True, and
2196 Whether to prompt for a username when committing. If True, and
2190 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2197 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2191 be prompted to enter a username. If no username is entered, the
2198 be prompted to enter a username. If no username is entered, the
2192 default ``USER@HOST`` is used instead.
2199 default ``USER@HOST`` is used instead.
2193 (default: False)
2200 (default: False)
2194
2201
2195 ``clonebundles``
2202 ``clonebundles``
2196 Whether the "clone bundles" feature is enabled.
2203 Whether the "clone bundles" feature is enabled.
2197
2204
2198 When enabled, :hg:`clone` may download and apply a server-advertised
2205 When enabled, :hg:`clone` may download and apply a server-advertised
2199 bundle file from a URL instead of using the normal exchange mechanism.
2206 bundle file from a URL instead of using the normal exchange mechanism.
2200
2207
2201 This can likely result in faster and more reliable clones.
2208 This can likely result in faster and more reliable clones.
2202
2209
2203 (default: True)
2210 (default: True)
2204
2211
2205 ``clonebundlefallback``
2212 ``clonebundlefallback``
2206 Whether failure to apply an advertised "clone bundle" from a server
2213 Whether failure to apply an advertised "clone bundle" from a server
2207 should result in fallback to a regular clone.
2214 should result in fallback to a regular clone.
2208
2215
2209 This is disabled by default because servers advertising "clone
2216 This is disabled by default because servers advertising "clone
2210 bundles" often do so to reduce server load. If advertised bundles
2217 bundles" often do so to reduce server load. If advertised bundles
2211 start mass failing and clients automatically fall back to a regular
2218 start mass failing and clients automatically fall back to a regular
2212 clone, this would add significant and unexpected load to the server
2219 clone, this would add significant and unexpected load to the server
2213 since the server is expecting clone operations to be offloaded to
2220 since the server is expecting clone operations to be offloaded to
2214 pre-generated bundles. Failing fast (the default behavior) ensures
2221 pre-generated bundles. Failing fast (the default behavior) ensures
2215 clients don't overwhelm the server when "clone bundle" application
2222 clients don't overwhelm the server when "clone bundle" application
2216 fails.
2223 fails.
2217
2224
2218 (default: False)
2225 (default: False)
2219
2226
2220 ``clonebundleprefers``
2227 ``clonebundleprefers``
2221 Defines preferences for which "clone bundles" to use.
2228 Defines preferences for which "clone bundles" to use.
2222
2229
2223 Servers advertising "clone bundles" may advertise multiple available
2230 Servers advertising "clone bundles" may advertise multiple available
2224 bundles. Each bundle may have different attributes, such as the bundle
2231 bundles. Each bundle may have different attributes, such as the bundle
2225 type and compression format. This option is used to prefer a particular
2232 type and compression format. This option is used to prefer a particular
2226 bundle over another.
2233 bundle over another.
2227
2234
2228 The following keys are defined by Mercurial:
2235 The following keys are defined by Mercurial:
2229
2236
2230 BUNDLESPEC
2237 BUNDLESPEC
2231 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2238 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2232 e.g. ``gzip-v2`` or ``bzip2-v1``.
2239 e.g. ``gzip-v2`` or ``bzip2-v1``.
2233
2240
2234 COMPRESSION
2241 COMPRESSION
2235 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2242 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2236
2243
2237 Server operators may define custom keys.
2244 Server operators may define custom keys.
2238
2245
2239 Example values: ``COMPRESSION=bzip2``,
2246 Example values: ``COMPRESSION=bzip2``,
2240 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2247 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2241
2248
2242 By default, the first bundle advertised by the server is used.
2249 By default, the first bundle advertised by the server is used.
2243
2250
2244 ``color``
2251 ``color``
2245 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2252 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2246 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2253 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2247 seems possible. See :hg:`help color` for details.
2254 seems possible. See :hg:`help color` for details.
2248
2255
2249 ``commitsubrepos``
2256 ``commitsubrepos``
2250 Whether to commit modified subrepositories when committing the
2257 Whether to commit modified subrepositories when committing the
2251 parent repository. If False and one subrepository has uncommitted
2258 parent repository. If False and one subrepository has uncommitted
2252 changes, abort the commit.
2259 changes, abort the commit.
2253 (default: False)
2260 (default: False)
2254
2261
2255 ``debug``
2262 ``debug``
2256 Print debugging information. (default: False)
2263 Print debugging information. (default: False)
2257
2264
2258 ``editor``
2265 ``editor``
2259 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2266 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2260
2267
2261 ``fallbackencoding``
2268 ``fallbackencoding``
2262 Encoding to try if it's not possible to decode the changelog using
2269 Encoding to try if it's not possible to decode the changelog using
2263 UTF-8. (default: ISO-8859-1)
2270 UTF-8. (default: ISO-8859-1)
2264
2271
2265 ``graphnodetemplate``
2272 ``graphnodetemplate``
2266 The template used to print changeset nodes in an ASCII revision graph.
2273 The template used to print changeset nodes in an ASCII revision graph.
2267 (default: ``{graphnode}``)
2274 (default: ``{graphnode}``)
2268
2275
2269 ``ignore``
2276 ``ignore``
2270 A file to read per-user ignore patterns from. This file should be
2277 A file to read per-user ignore patterns from. This file should be
2271 in the same format as a repository-wide .hgignore file. Filenames
2278 in the same format as a repository-wide .hgignore file. Filenames
2272 are relative to the repository root. This option supports hook syntax,
2279 are relative to the repository root. This option supports hook syntax,
2273 so if you want to specify multiple ignore files, you can do so by
2280 so if you want to specify multiple ignore files, you can do so by
2274 setting something like ``ignore.other = ~/.hgignore2``. For details
2281 setting something like ``ignore.other = ~/.hgignore2``. For details
2275 of the ignore file format, see the ``hgignore(5)`` man page.
2282 of the ignore file format, see the ``hgignore(5)`` man page.
2276
2283
2277 ``interactive``
2284 ``interactive``
2278 Allow to prompt the user. (default: True)
2285 Allow to prompt the user. (default: True)
2279
2286
2280 ``interface``
2287 ``interface``
2281 Select the default interface for interactive features (default: text).
2288 Select the default interface for interactive features (default: text).
2282 Possible values are 'text' and 'curses'.
2289 Possible values are 'text' and 'curses'.
2283
2290
2284 ``interface.chunkselector``
2291 ``interface.chunkselector``
2285 Select the interface for change recording (e.g. :hg:`commit -i`).
2292 Select the interface for change recording (e.g. :hg:`commit -i`).
2286 Possible values are 'text' and 'curses'.
2293 Possible values are 'text' and 'curses'.
2287 This config overrides the interface specified by ui.interface.
2294 This config overrides the interface specified by ui.interface.
2288
2295
2289 ``large-file-limit``
2296 ``large-file-limit``
2290 Largest file size that gives no memory use warning.
2297 Largest file size that gives no memory use warning.
2291 Possible values are integers or 0 to disable the check.
2298 Possible values are integers or 0 to disable the check.
2292 (default: 10000000)
2299 (default: 10000000)
2293
2300
2294 ``logtemplate``
2301 ``logtemplate``
2295 Template string for commands that print changesets.
2302 Template string for commands that print changesets.
2296
2303
2297 ``merge``
2304 ``merge``
2298 The conflict resolution program to use during a manual merge.
2305 The conflict resolution program to use during a manual merge.
2299 For more information on merge tools see :hg:`help merge-tools`.
2306 For more information on merge tools see :hg:`help merge-tools`.
2300 For configuring merge tools see the ``[merge-tools]`` section.
2307 For configuring merge tools see the ``[merge-tools]`` section.
2301
2308
2302 ``mergemarkers``
2309 ``mergemarkers``
2303 Sets the merge conflict marker label styling. The ``detailed``
2310 Sets the merge conflict marker label styling. The ``detailed``
2304 style uses the ``mergemarkertemplate`` setting to style the labels.
2311 style uses the ``mergemarkertemplate`` setting to style the labels.
2305 The ``basic`` style just uses 'local' and 'other' as the marker label.
2312 The ``basic`` style just uses 'local' and 'other' as the marker label.
2306 One of ``basic`` or ``detailed``.
2313 One of ``basic`` or ``detailed``.
2307 (default: ``basic``)
2314 (default: ``basic``)
2308
2315
2309 ``mergemarkertemplate``
2316 ``mergemarkertemplate``
2310 The template used to print the commit description next to each conflict
2317 The template used to print the commit description next to each conflict
2311 marker during merge conflicts. See :hg:`help templates` for the template
2318 marker during merge conflicts. See :hg:`help templates` for the template
2312 format.
2319 format.
2313
2320
2314 Defaults to showing the hash, tags, branches, bookmarks, author, and
2321 Defaults to showing the hash, tags, branches, bookmarks, author, and
2315 the first line of the commit description.
2322 the first line of the commit description.
2316
2323
2317 If you use non-ASCII characters in names for tags, branches, bookmarks,
2324 If you use non-ASCII characters in names for tags, branches, bookmarks,
2318 authors, and/or commit descriptions, you must pay attention to encodings of
2325 authors, and/or commit descriptions, you must pay attention to encodings of
2319 managed files. At template expansion, non-ASCII characters use the encoding
2326 managed files. At template expansion, non-ASCII characters use the encoding
2320 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2327 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2321 environment variables that govern your locale. If the encoding of the merge
2328 environment variables that govern your locale. If the encoding of the merge
2322 markers is different from the encoding of the merged files,
2329 markers is different from the encoding of the merged files,
2323 serious problems may occur.
2330 serious problems may occur.
2324
2331
2325 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2332 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2326
2333
2327 ``message-output``
2334 ``message-output``
2328 Where to write status and error messages. (default: ``stdio``)
2335 Where to write status and error messages. (default: ``stdio``)
2329
2336
2330 ``stderr``
2337 ``stderr``
2331 Everything to stderr.
2338 Everything to stderr.
2332 ``stdio``
2339 ``stdio``
2333 Status to stdout, and error to stderr.
2340 Status to stdout, and error to stderr.
2334
2341
2335 ``origbackuppath``
2342 ``origbackuppath``
2336 The path to a directory used to store generated .orig files. If the path is
2343 The path to a directory used to store generated .orig files. If the path is
2337 not a directory, one will be created. If set, files stored in this
2344 not a directory, one will be created. If set, files stored in this
2338 directory have the same name as the original file and do not have a .orig
2345 directory have the same name as the original file and do not have a .orig
2339 suffix.
2346 suffix.
2340
2347
2341 ``paginate``
2348 ``paginate``
2342 Control the pagination of command output (default: True). See :hg:`help pager`
2349 Control the pagination of command output (default: True). See :hg:`help pager`
2343 for details.
2350 for details.
2344
2351
2345 ``patch``
2352 ``patch``
2346 An optional external tool that ``hg import`` and some extensions
2353 An optional external tool that ``hg import`` and some extensions
2347 will use for applying patches. By default Mercurial uses an
2354 will use for applying patches. By default Mercurial uses an
2348 internal patch utility. The external tool must work as the common
2355 internal patch utility. The external tool must work as the common
2349 Unix ``patch`` program. In particular, it must accept a ``-p``
2356 Unix ``patch`` program. In particular, it must accept a ``-p``
2350 argument to strip patch headers, a ``-d`` argument to specify the
2357 argument to strip patch headers, a ``-d`` argument to specify the
2351 current directory, a file name to patch, and a patch file to take
2358 current directory, a file name to patch, and a patch file to take
2352 from stdin.
2359 from stdin.
2353
2360
2354 It is possible to specify a patch tool together with extra
2361 It is possible to specify a patch tool together with extra
2355 arguments. For example, setting this option to ``patch --merge``
2362 arguments. For example, setting this option to ``patch --merge``
2356 will use the ``patch`` program with its 2-way merge option.
2363 will use the ``patch`` program with its 2-way merge option.
2357
2364
2358 ``portablefilenames``
2365 ``portablefilenames``
2359 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2366 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2360 (default: ``warn``)
2367 (default: ``warn``)
2361
2368
2362 ``warn``
2369 ``warn``
2363 Print a warning message on POSIX platforms, if a file with a non-portable
2370 Print a warning message on POSIX platforms, if a file with a non-portable
2364 filename is added (e.g. a file with a name that can't be created on
2371 filename is added (e.g. a file with a name that can't be created on
2365 Windows because it contains reserved parts like ``AUX``, reserved
2372 Windows because it contains reserved parts like ``AUX``, reserved
2366 characters like ``:``, or would cause a case collision with an existing
2373 characters like ``:``, or would cause a case collision with an existing
2367 file).
2374 file).
2368
2375
2369 ``ignore``
2376 ``ignore``
2370 Don't print a warning.
2377 Don't print a warning.
2371
2378
2372 ``abort``
2379 ``abort``
2373 The command is aborted.
2380 The command is aborted.
2374
2381
2375 ``true``
2382 ``true``
2376 Alias for ``warn``.
2383 Alias for ``warn``.
2377
2384
2378 ``false``
2385 ``false``
2379 Alias for ``ignore``.
2386 Alias for ``ignore``.
2380
2387
2381 .. container:: windows
2388 .. container:: windows
2382
2389
2383 On Windows, this configuration option is ignored and the command aborted.
2390 On Windows, this configuration option is ignored and the command aborted.
2384
2391
2385 ``pre-merge-tool-output-template``
2392 ``pre-merge-tool-output-template``
2386 A template that is printed before executing an external merge tool. This can
2393 A template that is printed before executing an external merge tool. This can
2387 be used to print out additional context that might be useful to have during
2394 be used to print out additional context that might be useful to have during
2388 the conflict resolution, such as the description of the various commits
2395 the conflict resolution, such as the description of the various commits
2389 involved or bookmarks/tags.
2396 involved or bookmarks/tags.
2390
2397
2391 Additional information is available in the ``local`, ``base``, and ``other``
2398 Additional information is available in the ``local`, ``base``, and ``other``
2392 dicts. For example: ``{local.label}``, ``{base.name}``, or
2399 dicts. For example: ``{local.label}``, ``{base.name}``, or
2393 ``{other.islink}``.
2400 ``{other.islink}``.
2394
2401
2395 ``quiet``
2402 ``quiet``
2396 Reduce the amount of output printed.
2403 Reduce the amount of output printed.
2397 (default: False)
2404 (default: False)
2398
2405
2399 ``relative-paths``
2406 ``relative-paths``
2400 Prefer relative paths in the UI.
2407 Prefer relative paths in the UI.
2401
2408
2402 ``remotecmd``
2409 ``remotecmd``
2403 Remote command to use for clone/push/pull operations.
2410 Remote command to use for clone/push/pull operations.
2404 (default: ``hg``)
2411 (default: ``hg``)
2405
2412
2406 ``report_untrusted``
2413 ``report_untrusted``
2407 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2414 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2408 trusted user or group.
2415 trusted user or group.
2409 (default: True)
2416 (default: True)
2410
2417
2411 ``slash``
2418 ``slash``
2412 (Deprecated. Use ``slashpath`` template filter instead.)
2419 (Deprecated. Use ``slashpath`` template filter instead.)
2413
2420
2414 Display paths using a slash (``/``) as the path separator. This
2421 Display paths using a slash (``/``) as the path separator. This
2415 only makes a difference on systems where the default path
2422 only makes a difference on systems where the default path
2416 separator is not the slash character (e.g. Windows uses the
2423 separator is not the slash character (e.g. Windows uses the
2417 backslash character (``\``)).
2424 backslash character (``\``)).
2418 (default: False)
2425 (default: False)
2419
2426
2420 ``statuscopies``
2427 ``statuscopies``
2421 Display copies in the status command.
2428 Display copies in the status command.
2422
2429
2423 ``ssh``
2430 ``ssh``
2424 Command to use for SSH connections. (default: ``ssh``)
2431 Command to use for SSH connections. (default: ``ssh``)
2425
2432
2426 ``ssherrorhint``
2433 ``ssherrorhint``
2427 A hint shown to the user in the case of SSH error (e.g.
2434 A hint shown to the user in the case of SSH error (e.g.
2428 ``Please see http://company/internalwiki/ssh.html``)
2435 ``Please see http://company/internalwiki/ssh.html``)
2429
2436
2430 ``strict``
2437 ``strict``
2431 Require exact command names, instead of allowing unambiguous
2438 Require exact command names, instead of allowing unambiguous
2432 abbreviations. (default: False)
2439 abbreviations. (default: False)
2433
2440
2434 ``style``
2441 ``style``
2435 Name of style to use for command output.
2442 Name of style to use for command output.
2436
2443
2437 ``supportcontact``
2444 ``supportcontact``
2438 A URL where users should report a Mercurial traceback. Use this if you are a
2445 A URL where users should report a Mercurial traceback. Use this if you are a
2439 large organisation with its own Mercurial deployment process and crash
2446 large organisation with its own Mercurial deployment process and crash
2440 reports should be addressed to your internal support.
2447 reports should be addressed to your internal support.
2441
2448
2442 ``textwidth``
2449 ``textwidth``
2443 Maximum width of help text. A longer line generated by ``hg help`` or
2450 Maximum width of help text. A longer line generated by ``hg help`` or
2444 ``hg subcommand --help`` will be broken after white space to get this
2451 ``hg subcommand --help`` will be broken after white space to get this
2445 width or the terminal width, whichever comes first.
2452 width or the terminal width, whichever comes first.
2446 A non-positive value will disable this and the terminal width will be
2453 A non-positive value will disable this and the terminal width will be
2447 used. (default: 78)
2454 used. (default: 78)
2448
2455
2449 ``timeout``
2456 ``timeout``
2450 The timeout used when a lock is held (in seconds), a negative value
2457 The timeout used when a lock is held (in seconds), a negative value
2451 means no timeout. (default: 600)
2458 means no timeout. (default: 600)
2452
2459
2453 ``timeout.warn``
2460 ``timeout.warn``
2454 Time (in seconds) before a warning is printed about held lock. A negative
2461 Time (in seconds) before a warning is printed about held lock. A negative
2455 value means no warning. (default: 0)
2462 value means no warning. (default: 0)
2456
2463
2457 ``traceback``
2464 ``traceback``
2458 Mercurial always prints a traceback when an unknown exception
2465 Mercurial always prints a traceback when an unknown exception
2459 occurs. Setting this to True will make Mercurial print a traceback
2466 occurs. Setting this to True will make Mercurial print a traceback
2460 on all exceptions, even those recognized by Mercurial (such as
2467 on all exceptions, even those recognized by Mercurial (such as
2461 IOError or MemoryError). (default: False)
2468 IOError or MemoryError). (default: False)
2462
2469
2463 ``tweakdefaults``
2470 ``tweakdefaults``
2464
2471
2465 By default Mercurial's behavior changes very little from release
2472 By default Mercurial's behavior changes very little from release
2466 to release, but over time the recommended config settings
2473 to release, but over time the recommended config settings
2467 shift. Enable this config to opt in to get automatic tweaks to
2474 shift. Enable this config to opt in to get automatic tweaks to
2468 Mercurial's behavior over time. This config setting will have no
2475 Mercurial's behavior over time. This config setting will have no
2469 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2476 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2470 not include ``tweakdefaults``. (default: False)
2477 not include ``tweakdefaults``. (default: False)
2471
2478
2472 It currently means::
2479 It currently means::
2473
2480
2474 .. tweakdefaultsmarker
2481 .. tweakdefaultsmarker
2475
2482
2476 ``username``
2483 ``username``
2477 The committer of a changeset created when running "commit".
2484 The committer of a changeset created when running "commit".
2478 Typically a person's name and email address, e.g. ``Fred Widget
2485 Typically a person's name and email address, e.g. ``Fred Widget
2479 <fred@example.com>``. Environment variables in the
2486 <fred@example.com>``. Environment variables in the
2480 username are expanded.
2487 username are expanded.
2481
2488
2482 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2489 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2483 hgrc is empty, e.g. if the system admin set ``username =`` in the
2490 hgrc is empty, e.g. if the system admin set ``username =`` in the
2484 system hgrc, it has to be specified manually or in a different
2491 system hgrc, it has to be specified manually or in a different
2485 hgrc file)
2492 hgrc file)
2486
2493
2487 ``verbose``
2494 ``verbose``
2488 Increase the amount of output printed. (default: False)
2495 Increase the amount of output printed. (default: False)
2489
2496
2490
2497
2491 ``web``
2498 ``web``
2492 -------
2499 -------
2493
2500
2494 Web interface configuration. The settings in this section apply to
2501 Web interface configuration. The settings in this section apply to
2495 both the builtin webserver (started by :hg:`serve`) and the script you
2502 both the builtin webserver (started by :hg:`serve`) and the script you
2496 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2503 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2497 and WSGI).
2504 and WSGI).
2498
2505
2499 The Mercurial webserver does no authentication (it does not prompt for
2506 The Mercurial webserver does no authentication (it does not prompt for
2500 usernames and passwords to validate *who* users are), but it does do
2507 usernames and passwords to validate *who* users are), but it does do
2501 authorization (it grants or denies access for *authenticated users*
2508 authorization (it grants or denies access for *authenticated users*
2502 based on settings in this section). You must either configure your
2509 based on settings in this section). You must either configure your
2503 webserver to do authentication for you, or disable the authorization
2510 webserver to do authentication for you, or disable the authorization
2504 checks.
2511 checks.
2505
2512
2506 For a quick setup in a trusted environment, e.g., a private LAN, where
2513 For a quick setup in a trusted environment, e.g., a private LAN, where
2507 you want it to accept pushes from anybody, you can use the following
2514 you want it to accept pushes from anybody, you can use the following
2508 command line::
2515 command line::
2509
2516
2510 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2517 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2511
2518
2512 Note that this will allow anybody to push anything to the server and
2519 Note that this will allow anybody to push anything to the server and
2513 that this should not be used for public servers.
2520 that this should not be used for public servers.
2514
2521
2515 The full set of options is:
2522 The full set of options is:
2516
2523
2517 ``accesslog``
2524 ``accesslog``
2518 Where to output the access log. (default: stdout)
2525 Where to output the access log. (default: stdout)
2519
2526
2520 ``address``
2527 ``address``
2521 Interface address to bind to. (default: all)
2528 Interface address to bind to. (default: all)
2522
2529
2523 ``allow-archive``
2530 ``allow-archive``
2524 List of archive format (bz2, gz, zip) allowed for downloading.
2531 List of archive format (bz2, gz, zip) allowed for downloading.
2525 (default: empty)
2532 (default: empty)
2526
2533
2527 ``allowbz2``
2534 ``allowbz2``
2528 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2535 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2529 revisions.
2536 revisions.
2530 (default: False)
2537 (default: False)
2531
2538
2532 ``allowgz``
2539 ``allowgz``
2533 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2540 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2534 revisions.
2541 revisions.
2535 (default: False)
2542 (default: False)
2536
2543
2537 ``allow-pull``
2544 ``allow-pull``
2538 Whether to allow pulling from the repository. (default: True)
2545 Whether to allow pulling from the repository. (default: True)
2539
2546
2540 ``allow-push``
2547 ``allow-push``
2541 Whether to allow pushing to the repository. If empty or not set,
2548 Whether to allow pushing to the repository. If empty or not set,
2542 pushing is not allowed. If the special value ``*``, any remote
2549 pushing is not allowed. If the special value ``*``, any remote
2543 user can push, including unauthenticated users. Otherwise, the
2550 user can push, including unauthenticated users. Otherwise, the
2544 remote user must have been authenticated, and the authenticated
2551 remote user must have been authenticated, and the authenticated
2545 user name must be present in this list. The contents of the
2552 user name must be present in this list. The contents of the
2546 allow-push list are examined after the deny_push list.
2553 allow-push list are examined after the deny_push list.
2547
2554
2548 ``allow_read``
2555 ``allow_read``
2549 If the user has not already been denied repository access due to
2556 If the user has not already been denied repository access due to
2550 the contents of deny_read, this list determines whether to grant
2557 the contents of deny_read, this list determines whether to grant
2551 repository access to the user. If this list is not empty, and the
2558 repository access to the user. If this list is not empty, and the
2552 user is unauthenticated or not present in the list, then access is
2559 user is unauthenticated or not present in the list, then access is
2553 denied for the user. If the list is empty or not set, then access
2560 denied for the user. If the list is empty or not set, then access
2554 is permitted to all users by default. Setting allow_read to the
2561 is permitted to all users by default. Setting allow_read to the
2555 special value ``*`` is equivalent to it not being set (i.e. access
2562 special value ``*`` is equivalent to it not being set (i.e. access
2556 is permitted to all users). The contents of the allow_read list are
2563 is permitted to all users). The contents of the allow_read list are
2557 examined after the deny_read list.
2564 examined after the deny_read list.
2558
2565
2559 ``allowzip``
2566 ``allowzip``
2560 (DEPRECATED) Whether to allow .zip downloading of repository
2567 (DEPRECATED) Whether to allow .zip downloading of repository
2561 revisions. This feature creates temporary files.
2568 revisions. This feature creates temporary files.
2562 (default: False)
2569 (default: False)
2563
2570
2564 ``archivesubrepos``
2571 ``archivesubrepos``
2565 Whether to recurse into subrepositories when archiving.
2572 Whether to recurse into subrepositories when archiving.
2566 (default: False)
2573 (default: False)
2567
2574
2568 ``baseurl``
2575 ``baseurl``
2569 Base URL to use when publishing URLs in other locations, so
2576 Base URL to use when publishing URLs in other locations, so
2570 third-party tools like email notification hooks can construct
2577 third-party tools like email notification hooks can construct
2571 URLs. Example: ``http://hgserver/repos/``.
2578 URLs. Example: ``http://hgserver/repos/``.
2572
2579
2573 ``cacerts``
2580 ``cacerts``
2574 Path to file containing a list of PEM encoded certificate
2581 Path to file containing a list of PEM encoded certificate
2575 authority certificates. Environment variables and ``~user``
2582 authority certificates. Environment variables and ``~user``
2576 constructs are expanded in the filename. If specified on the
2583 constructs are expanded in the filename. If specified on the
2577 client, then it will verify the identity of remote HTTPS servers
2584 client, then it will verify the identity of remote HTTPS servers
2578 with these certificates.
2585 with these certificates.
2579
2586
2580 To disable SSL verification temporarily, specify ``--insecure`` from
2587 To disable SSL verification temporarily, specify ``--insecure`` from
2581 command line.
2588 command line.
2582
2589
2583 You can use OpenSSL's CA certificate file if your platform has
2590 You can use OpenSSL's CA certificate file if your platform has
2584 one. On most Linux systems this will be
2591 one. On most Linux systems this will be
2585 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2592 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2586 generate this file manually. The form must be as follows::
2593 generate this file manually. The form must be as follows::
2587
2594
2588 -----BEGIN CERTIFICATE-----
2595 -----BEGIN CERTIFICATE-----
2589 ... (certificate in base64 PEM encoding) ...
2596 ... (certificate in base64 PEM encoding) ...
2590 -----END CERTIFICATE-----
2597 -----END CERTIFICATE-----
2591 -----BEGIN CERTIFICATE-----
2598 -----BEGIN CERTIFICATE-----
2592 ... (certificate in base64 PEM encoding) ...
2599 ... (certificate in base64 PEM encoding) ...
2593 -----END CERTIFICATE-----
2600 -----END CERTIFICATE-----
2594
2601
2595 ``cache``
2602 ``cache``
2596 Whether to support caching in hgweb. (default: True)
2603 Whether to support caching in hgweb. (default: True)
2597
2604
2598 ``certificate``
2605 ``certificate``
2599 Certificate to use when running :hg:`serve`.
2606 Certificate to use when running :hg:`serve`.
2600
2607
2601 ``collapse``
2608 ``collapse``
2602 With ``descend`` enabled, repositories in subdirectories are shown at
2609 With ``descend`` enabled, repositories in subdirectories are shown at
2603 a single level alongside repositories in the current path. With
2610 a single level alongside repositories in the current path. With
2604 ``collapse`` also enabled, repositories residing at a deeper level than
2611 ``collapse`` also enabled, repositories residing at a deeper level than
2605 the current path are grouped behind navigable directory entries that
2612 the current path are grouped behind navigable directory entries that
2606 lead to the locations of these repositories. In effect, this setting
2613 lead to the locations of these repositories. In effect, this setting
2607 collapses each collection of repositories found within a subdirectory
2614 collapses each collection of repositories found within a subdirectory
2608 into a single entry for that subdirectory. (default: False)
2615 into a single entry for that subdirectory. (default: False)
2609
2616
2610 ``comparisoncontext``
2617 ``comparisoncontext``
2611 Number of lines of context to show in side-by-side file comparison. If
2618 Number of lines of context to show in side-by-side file comparison. If
2612 negative or the value ``full``, whole files are shown. (default: 5)
2619 negative or the value ``full``, whole files are shown. (default: 5)
2613
2620
2614 This setting can be overridden by a ``context`` request parameter to the
2621 This setting can be overridden by a ``context`` request parameter to the
2615 ``comparison`` command, taking the same values.
2622 ``comparison`` command, taking the same values.
2616
2623
2617 ``contact``
2624 ``contact``
2618 Name or email address of the person in charge of the repository.
2625 Name or email address of the person in charge of the repository.
2619 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2626 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2620
2627
2621 ``csp``
2628 ``csp``
2622 Send a ``Content-Security-Policy`` HTTP header with this value.
2629 Send a ``Content-Security-Policy`` HTTP header with this value.
2623
2630
2624 The value may contain a special string ``%nonce%``, which will be replaced
2631 The value may contain a special string ``%nonce%``, which will be replaced
2625 by a randomly-generated one-time use value. If the value contains
2632 by a randomly-generated one-time use value. If the value contains
2626 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2633 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2627 one-time property of the nonce. This nonce will also be inserted into
2634 one-time property of the nonce. This nonce will also be inserted into
2628 ``<script>`` elements containing inline JavaScript.
2635 ``<script>`` elements containing inline JavaScript.
2629
2636
2630 Note: lots of HTML content sent by the server is derived from repository
2637 Note: lots of HTML content sent by the server is derived from repository
2631 data. Please consider the potential for malicious repository data to
2638 data. Please consider the potential for malicious repository data to
2632 "inject" itself into generated HTML content as part of your security
2639 "inject" itself into generated HTML content as part of your security
2633 threat model.
2640 threat model.
2634
2641
2635 ``deny_push``
2642 ``deny_push``
2636 Whether to deny pushing to the repository. If empty or not set,
2643 Whether to deny pushing to the repository. If empty or not set,
2637 push is not denied. If the special value ``*``, all remote users are
2644 push is not denied. If the special value ``*``, all remote users are
2638 denied push. Otherwise, unauthenticated users are all denied, and
2645 denied push. Otherwise, unauthenticated users are all denied, and
2639 any authenticated user name present in this list is also denied. The
2646 any authenticated user name present in this list is also denied. The
2640 contents of the deny_push list are examined before the allow-push list.
2647 contents of the deny_push list are examined before the allow-push list.
2641
2648
2642 ``deny_read``
2649 ``deny_read``
2643 Whether to deny reading/viewing of the repository. If this list is
2650 Whether to deny reading/viewing of the repository. If this list is
2644 not empty, unauthenticated users are all denied, and any
2651 not empty, unauthenticated users are all denied, and any
2645 authenticated user name present in this list is also denied access to
2652 authenticated user name present in this list is also denied access to
2646 the repository. If set to the special value ``*``, all remote users
2653 the repository. If set to the special value ``*``, all remote users
2647 are denied access (rarely needed ;). If deny_read is empty or not set,
2654 are denied access (rarely needed ;). If deny_read is empty or not set,
2648 the determination of repository access depends on the presence and
2655 the determination of repository access depends on the presence and
2649 content of the allow_read list (see description). If both
2656 content of the allow_read list (see description). If both
2650 deny_read and allow_read are empty or not set, then access is
2657 deny_read and allow_read are empty or not set, then access is
2651 permitted to all users by default. If the repository is being
2658 permitted to all users by default. If the repository is being
2652 served via hgwebdir, denied users will not be able to see it in
2659 served via hgwebdir, denied users will not be able to see it in
2653 the list of repositories. The contents of the deny_read list have
2660 the list of repositories. The contents of the deny_read list have
2654 priority over (are examined before) the contents of the allow_read
2661 priority over (are examined before) the contents of the allow_read
2655 list.
2662 list.
2656
2663
2657 ``descend``
2664 ``descend``
2658 hgwebdir indexes will not descend into subdirectories. Only repositories
2665 hgwebdir indexes will not descend into subdirectories. Only repositories
2659 directly in the current path will be shown (other repositories are still
2666 directly in the current path will be shown (other repositories are still
2660 available from the index corresponding to their containing path).
2667 available from the index corresponding to their containing path).
2661
2668
2662 ``description``
2669 ``description``
2663 Textual description of the repository's purpose or contents.
2670 Textual description of the repository's purpose or contents.
2664 (default: "unknown")
2671 (default: "unknown")
2665
2672
2666 ``encoding``
2673 ``encoding``
2667 Character encoding name. (default: the current locale charset)
2674 Character encoding name. (default: the current locale charset)
2668 Example: "UTF-8".
2675 Example: "UTF-8".
2669
2676
2670 ``errorlog``
2677 ``errorlog``
2671 Where to output the error log. (default: stderr)
2678 Where to output the error log. (default: stderr)
2672
2679
2673 ``guessmime``
2680 ``guessmime``
2674 Control MIME types for raw download of file content.
2681 Control MIME types for raw download of file content.
2675 Set to True to let hgweb guess the content type from the file
2682 Set to True to let hgweb guess the content type from the file
2676 extension. This will serve HTML files as ``text/html`` and might
2683 extension. This will serve HTML files as ``text/html`` and might
2677 allow cross-site scripting attacks when serving untrusted
2684 allow cross-site scripting attacks when serving untrusted
2678 repositories. (default: False)
2685 repositories. (default: False)
2679
2686
2680 ``hidden``
2687 ``hidden``
2681 Whether to hide the repository in the hgwebdir index.
2688 Whether to hide the repository in the hgwebdir index.
2682 (default: False)
2689 (default: False)
2683
2690
2684 ``ipv6``
2691 ``ipv6``
2685 Whether to use IPv6. (default: False)
2692 Whether to use IPv6. (default: False)
2686
2693
2687 ``labels``
2694 ``labels``
2688 List of string *labels* associated with the repository.
2695 List of string *labels* associated with the repository.
2689
2696
2690 Labels are exposed as a template keyword and can be used to customize
2697 Labels are exposed as a template keyword and can be used to customize
2691 output. e.g. the ``index`` template can group or filter repositories
2698 output. e.g. the ``index`` template can group or filter repositories
2692 by labels and the ``summary`` template can display additional content
2699 by labels and the ``summary`` template can display additional content
2693 if a specific label is present.
2700 if a specific label is present.
2694
2701
2695 ``logoimg``
2702 ``logoimg``
2696 File name of the logo image that some templates display on each page.
2703 File name of the logo image that some templates display on each page.
2697 The file name is relative to ``staticurl``. That is, the full path to
2704 The file name is relative to ``staticurl``. That is, the full path to
2698 the logo image is "staticurl/logoimg".
2705 the logo image is "staticurl/logoimg".
2699 If unset, ``hglogo.png`` will be used.
2706 If unset, ``hglogo.png`` will be used.
2700
2707
2701 ``logourl``
2708 ``logourl``
2702 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2709 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2703 will be used.
2710 will be used.
2704
2711
2705 ``maxchanges``
2712 ``maxchanges``
2706 Maximum number of changes to list on the changelog. (default: 10)
2713 Maximum number of changes to list on the changelog. (default: 10)
2707
2714
2708 ``maxfiles``
2715 ``maxfiles``
2709 Maximum number of files to list per changeset. (default: 10)
2716 Maximum number of files to list per changeset. (default: 10)
2710
2717
2711 ``maxshortchanges``
2718 ``maxshortchanges``
2712 Maximum number of changes to list on the shortlog, graph or filelog
2719 Maximum number of changes to list on the shortlog, graph or filelog
2713 pages. (default: 60)
2720 pages. (default: 60)
2714
2721
2715 ``name``
2722 ``name``
2716 Repository name to use in the web interface.
2723 Repository name to use in the web interface.
2717 (default: current working directory)
2724 (default: current working directory)
2718
2725
2719 ``port``
2726 ``port``
2720 Port to listen on. (default: 8000)
2727 Port to listen on. (default: 8000)
2721
2728
2722 ``prefix``
2729 ``prefix``
2723 Prefix path to serve from. (default: '' (server root))
2730 Prefix path to serve from. (default: '' (server root))
2724
2731
2725 ``push_ssl``
2732 ``push_ssl``
2726 Whether to require that inbound pushes be transported over SSL to
2733 Whether to require that inbound pushes be transported over SSL to
2727 prevent password sniffing. (default: True)
2734 prevent password sniffing. (default: True)
2728
2735
2729 ``refreshinterval``
2736 ``refreshinterval``
2730 How frequently directory listings re-scan the filesystem for new
2737 How frequently directory listings re-scan the filesystem for new
2731 repositories, in seconds. This is relevant when wildcards are used
2738 repositories, in seconds. This is relevant when wildcards are used
2732 to define paths. Depending on how much filesystem traversal is
2739 to define paths. Depending on how much filesystem traversal is
2733 required, refreshing may negatively impact performance.
2740 required, refreshing may negatively impact performance.
2734
2741
2735 Values less than or equal to 0 always refresh.
2742 Values less than or equal to 0 always refresh.
2736 (default: 20)
2743 (default: 20)
2737
2744
2738 ``server-header``
2745 ``server-header``
2739 Value for HTTP ``Server`` response header.
2746 Value for HTTP ``Server`` response header.
2740
2747
2741 ``static``
2748 ``static``
2742 Directory where static files are served from.
2749 Directory where static files are served from.
2743
2750
2744 ``staticurl``
2751 ``staticurl``
2745 Base URL to use for static files. If unset, static files (e.g. the
2752 Base URL to use for static files. If unset, static files (e.g. the
2746 hgicon.png favicon) will be served by the CGI script itself. Use
2753 hgicon.png favicon) will be served by the CGI script itself. Use
2747 this setting to serve them directly with the HTTP server.
2754 this setting to serve them directly with the HTTP server.
2748 Example: ``http://hgserver/static/``.
2755 Example: ``http://hgserver/static/``.
2749
2756
2750 ``stripes``
2757 ``stripes``
2751 How many lines a "zebra stripe" should span in multi-line output.
2758 How many lines a "zebra stripe" should span in multi-line output.
2752 Set to 0 to disable. (default: 1)
2759 Set to 0 to disable. (default: 1)
2753
2760
2754 ``style``
2761 ``style``
2755 Which template map style to use. The available options are the names of
2762 Which template map style to use. The available options are the names of
2756 subdirectories in the HTML templates path. (default: ``paper``)
2763 subdirectories in the HTML templates path. (default: ``paper``)
2757 Example: ``monoblue``.
2764 Example: ``monoblue``.
2758
2765
2759 ``templates``
2766 ``templates``
2760 Where to find the HTML templates. The default path to the HTML templates
2767 Where to find the HTML templates. The default path to the HTML templates
2761 can be obtained from ``hg debuginstall``.
2768 can be obtained from ``hg debuginstall``.
2762
2769
2763 ``websub``
2770 ``websub``
2764 ----------
2771 ----------
2765
2772
2766 Web substitution filter definition. You can use this section to
2773 Web substitution filter definition. You can use this section to
2767 define a set of regular expression substitution patterns which
2774 define a set of regular expression substitution patterns which
2768 let you automatically modify the hgweb server output.
2775 let you automatically modify the hgweb server output.
2769
2776
2770 The default hgweb templates only apply these substitution patterns
2777 The default hgweb templates only apply these substitution patterns
2771 on the revision description fields. You can apply them anywhere
2778 on the revision description fields. You can apply them anywhere
2772 you want when you create your own templates by adding calls to the
2779 you want when you create your own templates by adding calls to the
2773 "websub" filter (usually after calling the "escape" filter).
2780 "websub" filter (usually after calling the "escape" filter).
2774
2781
2775 This can be used, for example, to convert issue references to links
2782 This can be used, for example, to convert issue references to links
2776 to your issue tracker, or to convert "markdown-like" syntax into
2783 to your issue tracker, or to convert "markdown-like" syntax into
2777 HTML (see the examples below).
2784 HTML (see the examples below).
2778
2785
2779 Each entry in this section names a substitution filter.
2786 Each entry in this section names a substitution filter.
2780 The value of each entry defines the substitution expression itself.
2787 The value of each entry defines the substitution expression itself.
2781 The websub expressions follow the old interhg extension syntax,
2788 The websub expressions follow the old interhg extension syntax,
2782 which in turn imitates the Unix sed replacement syntax::
2789 which in turn imitates the Unix sed replacement syntax::
2783
2790
2784 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2791 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2785
2792
2786 You can use any separator other than "/". The final "i" is optional
2793 You can use any separator other than "/". The final "i" is optional
2787 and indicates that the search must be case insensitive.
2794 and indicates that the search must be case insensitive.
2788
2795
2789 Examples::
2796 Examples::
2790
2797
2791 [websub]
2798 [websub]
2792 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2799 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2793 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2800 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2794 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2801 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2795
2802
2796 ``worker``
2803 ``worker``
2797 ----------
2804 ----------
2798
2805
2799 Parallel master/worker configuration. We currently perform working
2806 Parallel master/worker configuration. We currently perform working
2800 directory updates in parallel on Unix-like systems, which greatly
2807 directory updates in parallel on Unix-like systems, which greatly
2801 helps performance.
2808 helps performance.
2802
2809
2803 ``enabled``
2810 ``enabled``
2804 Whether to enable workers code to be used.
2811 Whether to enable workers code to be used.
2805 (default: true)
2812 (default: true)
2806
2813
2807 ``numcpus``
2814 ``numcpus``
2808 Number of CPUs to use for parallel operations. A zero or
2815 Number of CPUs to use for parallel operations. A zero or
2809 negative value is treated as ``use the default``.
2816 negative value is treated as ``use the default``.
2810 (default: 4 or the number of CPUs on the system, whichever is larger)
2817 (default: 4 or the number of CPUs on the system, whichever is larger)
2811
2818
2812 ``backgroundclose``
2819 ``backgroundclose``
2813 Whether to enable closing file handles on background threads during certain
2820 Whether to enable closing file handles on background threads during certain
2814 operations. Some platforms aren't very efficient at closing file
2821 operations. Some platforms aren't very efficient at closing file
2815 handles that have been written or appended to. By performing file closing
2822 handles that have been written or appended to. By performing file closing
2816 on background threads, file write rate can increase substantially.
2823 on background threads, file write rate can increase substantially.
2817 (default: true on Windows, false elsewhere)
2824 (default: true on Windows, false elsewhere)
2818
2825
2819 ``backgroundcloseminfilecount``
2826 ``backgroundcloseminfilecount``
2820 Minimum number of files required to trigger background file closing.
2827 Minimum number of files required to trigger background file closing.
2821 Operations not writing this many files won't start background close
2828 Operations not writing this many files won't start background close
2822 threads.
2829 threads.
2823 (default: 2048)
2830 (default: 2048)
2824
2831
2825 ``backgroundclosemaxqueue``
2832 ``backgroundclosemaxqueue``
2826 The maximum number of opened file handles waiting to be closed in the
2833 The maximum number of opened file handles waiting to be closed in the
2827 background. This option only has an effect if ``backgroundclose`` is
2834 background. This option only has an effect if ``backgroundclose`` is
2828 enabled.
2835 enabled.
2829 (default: 384)
2836 (default: 384)
2830
2837
2831 ``backgroundclosethreadcount``
2838 ``backgroundclosethreadcount``
2832 Number of threads to process background file closes. Only relevant if
2839 Number of threads to process background file closes. Only relevant if
2833 ``backgroundclose`` is enabled.
2840 ``backgroundclose`` is enabled.
2834 (default: 4)
2841 (default: 4)
@@ -1,3103 +1,3103 b''
1 # localrepo.py - read/write repository class for mercurial
1 # localrepo.py - read/write repository class for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 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 errno
10 import errno
11 import hashlib
11 import hashlib
12 import os
12 import os
13 import random
13 import random
14 import sys
14 import sys
15 import time
15 import time
16 import weakref
16 import weakref
17
17
18 from .i18n import _
18 from .i18n import _
19 from .node import (
19 from .node import (
20 bin,
20 bin,
21 hex,
21 hex,
22 nullid,
22 nullid,
23 nullrev,
23 nullrev,
24 short,
24 short,
25 )
25 )
26 from . import (
26 from . import (
27 bookmarks,
27 bookmarks,
28 branchmap,
28 branchmap,
29 bundle2,
29 bundle2,
30 changegroup,
30 changegroup,
31 changelog,
31 changelog,
32 color,
32 color,
33 context,
33 context,
34 dirstate,
34 dirstate,
35 dirstateguard,
35 dirstateguard,
36 discovery,
36 discovery,
37 encoding,
37 encoding,
38 error,
38 error,
39 exchange,
39 exchange,
40 extensions,
40 extensions,
41 filelog,
41 filelog,
42 hook,
42 hook,
43 lock as lockmod,
43 lock as lockmod,
44 manifest,
44 manifest,
45 match as matchmod,
45 match as matchmod,
46 merge as mergemod,
46 merge as mergemod,
47 mergeutil,
47 mergeutil,
48 namespaces,
48 namespaces,
49 narrowspec,
49 narrowspec,
50 obsolete,
50 obsolete,
51 pathutil,
51 pathutil,
52 phases,
52 phases,
53 pushkey,
53 pushkey,
54 pycompat,
54 pycompat,
55 repository,
55 repository,
56 repoview,
56 repoview,
57 revset,
57 revset,
58 revsetlang,
58 revsetlang,
59 scmutil,
59 scmutil,
60 sparse,
60 sparse,
61 store as storemod,
61 store as storemod,
62 subrepoutil,
62 subrepoutil,
63 tags as tagsmod,
63 tags as tagsmod,
64 transaction,
64 transaction,
65 txnutil,
65 txnutil,
66 util,
66 util,
67 vfs as vfsmod,
67 vfs as vfsmod,
68 )
68 )
69 from .utils import (
69 from .utils import (
70 interfaceutil,
70 interfaceutil,
71 procutil,
71 procutil,
72 stringutil,
72 stringutil,
73 )
73 )
74
74
75 from .revlogutils import (
75 from .revlogutils import (
76 constants as revlogconst,
76 constants as revlogconst,
77 )
77 )
78
78
79 release = lockmod.release
79 release = lockmod.release
80 urlerr = util.urlerr
80 urlerr = util.urlerr
81 urlreq = util.urlreq
81 urlreq = util.urlreq
82
82
83 # set of (path, vfs-location) tuples. vfs-location is:
83 # set of (path, vfs-location) tuples. vfs-location is:
84 # - 'plain for vfs relative paths
84 # - 'plain for vfs relative paths
85 # - '' for svfs relative paths
85 # - '' for svfs relative paths
86 _cachedfiles = set()
86 _cachedfiles = set()
87
87
88 class _basefilecache(scmutil.filecache):
88 class _basefilecache(scmutil.filecache):
89 """All filecache usage on repo are done for logic that should be unfiltered
89 """All filecache usage on repo are done for logic that should be unfiltered
90 """
90 """
91 def __get__(self, repo, type=None):
91 def __get__(self, repo, type=None):
92 if repo is None:
92 if repo is None:
93 return self
93 return self
94 # proxy to unfiltered __dict__ since filtered repo has no entry
94 # proxy to unfiltered __dict__ since filtered repo has no entry
95 unfi = repo.unfiltered()
95 unfi = repo.unfiltered()
96 try:
96 try:
97 return unfi.__dict__[self.sname]
97 return unfi.__dict__[self.sname]
98 except KeyError:
98 except KeyError:
99 pass
99 pass
100 return super(_basefilecache, self).__get__(unfi, type)
100 return super(_basefilecache, self).__get__(unfi, type)
101
101
102 def set(self, repo, value):
102 def set(self, repo, value):
103 return super(_basefilecache, self).set(repo.unfiltered(), value)
103 return super(_basefilecache, self).set(repo.unfiltered(), value)
104
104
105 class repofilecache(_basefilecache):
105 class repofilecache(_basefilecache):
106 """filecache for files in .hg but outside of .hg/store"""
106 """filecache for files in .hg but outside of .hg/store"""
107 def __init__(self, *paths):
107 def __init__(self, *paths):
108 super(repofilecache, self).__init__(*paths)
108 super(repofilecache, self).__init__(*paths)
109 for path in paths:
109 for path in paths:
110 _cachedfiles.add((path, 'plain'))
110 _cachedfiles.add((path, 'plain'))
111
111
112 def join(self, obj, fname):
112 def join(self, obj, fname):
113 return obj.vfs.join(fname)
113 return obj.vfs.join(fname)
114
114
115 class storecache(_basefilecache):
115 class storecache(_basefilecache):
116 """filecache for files in the store"""
116 """filecache for files in the store"""
117 def __init__(self, *paths):
117 def __init__(self, *paths):
118 super(storecache, self).__init__(*paths)
118 super(storecache, self).__init__(*paths)
119 for path in paths:
119 for path in paths:
120 _cachedfiles.add((path, ''))
120 _cachedfiles.add((path, ''))
121
121
122 def join(self, obj, fname):
122 def join(self, obj, fname):
123 return obj.sjoin(fname)
123 return obj.sjoin(fname)
124
124
125 def isfilecached(repo, name):
125 def isfilecached(repo, name):
126 """check if a repo has already cached "name" filecache-ed property
126 """check if a repo has already cached "name" filecache-ed property
127
127
128 This returns (cachedobj-or-None, iscached) tuple.
128 This returns (cachedobj-or-None, iscached) tuple.
129 """
129 """
130 cacheentry = repo.unfiltered()._filecache.get(name, None)
130 cacheentry = repo.unfiltered()._filecache.get(name, None)
131 if not cacheentry:
131 if not cacheentry:
132 return None, False
132 return None, False
133 return cacheentry.obj, True
133 return cacheentry.obj, True
134
134
135 class unfilteredpropertycache(util.propertycache):
135 class unfilteredpropertycache(util.propertycache):
136 """propertycache that apply to unfiltered repo only"""
136 """propertycache that apply to unfiltered repo only"""
137
137
138 def __get__(self, repo, type=None):
138 def __get__(self, repo, type=None):
139 unfi = repo.unfiltered()
139 unfi = repo.unfiltered()
140 if unfi is repo:
140 if unfi is repo:
141 return super(unfilteredpropertycache, self).__get__(unfi)
141 return super(unfilteredpropertycache, self).__get__(unfi)
142 return getattr(unfi, self.name)
142 return getattr(unfi, self.name)
143
143
144 class filteredpropertycache(util.propertycache):
144 class filteredpropertycache(util.propertycache):
145 """propertycache that must take filtering in account"""
145 """propertycache that must take filtering in account"""
146
146
147 def cachevalue(self, obj, value):
147 def cachevalue(self, obj, value):
148 object.__setattr__(obj, self.name, value)
148 object.__setattr__(obj, self.name, value)
149
149
150
150
151 def hasunfilteredcache(repo, name):
151 def hasunfilteredcache(repo, name):
152 """check if a repo has an unfilteredpropertycache value for <name>"""
152 """check if a repo has an unfilteredpropertycache value for <name>"""
153 return name in vars(repo.unfiltered())
153 return name in vars(repo.unfiltered())
154
154
155 def unfilteredmethod(orig):
155 def unfilteredmethod(orig):
156 """decorate method that always need to be run on unfiltered version"""
156 """decorate method that always need to be run on unfiltered version"""
157 def wrapper(repo, *args, **kwargs):
157 def wrapper(repo, *args, **kwargs):
158 return orig(repo.unfiltered(), *args, **kwargs)
158 return orig(repo.unfiltered(), *args, **kwargs)
159 return wrapper
159 return wrapper
160
160
161 moderncaps = {'lookup', 'branchmap', 'pushkey', 'known', 'getbundle',
161 moderncaps = {'lookup', 'branchmap', 'pushkey', 'known', 'getbundle',
162 'unbundle'}
162 'unbundle'}
163 legacycaps = moderncaps.union({'changegroupsubset'})
163 legacycaps = moderncaps.union({'changegroupsubset'})
164
164
165 @interfaceutil.implementer(repository.ipeercommandexecutor)
165 @interfaceutil.implementer(repository.ipeercommandexecutor)
166 class localcommandexecutor(object):
166 class localcommandexecutor(object):
167 def __init__(self, peer):
167 def __init__(self, peer):
168 self._peer = peer
168 self._peer = peer
169 self._sent = False
169 self._sent = False
170 self._closed = False
170 self._closed = False
171
171
172 def __enter__(self):
172 def __enter__(self):
173 return self
173 return self
174
174
175 def __exit__(self, exctype, excvalue, exctb):
175 def __exit__(self, exctype, excvalue, exctb):
176 self.close()
176 self.close()
177
177
178 def callcommand(self, command, args):
178 def callcommand(self, command, args):
179 if self._sent:
179 if self._sent:
180 raise error.ProgrammingError('callcommand() cannot be used after '
180 raise error.ProgrammingError('callcommand() cannot be used after '
181 'sendcommands()')
181 'sendcommands()')
182
182
183 if self._closed:
183 if self._closed:
184 raise error.ProgrammingError('callcommand() cannot be used after '
184 raise error.ProgrammingError('callcommand() cannot be used after '
185 'close()')
185 'close()')
186
186
187 # We don't need to support anything fancy. Just call the named
187 # We don't need to support anything fancy. Just call the named
188 # method on the peer and return a resolved future.
188 # method on the peer and return a resolved future.
189 fn = getattr(self._peer, pycompat.sysstr(command))
189 fn = getattr(self._peer, pycompat.sysstr(command))
190
190
191 f = pycompat.futures.Future()
191 f = pycompat.futures.Future()
192
192
193 try:
193 try:
194 result = fn(**pycompat.strkwargs(args))
194 result = fn(**pycompat.strkwargs(args))
195 except Exception:
195 except Exception:
196 pycompat.future_set_exception_info(f, sys.exc_info()[1:])
196 pycompat.future_set_exception_info(f, sys.exc_info()[1:])
197 else:
197 else:
198 f.set_result(result)
198 f.set_result(result)
199
199
200 return f
200 return f
201
201
202 def sendcommands(self):
202 def sendcommands(self):
203 self._sent = True
203 self._sent = True
204
204
205 def close(self):
205 def close(self):
206 self._closed = True
206 self._closed = True
207
207
208 @interfaceutil.implementer(repository.ipeercommands)
208 @interfaceutil.implementer(repository.ipeercommands)
209 class localpeer(repository.peer):
209 class localpeer(repository.peer):
210 '''peer for a local repo; reflects only the most recent API'''
210 '''peer for a local repo; reflects only the most recent API'''
211
211
212 def __init__(self, repo, caps=None):
212 def __init__(self, repo, caps=None):
213 super(localpeer, self).__init__()
213 super(localpeer, self).__init__()
214
214
215 if caps is None:
215 if caps is None:
216 caps = moderncaps.copy()
216 caps = moderncaps.copy()
217 self._repo = repo.filtered('served')
217 self._repo = repo.filtered('served')
218 self.ui = repo.ui
218 self.ui = repo.ui
219 self._caps = repo._restrictcapabilities(caps)
219 self._caps = repo._restrictcapabilities(caps)
220
220
221 # Begin of _basepeer interface.
221 # Begin of _basepeer interface.
222
222
223 def url(self):
223 def url(self):
224 return self._repo.url()
224 return self._repo.url()
225
225
226 def local(self):
226 def local(self):
227 return self._repo
227 return self._repo
228
228
229 def peer(self):
229 def peer(self):
230 return self
230 return self
231
231
232 def canpush(self):
232 def canpush(self):
233 return True
233 return True
234
234
235 def close(self):
235 def close(self):
236 self._repo.close()
236 self._repo.close()
237
237
238 # End of _basepeer interface.
238 # End of _basepeer interface.
239
239
240 # Begin of _basewirecommands interface.
240 # Begin of _basewirecommands interface.
241
241
242 def branchmap(self):
242 def branchmap(self):
243 return self._repo.branchmap()
243 return self._repo.branchmap()
244
244
245 def capabilities(self):
245 def capabilities(self):
246 return self._caps
246 return self._caps
247
247
248 def clonebundles(self):
248 def clonebundles(self):
249 return self._repo.tryread('clonebundles.manifest')
249 return self._repo.tryread('clonebundles.manifest')
250
250
251 def debugwireargs(self, one, two, three=None, four=None, five=None):
251 def debugwireargs(self, one, two, three=None, four=None, five=None):
252 """Used to test argument passing over the wire"""
252 """Used to test argument passing over the wire"""
253 return "%s %s %s %s %s" % (one, two, pycompat.bytestr(three),
253 return "%s %s %s %s %s" % (one, two, pycompat.bytestr(three),
254 pycompat.bytestr(four),
254 pycompat.bytestr(four),
255 pycompat.bytestr(five))
255 pycompat.bytestr(five))
256
256
257 def getbundle(self, source, heads=None, common=None, bundlecaps=None,
257 def getbundle(self, source, heads=None, common=None, bundlecaps=None,
258 **kwargs):
258 **kwargs):
259 chunks = exchange.getbundlechunks(self._repo, source, heads=heads,
259 chunks = exchange.getbundlechunks(self._repo, source, heads=heads,
260 common=common, bundlecaps=bundlecaps,
260 common=common, bundlecaps=bundlecaps,
261 **kwargs)[1]
261 **kwargs)[1]
262 cb = util.chunkbuffer(chunks)
262 cb = util.chunkbuffer(chunks)
263
263
264 if exchange.bundle2requested(bundlecaps):
264 if exchange.bundle2requested(bundlecaps):
265 # When requesting a bundle2, getbundle returns a stream to make the
265 # When requesting a bundle2, getbundle returns a stream to make the
266 # wire level function happier. We need to build a proper object
266 # wire level function happier. We need to build a proper object
267 # from it in local peer.
267 # from it in local peer.
268 return bundle2.getunbundler(self.ui, cb)
268 return bundle2.getunbundler(self.ui, cb)
269 else:
269 else:
270 return changegroup.getunbundler('01', cb, None)
270 return changegroup.getunbundler('01', cb, None)
271
271
272 def heads(self):
272 def heads(self):
273 return self._repo.heads()
273 return self._repo.heads()
274
274
275 def known(self, nodes):
275 def known(self, nodes):
276 return self._repo.known(nodes)
276 return self._repo.known(nodes)
277
277
278 def listkeys(self, namespace):
278 def listkeys(self, namespace):
279 return self._repo.listkeys(namespace)
279 return self._repo.listkeys(namespace)
280
280
281 def lookup(self, key):
281 def lookup(self, key):
282 return self._repo.lookup(key)
282 return self._repo.lookup(key)
283
283
284 def pushkey(self, namespace, key, old, new):
284 def pushkey(self, namespace, key, old, new):
285 return self._repo.pushkey(namespace, key, old, new)
285 return self._repo.pushkey(namespace, key, old, new)
286
286
287 def stream_out(self):
287 def stream_out(self):
288 raise error.Abort(_('cannot perform stream clone against local '
288 raise error.Abort(_('cannot perform stream clone against local '
289 'peer'))
289 'peer'))
290
290
291 def unbundle(self, bundle, heads, url):
291 def unbundle(self, bundle, heads, url):
292 """apply a bundle on a repo
292 """apply a bundle on a repo
293
293
294 This function handles the repo locking itself."""
294 This function handles the repo locking itself."""
295 try:
295 try:
296 try:
296 try:
297 bundle = exchange.readbundle(self.ui, bundle, None)
297 bundle = exchange.readbundle(self.ui, bundle, None)
298 ret = exchange.unbundle(self._repo, bundle, heads, 'push', url)
298 ret = exchange.unbundle(self._repo, bundle, heads, 'push', url)
299 if util.safehasattr(ret, 'getchunks'):
299 if util.safehasattr(ret, 'getchunks'):
300 # This is a bundle20 object, turn it into an unbundler.
300 # This is a bundle20 object, turn it into an unbundler.
301 # This little dance should be dropped eventually when the
301 # This little dance should be dropped eventually when the
302 # API is finally improved.
302 # API is finally improved.
303 stream = util.chunkbuffer(ret.getchunks())
303 stream = util.chunkbuffer(ret.getchunks())
304 ret = bundle2.getunbundler(self.ui, stream)
304 ret = bundle2.getunbundler(self.ui, stream)
305 return ret
305 return ret
306 except Exception as exc:
306 except Exception as exc:
307 # If the exception contains output salvaged from a bundle2
307 # If the exception contains output salvaged from a bundle2
308 # reply, we need to make sure it is printed before continuing
308 # reply, we need to make sure it is printed before continuing
309 # to fail. So we build a bundle2 with such output and consume
309 # to fail. So we build a bundle2 with such output and consume
310 # it directly.
310 # it directly.
311 #
311 #
312 # This is not very elegant but allows a "simple" solution for
312 # This is not very elegant but allows a "simple" solution for
313 # issue4594
313 # issue4594
314 output = getattr(exc, '_bundle2salvagedoutput', ())
314 output = getattr(exc, '_bundle2salvagedoutput', ())
315 if output:
315 if output:
316 bundler = bundle2.bundle20(self._repo.ui)
316 bundler = bundle2.bundle20(self._repo.ui)
317 for out in output:
317 for out in output:
318 bundler.addpart(out)
318 bundler.addpart(out)
319 stream = util.chunkbuffer(bundler.getchunks())
319 stream = util.chunkbuffer(bundler.getchunks())
320 b = bundle2.getunbundler(self.ui, stream)
320 b = bundle2.getunbundler(self.ui, stream)
321 bundle2.processbundle(self._repo, b)
321 bundle2.processbundle(self._repo, b)
322 raise
322 raise
323 except error.PushRaced as exc:
323 except error.PushRaced as exc:
324 raise error.ResponseError(_('push failed:'),
324 raise error.ResponseError(_('push failed:'),
325 stringutil.forcebytestr(exc))
325 stringutil.forcebytestr(exc))
326
326
327 # End of _basewirecommands interface.
327 # End of _basewirecommands interface.
328
328
329 # Begin of peer interface.
329 # Begin of peer interface.
330
330
331 def commandexecutor(self):
331 def commandexecutor(self):
332 return localcommandexecutor(self)
332 return localcommandexecutor(self)
333
333
334 # End of peer interface.
334 # End of peer interface.
335
335
336 @interfaceutil.implementer(repository.ipeerlegacycommands)
336 @interfaceutil.implementer(repository.ipeerlegacycommands)
337 class locallegacypeer(localpeer):
337 class locallegacypeer(localpeer):
338 '''peer extension which implements legacy methods too; used for tests with
338 '''peer extension which implements legacy methods too; used for tests with
339 restricted capabilities'''
339 restricted capabilities'''
340
340
341 def __init__(self, repo):
341 def __init__(self, repo):
342 super(locallegacypeer, self).__init__(repo, caps=legacycaps)
342 super(locallegacypeer, self).__init__(repo, caps=legacycaps)
343
343
344 # Begin of baselegacywirecommands interface.
344 # Begin of baselegacywirecommands interface.
345
345
346 def between(self, pairs):
346 def between(self, pairs):
347 return self._repo.between(pairs)
347 return self._repo.between(pairs)
348
348
349 def branches(self, nodes):
349 def branches(self, nodes):
350 return self._repo.branches(nodes)
350 return self._repo.branches(nodes)
351
351
352 def changegroup(self, nodes, source):
352 def changegroup(self, nodes, source):
353 outgoing = discovery.outgoing(self._repo, missingroots=nodes,
353 outgoing = discovery.outgoing(self._repo, missingroots=nodes,
354 missingheads=self._repo.heads())
354 missingheads=self._repo.heads())
355 return changegroup.makechangegroup(self._repo, outgoing, '01', source)
355 return changegroup.makechangegroup(self._repo, outgoing, '01', source)
356
356
357 def changegroupsubset(self, bases, heads, source):
357 def changegroupsubset(self, bases, heads, source):
358 outgoing = discovery.outgoing(self._repo, missingroots=bases,
358 outgoing = discovery.outgoing(self._repo, missingroots=bases,
359 missingheads=heads)
359 missingheads=heads)
360 return changegroup.makechangegroup(self._repo, outgoing, '01', source)
360 return changegroup.makechangegroup(self._repo, outgoing, '01', source)
361
361
362 # End of baselegacywirecommands interface.
362 # End of baselegacywirecommands interface.
363
363
364 # Increment the sub-version when the revlog v2 format changes to lock out old
364 # Increment the sub-version when the revlog v2 format changes to lock out old
365 # clients.
365 # clients.
366 REVLOGV2_REQUIREMENT = 'exp-revlogv2.1'
366 REVLOGV2_REQUIREMENT = 'exp-revlogv2.1'
367
367
368 # A repository with the sparserevlog feature will have delta chains that
368 # A repository with the sparserevlog feature will have delta chains that
369 # can spread over a larger span. Sparse reading cuts these large spans into
369 # can spread over a larger span. Sparse reading cuts these large spans into
370 # pieces, so that each piece isn't too big.
370 # pieces, so that each piece isn't too big.
371 # Without the sparserevlog capability, reading from the repository could use
371 # Without the sparserevlog capability, reading from the repository could use
372 # huge amounts of memory, because the whole span would be read at once,
372 # huge amounts of memory, because the whole span would be read at once,
373 # including all the intermediate revisions that aren't pertinent for the chain.
373 # including all the intermediate revisions that aren't pertinent for the chain.
374 # This is why once a repository has enabled sparse-read, it becomes required.
374 # This is why once a repository has enabled sparse-read, it becomes required.
375 SPARSEREVLOG_REQUIREMENT = 'sparserevlog'
375 SPARSEREVLOG_REQUIREMENT = 'sparserevlog'
376
376
377 # Functions receiving (ui, features) that extensions can register to impact
377 # Functions receiving (ui, features) that extensions can register to impact
378 # the ability to load repositories with custom requirements. Only
378 # the ability to load repositories with custom requirements. Only
379 # functions defined in loaded extensions are called.
379 # functions defined in loaded extensions are called.
380 #
380 #
381 # The function receives a set of requirement strings that the repository
381 # The function receives a set of requirement strings that the repository
382 # is capable of opening. Functions will typically add elements to the
382 # is capable of opening. Functions will typically add elements to the
383 # set to reflect that the extension knows how to handle that requirements.
383 # set to reflect that the extension knows how to handle that requirements.
384 featuresetupfuncs = set()
384 featuresetupfuncs = set()
385
385
386 def makelocalrepository(baseui, path, intents=None):
386 def makelocalrepository(baseui, path, intents=None):
387 """Create a local repository object.
387 """Create a local repository object.
388
388
389 Given arguments needed to construct a local repository, this function
389 Given arguments needed to construct a local repository, this function
390 performs various early repository loading functionality (such as
390 performs various early repository loading functionality (such as
391 reading the ``.hg/requires`` and ``.hg/hgrc`` files), validates that
391 reading the ``.hg/requires`` and ``.hg/hgrc`` files), validates that
392 the repository can be opened, derives a type suitable for representing
392 the repository can be opened, derives a type suitable for representing
393 that repository, and returns an instance of it.
393 that repository, and returns an instance of it.
394
394
395 The returned object conforms to the ``repository.completelocalrepository``
395 The returned object conforms to the ``repository.completelocalrepository``
396 interface.
396 interface.
397
397
398 The repository type is derived by calling a series of factory functions
398 The repository type is derived by calling a series of factory functions
399 for each aspect/interface of the final repository. These are defined by
399 for each aspect/interface of the final repository. These are defined by
400 ``REPO_INTERFACES``.
400 ``REPO_INTERFACES``.
401
401
402 Each factory function is called to produce a type implementing a specific
402 Each factory function is called to produce a type implementing a specific
403 interface. The cumulative list of returned types will be combined into a
403 interface. The cumulative list of returned types will be combined into a
404 new type and that type will be instantiated to represent the local
404 new type and that type will be instantiated to represent the local
405 repository.
405 repository.
406
406
407 The factory functions each receive various state that may be consulted
407 The factory functions each receive various state that may be consulted
408 as part of deriving a type.
408 as part of deriving a type.
409
409
410 Extensions should wrap these factory functions to customize repository type
410 Extensions should wrap these factory functions to customize repository type
411 creation. Note that an extension's wrapped function may be called even if
411 creation. Note that an extension's wrapped function may be called even if
412 that extension is not loaded for the repo being constructed. Extensions
412 that extension is not loaded for the repo being constructed. Extensions
413 should check if their ``__name__`` appears in the
413 should check if their ``__name__`` appears in the
414 ``extensionmodulenames`` set passed to the factory function and no-op if
414 ``extensionmodulenames`` set passed to the factory function and no-op if
415 not.
415 not.
416 """
416 """
417 ui = baseui.copy()
417 ui = baseui.copy()
418 # Prevent copying repo configuration.
418 # Prevent copying repo configuration.
419 ui.copy = baseui.copy
419 ui.copy = baseui.copy
420
420
421 # Working directory VFS rooted at repository root.
421 # Working directory VFS rooted at repository root.
422 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
422 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
423
423
424 # Main VFS for .hg/ directory.
424 # Main VFS for .hg/ directory.
425 hgpath = wdirvfs.join(b'.hg')
425 hgpath = wdirvfs.join(b'.hg')
426 hgvfs = vfsmod.vfs(hgpath, cacheaudited=True)
426 hgvfs = vfsmod.vfs(hgpath, cacheaudited=True)
427
427
428 # The .hg/ path should exist and should be a directory. All other
428 # The .hg/ path should exist and should be a directory. All other
429 # cases are errors.
429 # cases are errors.
430 if not hgvfs.isdir():
430 if not hgvfs.isdir():
431 try:
431 try:
432 hgvfs.stat()
432 hgvfs.stat()
433 except OSError as e:
433 except OSError as e:
434 if e.errno != errno.ENOENT:
434 if e.errno != errno.ENOENT:
435 raise
435 raise
436
436
437 raise error.RepoError(_(b'repository %s not found') % path)
437 raise error.RepoError(_(b'repository %s not found') % path)
438
438
439 # .hg/requires file contains a newline-delimited list of
439 # .hg/requires file contains a newline-delimited list of
440 # features/capabilities the opener (us) must have in order to use
440 # features/capabilities the opener (us) must have in order to use
441 # the repository. This file was introduced in Mercurial 0.9.2,
441 # the repository. This file was introduced in Mercurial 0.9.2,
442 # which means very old repositories may not have one. We assume
442 # which means very old repositories may not have one. We assume
443 # a missing file translates to no requirements.
443 # a missing file translates to no requirements.
444 try:
444 try:
445 requirements = set(hgvfs.read(b'requires').splitlines())
445 requirements = set(hgvfs.read(b'requires').splitlines())
446 except IOError as e:
446 except IOError as e:
447 if e.errno != errno.ENOENT:
447 if e.errno != errno.ENOENT:
448 raise
448 raise
449 requirements = set()
449 requirements = set()
450
450
451 # The .hg/hgrc file may load extensions or contain config options
451 # The .hg/hgrc file may load extensions or contain config options
452 # that influence repository construction. Attempt to load it and
452 # that influence repository construction. Attempt to load it and
453 # process any new extensions that it may have pulled in.
453 # process any new extensions that it may have pulled in.
454 if loadhgrc(ui, wdirvfs, hgvfs, requirements):
454 if loadhgrc(ui, wdirvfs, hgvfs, requirements):
455 afterhgrcload(ui, wdirvfs, hgvfs, requirements)
455 afterhgrcload(ui, wdirvfs, hgvfs, requirements)
456 extensions.loadall(ui)
456 extensions.loadall(ui)
457 extensions.populateui(ui)
457 extensions.populateui(ui)
458
458
459 # Set of module names of extensions loaded for this repository.
459 # Set of module names of extensions loaded for this repository.
460 extensionmodulenames = {m.__name__ for n, m in extensions.extensions(ui)}
460 extensionmodulenames = {m.__name__ for n, m in extensions.extensions(ui)}
461
461
462 supportedrequirements = gathersupportedrequirements(ui)
462 supportedrequirements = gathersupportedrequirements(ui)
463
463
464 # We first validate the requirements are known.
464 # We first validate the requirements are known.
465 ensurerequirementsrecognized(requirements, supportedrequirements)
465 ensurerequirementsrecognized(requirements, supportedrequirements)
466
466
467 # Then we validate that the known set is reasonable to use together.
467 # Then we validate that the known set is reasonable to use together.
468 ensurerequirementscompatible(ui, requirements)
468 ensurerequirementscompatible(ui, requirements)
469
469
470 # TODO there are unhandled edge cases related to opening repositories with
470 # TODO there are unhandled edge cases related to opening repositories with
471 # shared storage. If storage is shared, we should also test for requirements
471 # shared storage. If storage is shared, we should also test for requirements
472 # compatibility in the pointed-to repo. This entails loading the .hg/hgrc in
472 # compatibility in the pointed-to repo. This entails loading the .hg/hgrc in
473 # that repo, as that repo may load extensions needed to open it. This is a
473 # that repo, as that repo may load extensions needed to open it. This is a
474 # bit complicated because we don't want the other hgrc to overwrite settings
474 # bit complicated because we don't want the other hgrc to overwrite settings
475 # in this hgrc.
475 # in this hgrc.
476 #
476 #
477 # This bug is somewhat mitigated by the fact that we copy the .hg/requires
477 # This bug is somewhat mitigated by the fact that we copy the .hg/requires
478 # file when sharing repos. But if a requirement is added after the share is
478 # file when sharing repos. But if a requirement is added after the share is
479 # performed, thereby introducing a new requirement for the opener, we may
479 # performed, thereby introducing a new requirement for the opener, we may
480 # will not see that and could encounter a run-time error interacting with
480 # will not see that and could encounter a run-time error interacting with
481 # that shared store since it has an unknown-to-us requirement.
481 # that shared store since it has an unknown-to-us requirement.
482
482
483 # At this point, we know we should be capable of opening the repository.
483 # At this point, we know we should be capable of opening the repository.
484 # Now get on with doing that.
484 # Now get on with doing that.
485
485
486 features = set()
486 features = set()
487
487
488 # The "store" part of the repository holds versioned data. How it is
488 # The "store" part of the repository holds versioned data. How it is
489 # accessed is determined by various requirements. The ``shared`` or
489 # accessed is determined by various requirements. The ``shared`` or
490 # ``relshared`` requirements indicate the store lives in the path contained
490 # ``relshared`` requirements indicate the store lives in the path contained
491 # in the ``.hg/sharedpath`` file. This is an absolute path for
491 # in the ``.hg/sharedpath`` file. This is an absolute path for
492 # ``shared`` and relative to ``.hg/`` for ``relshared``.
492 # ``shared`` and relative to ``.hg/`` for ``relshared``.
493 if b'shared' in requirements or b'relshared' in requirements:
493 if b'shared' in requirements or b'relshared' in requirements:
494 sharedpath = hgvfs.read(b'sharedpath').rstrip(b'\n')
494 sharedpath = hgvfs.read(b'sharedpath').rstrip(b'\n')
495 if b'relshared' in requirements:
495 if b'relshared' in requirements:
496 sharedpath = hgvfs.join(sharedpath)
496 sharedpath = hgvfs.join(sharedpath)
497
497
498 sharedvfs = vfsmod.vfs(sharedpath, realpath=True)
498 sharedvfs = vfsmod.vfs(sharedpath, realpath=True)
499
499
500 if not sharedvfs.exists():
500 if not sharedvfs.exists():
501 raise error.RepoError(_(b'.hg/sharedpath points to nonexistent '
501 raise error.RepoError(_(b'.hg/sharedpath points to nonexistent '
502 b'directory %s') % sharedvfs.base)
502 b'directory %s') % sharedvfs.base)
503
503
504 features.add(repository.REPO_FEATURE_SHARED_STORAGE)
504 features.add(repository.REPO_FEATURE_SHARED_STORAGE)
505
505
506 storebasepath = sharedvfs.base
506 storebasepath = sharedvfs.base
507 cachepath = sharedvfs.join(b'cache')
507 cachepath = sharedvfs.join(b'cache')
508 else:
508 else:
509 storebasepath = hgvfs.base
509 storebasepath = hgvfs.base
510 cachepath = hgvfs.join(b'cache')
510 cachepath = hgvfs.join(b'cache')
511 wcachepath = hgvfs.join(b'wcache')
511 wcachepath = hgvfs.join(b'wcache')
512
512
513
513
514 # The store has changed over time and the exact layout is dictated by
514 # The store has changed over time and the exact layout is dictated by
515 # requirements. The store interface abstracts differences across all
515 # requirements. The store interface abstracts differences across all
516 # of them.
516 # of them.
517 store = makestore(requirements, storebasepath,
517 store = makestore(requirements, storebasepath,
518 lambda base: vfsmod.vfs(base, cacheaudited=True))
518 lambda base: vfsmod.vfs(base, cacheaudited=True))
519 hgvfs.createmode = store.createmode
519 hgvfs.createmode = store.createmode
520
520
521 storevfs = store.vfs
521 storevfs = store.vfs
522 storevfs.options = resolvestorevfsoptions(ui, requirements, features)
522 storevfs.options = resolvestorevfsoptions(ui, requirements, features)
523
523
524 # The cache vfs is used to manage cache files.
524 # The cache vfs is used to manage cache files.
525 cachevfs = vfsmod.vfs(cachepath, cacheaudited=True)
525 cachevfs = vfsmod.vfs(cachepath, cacheaudited=True)
526 cachevfs.createmode = store.createmode
526 cachevfs.createmode = store.createmode
527 # The cache vfs is used to manage cache files related to the working copy
527 # The cache vfs is used to manage cache files related to the working copy
528 wcachevfs = vfsmod.vfs(wcachepath, cacheaudited=True)
528 wcachevfs = vfsmod.vfs(wcachepath, cacheaudited=True)
529 wcachevfs.createmode = store.createmode
529 wcachevfs.createmode = store.createmode
530
530
531 # Now resolve the type for the repository object. We do this by repeatedly
531 # Now resolve the type for the repository object. We do this by repeatedly
532 # calling a factory function to produces types for specific aspects of the
532 # calling a factory function to produces types for specific aspects of the
533 # repo's operation. The aggregate returned types are used as base classes
533 # repo's operation. The aggregate returned types are used as base classes
534 # for a dynamically-derived type, which will represent our new repository.
534 # for a dynamically-derived type, which will represent our new repository.
535
535
536 bases = []
536 bases = []
537 extrastate = {}
537 extrastate = {}
538
538
539 for iface, fn in REPO_INTERFACES:
539 for iface, fn in REPO_INTERFACES:
540 # We pass all potentially useful state to give extensions tons of
540 # We pass all potentially useful state to give extensions tons of
541 # flexibility.
541 # flexibility.
542 typ = fn()(ui=ui,
542 typ = fn()(ui=ui,
543 intents=intents,
543 intents=intents,
544 requirements=requirements,
544 requirements=requirements,
545 features=features,
545 features=features,
546 wdirvfs=wdirvfs,
546 wdirvfs=wdirvfs,
547 hgvfs=hgvfs,
547 hgvfs=hgvfs,
548 store=store,
548 store=store,
549 storevfs=storevfs,
549 storevfs=storevfs,
550 storeoptions=storevfs.options,
550 storeoptions=storevfs.options,
551 cachevfs=cachevfs,
551 cachevfs=cachevfs,
552 wcachevfs=wcachevfs,
552 wcachevfs=wcachevfs,
553 extensionmodulenames=extensionmodulenames,
553 extensionmodulenames=extensionmodulenames,
554 extrastate=extrastate,
554 extrastate=extrastate,
555 baseclasses=bases)
555 baseclasses=bases)
556
556
557 if not isinstance(typ, type):
557 if not isinstance(typ, type):
558 raise error.ProgrammingError('unable to construct type for %s' %
558 raise error.ProgrammingError('unable to construct type for %s' %
559 iface)
559 iface)
560
560
561 bases.append(typ)
561 bases.append(typ)
562
562
563 # type() allows you to use characters in type names that wouldn't be
563 # type() allows you to use characters in type names that wouldn't be
564 # recognized as Python symbols in source code. We abuse that to add
564 # recognized as Python symbols in source code. We abuse that to add
565 # rich information about our constructed repo.
565 # rich information about our constructed repo.
566 name = pycompat.sysstr(b'derivedrepo:%s<%s>' % (
566 name = pycompat.sysstr(b'derivedrepo:%s<%s>' % (
567 wdirvfs.base,
567 wdirvfs.base,
568 b','.join(sorted(requirements))))
568 b','.join(sorted(requirements))))
569
569
570 cls = type(name, tuple(bases), {})
570 cls = type(name, tuple(bases), {})
571
571
572 return cls(
572 return cls(
573 baseui=baseui,
573 baseui=baseui,
574 ui=ui,
574 ui=ui,
575 origroot=path,
575 origroot=path,
576 wdirvfs=wdirvfs,
576 wdirvfs=wdirvfs,
577 hgvfs=hgvfs,
577 hgvfs=hgvfs,
578 requirements=requirements,
578 requirements=requirements,
579 supportedrequirements=supportedrequirements,
579 supportedrequirements=supportedrequirements,
580 sharedpath=storebasepath,
580 sharedpath=storebasepath,
581 store=store,
581 store=store,
582 cachevfs=cachevfs,
582 cachevfs=cachevfs,
583 wcachevfs=wcachevfs,
583 wcachevfs=wcachevfs,
584 features=features,
584 features=features,
585 intents=intents)
585 intents=intents)
586
586
587 def loadhgrc(ui, wdirvfs, hgvfs, requirements):
587 def loadhgrc(ui, wdirvfs, hgvfs, requirements):
588 """Load hgrc files/content into a ui instance.
588 """Load hgrc files/content into a ui instance.
589
589
590 This is called during repository opening to load any additional
590 This is called during repository opening to load any additional
591 config files or settings relevant to the current repository.
591 config files or settings relevant to the current repository.
592
592
593 Returns a bool indicating whether any additional configs were loaded.
593 Returns a bool indicating whether any additional configs were loaded.
594
594
595 Extensions should monkeypatch this function to modify how per-repo
595 Extensions should monkeypatch this function to modify how per-repo
596 configs are loaded. For example, an extension may wish to pull in
596 configs are loaded. For example, an extension may wish to pull in
597 configs from alternate files or sources.
597 configs from alternate files or sources.
598 """
598 """
599 try:
599 try:
600 ui.readconfig(hgvfs.join(b'hgrc'), root=wdirvfs.base)
600 ui.readconfig(hgvfs.join(b'hgrc'), root=wdirvfs.base)
601 return True
601 return True
602 except IOError:
602 except IOError:
603 return False
603 return False
604
604
605 def afterhgrcload(ui, wdirvfs, hgvfs, requirements):
605 def afterhgrcload(ui, wdirvfs, hgvfs, requirements):
606 """Perform additional actions after .hg/hgrc is loaded.
606 """Perform additional actions after .hg/hgrc is loaded.
607
607
608 This function is called during repository loading immediately after
608 This function is called during repository loading immediately after
609 the .hg/hgrc file is loaded and before per-repo extensions are loaded.
609 the .hg/hgrc file is loaded and before per-repo extensions are loaded.
610
610
611 The function can be used to validate configs, automatically add
611 The function can be used to validate configs, automatically add
612 options (including extensions) based on requirements, etc.
612 options (including extensions) based on requirements, etc.
613 """
613 """
614
614
615 # Map of requirements to list of extensions to load automatically when
615 # Map of requirements to list of extensions to load automatically when
616 # requirement is present.
616 # requirement is present.
617 autoextensions = {
617 autoextensions = {
618 b'largefiles': [b'largefiles'],
618 b'largefiles': [b'largefiles'],
619 b'lfs': [b'lfs'],
619 b'lfs': [b'lfs'],
620 }
620 }
621
621
622 for requirement, names in sorted(autoextensions.items()):
622 for requirement, names in sorted(autoextensions.items()):
623 if requirement not in requirements:
623 if requirement not in requirements:
624 continue
624 continue
625
625
626 for name in names:
626 for name in names:
627 if not ui.hasconfig(b'extensions', name):
627 if not ui.hasconfig(b'extensions', name):
628 ui.setconfig(b'extensions', name, b'', source='autoload')
628 ui.setconfig(b'extensions', name, b'', source='autoload')
629
629
630 def gathersupportedrequirements(ui):
630 def gathersupportedrequirements(ui):
631 """Determine the complete set of recognized requirements."""
631 """Determine the complete set of recognized requirements."""
632 # Start with all requirements supported by this file.
632 # Start with all requirements supported by this file.
633 supported = set(localrepository._basesupported)
633 supported = set(localrepository._basesupported)
634
634
635 # Execute ``featuresetupfuncs`` entries if they belong to an extension
635 # Execute ``featuresetupfuncs`` entries if they belong to an extension
636 # relevant to this ui instance.
636 # relevant to this ui instance.
637 modules = {m.__name__ for n, m in extensions.extensions(ui)}
637 modules = {m.__name__ for n, m in extensions.extensions(ui)}
638
638
639 for fn in featuresetupfuncs:
639 for fn in featuresetupfuncs:
640 if fn.__module__ in modules:
640 if fn.__module__ in modules:
641 fn(ui, supported)
641 fn(ui, supported)
642
642
643 # Add derived requirements from registered compression engines.
643 # Add derived requirements from registered compression engines.
644 for name in util.compengines:
644 for name in util.compengines:
645 engine = util.compengines[name]
645 engine = util.compengines[name]
646 if engine.revlogheader():
646 if engine.revlogheader():
647 supported.add(b'exp-compression-%s' % name)
647 supported.add(b'exp-compression-%s' % name)
648
648
649 return supported
649 return supported
650
650
651 def ensurerequirementsrecognized(requirements, supported):
651 def ensurerequirementsrecognized(requirements, supported):
652 """Validate that a set of local requirements is recognized.
652 """Validate that a set of local requirements is recognized.
653
653
654 Receives a set of requirements. Raises an ``error.RepoError`` if there
654 Receives a set of requirements. Raises an ``error.RepoError`` if there
655 exists any requirement in that set that currently loaded code doesn't
655 exists any requirement in that set that currently loaded code doesn't
656 recognize.
656 recognize.
657
657
658 Returns a set of supported requirements.
658 Returns a set of supported requirements.
659 """
659 """
660 missing = set()
660 missing = set()
661
661
662 for requirement in requirements:
662 for requirement in requirements:
663 if requirement in supported:
663 if requirement in supported:
664 continue
664 continue
665
665
666 if not requirement or not requirement[0:1].isalnum():
666 if not requirement or not requirement[0:1].isalnum():
667 raise error.RequirementError(_(b'.hg/requires file is corrupt'))
667 raise error.RequirementError(_(b'.hg/requires file is corrupt'))
668
668
669 missing.add(requirement)
669 missing.add(requirement)
670
670
671 if missing:
671 if missing:
672 raise error.RequirementError(
672 raise error.RequirementError(
673 _(b'repository requires features unknown to this Mercurial: %s') %
673 _(b'repository requires features unknown to this Mercurial: %s') %
674 b' '.join(sorted(missing)),
674 b' '.join(sorted(missing)),
675 hint=_(b'see https://mercurial-scm.org/wiki/MissingRequirement '
675 hint=_(b'see https://mercurial-scm.org/wiki/MissingRequirement '
676 b'for more information'))
676 b'for more information'))
677
677
678 def ensurerequirementscompatible(ui, requirements):
678 def ensurerequirementscompatible(ui, requirements):
679 """Validates that a set of recognized requirements is mutually compatible.
679 """Validates that a set of recognized requirements is mutually compatible.
680
680
681 Some requirements may not be compatible with others or require
681 Some requirements may not be compatible with others or require
682 config options that aren't enabled. This function is called during
682 config options that aren't enabled. This function is called during
683 repository opening to ensure that the set of requirements needed
683 repository opening to ensure that the set of requirements needed
684 to open a repository is sane and compatible with config options.
684 to open a repository is sane and compatible with config options.
685
685
686 Extensions can monkeypatch this function to perform additional
686 Extensions can monkeypatch this function to perform additional
687 checking.
687 checking.
688
688
689 ``error.RepoError`` should be raised on failure.
689 ``error.RepoError`` should be raised on failure.
690 """
690 """
691 if b'exp-sparse' in requirements and not sparse.enabled:
691 if b'exp-sparse' in requirements and not sparse.enabled:
692 raise error.RepoError(_(b'repository is using sparse feature but '
692 raise error.RepoError(_(b'repository is using sparse feature but '
693 b'sparse is not enabled; enable the '
693 b'sparse is not enabled; enable the '
694 b'"sparse" extensions to access'))
694 b'"sparse" extensions to access'))
695
695
696 def makestore(requirements, path, vfstype):
696 def makestore(requirements, path, vfstype):
697 """Construct a storage object for a repository."""
697 """Construct a storage object for a repository."""
698 if b'store' in requirements:
698 if b'store' in requirements:
699 if b'fncache' in requirements:
699 if b'fncache' in requirements:
700 return storemod.fncachestore(path, vfstype,
700 return storemod.fncachestore(path, vfstype,
701 b'dotencode' in requirements)
701 b'dotencode' in requirements)
702
702
703 return storemod.encodedstore(path, vfstype)
703 return storemod.encodedstore(path, vfstype)
704
704
705 return storemod.basicstore(path, vfstype)
705 return storemod.basicstore(path, vfstype)
706
706
707 def resolvestorevfsoptions(ui, requirements, features):
707 def resolvestorevfsoptions(ui, requirements, features):
708 """Resolve the options to pass to the store vfs opener.
708 """Resolve the options to pass to the store vfs opener.
709
709
710 The returned dict is used to influence behavior of the storage layer.
710 The returned dict is used to influence behavior of the storage layer.
711 """
711 """
712 options = {}
712 options = {}
713
713
714 if b'treemanifest' in requirements:
714 if b'treemanifest' in requirements:
715 options[b'treemanifest'] = True
715 options[b'treemanifest'] = True
716
716
717 # experimental config: format.manifestcachesize
717 # experimental config: format.manifestcachesize
718 manifestcachesize = ui.configint(b'format', b'manifestcachesize')
718 manifestcachesize = ui.configint(b'format', b'manifestcachesize')
719 if manifestcachesize is not None:
719 if manifestcachesize is not None:
720 options[b'manifestcachesize'] = manifestcachesize
720 options[b'manifestcachesize'] = manifestcachesize
721
721
722 # In the absence of another requirement superseding a revlog-related
722 # In the absence of another requirement superseding a revlog-related
723 # requirement, we have to assume the repo is using revlog version 0.
723 # requirement, we have to assume the repo is using revlog version 0.
724 # This revlog format is super old and we don't bother trying to parse
724 # This revlog format is super old and we don't bother trying to parse
725 # opener options for it because those options wouldn't do anything
725 # opener options for it because those options wouldn't do anything
726 # meaningful on such old repos.
726 # meaningful on such old repos.
727 if b'revlogv1' in requirements or REVLOGV2_REQUIREMENT in requirements:
727 if b'revlogv1' in requirements or REVLOGV2_REQUIREMENT in requirements:
728 options.update(resolverevlogstorevfsoptions(ui, requirements, features))
728 options.update(resolverevlogstorevfsoptions(ui, requirements, features))
729
729
730 return options
730 return options
731
731
732 def resolverevlogstorevfsoptions(ui, requirements, features):
732 def resolverevlogstorevfsoptions(ui, requirements, features):
733 """Resolve opener options specific to revlogs."""
733 """Resolve opener options specific to revlogs."""
734
734
735 options = {}
735 options = {}
736 options[b'flagprocessors'] = {}
736 options[b'flagprocessors'] = {}
737
737
738 if b'revlogv1' in requirements:
738 if b'revlogv1' in requirements:
739 options[b'revlogv1'] = True
739 options[b'revlogv1'] = True
740 if REVLOGV2_REQUIREMENT in requirements:
740 if REVLOGV2_REQUIREMENT in requirements:
741 options[b'revlogv2'] = True
741 options[b'revlogv2'] = True
742
742
743 if b'generaldelta' in requirements:
743 if b'generaldelta' in requirements:
744 options[b'generaldelta'] = True
744 options[b'generaldelta'] = True
745
745
746 # experimental config: format.chunkcachesize
746 # experimental config: format.chunkcachesize
747 chunkcachesize = ui.configint(b'format', b'chunkcachesize')
747 chunkcachesize = ui.configint(b'format', b'chunkcachesize')
748 if chunkcachesize is not None:
748 if chunkcachesize is not None:
749 options[b'chunkcachesize'] = chunkcachesize
749 options[b'chunkcachesize'] = chunkcachesize
750
750
751 deltabothparents = ui.configbool(b'storage',
751 deltabothparents = ui.configbool(b'storage',
752 b'revlog.optimize-delta-parent-choice')
752 b'revlog.optimize-delta-parent-choice')
753 options[b'deltabothparents'] = deltabothparents
753 options[b'deltabothparents'] = deltabothparents
754
754
755 lazydelta = ui.configbool(b'storage', b'revlog.reuse-external-delta')
755 lazydelta = ui.configbool(b'storage', b'revlog.reuse-external-delta')
756 lazydeltabase = False
756 lazydeltabase = False
757 if lazydelta:
757 if lazydelta:
758 lazydeltabase = ui.configbool(b'storage',
758 lazydeltabase = ui.configbool(b'storage',
759 b'revlog.reuse-external-delta-parent')
759 b'revlog.reuse-external-delta-parent')
760 if lazydeltabase is None:
760 if lazydeltabase is None:
761 lazydeltabase = not scmutil.gddeltaconfig(ui)
761 lazydeltabase = not scmutil.gddeltaconfig(ui)
762 options[b'lazydelta'] = lazydelta
762 options[b'lazydelta'] = lazydelta
763 options[b'lazydeltabase'] = lazydeltabase
763 options[b'lazydeltabase'] = lazydeltabase
764
764
765 chainspan = ui.configbytes(b'experimental', b'maxdeltachainspan')
765 chainspan = ui.configbytes(b'experimental', b'maxdeltachainspan')
766 if 0 <= chainspan:
766 if 0 <= chainspan:
767 options[b'maxdeltachainspan'] = chainspan
767 options[b'maxdeltachainspan'] = chainspan
768
768
769 mmapindexthreshold = ui.configbytes(b'experimental',
769 mmapindexthreshold = ui.configbytes(b'experimental',
770 b'mmapindexthreshold')
770 b'mmapindexthreshold')
771 if mmapindexthreshold is not None:
771 if mmapindexthreshold is not None:
772 options[b'mmapindexthreshold'] = mmapindexthreshold
772 options[b'mmapindexthreshold'] = mmapindexthreshold
773
773
774 withsparseread = ui.configbool(b'experimental', b'sparse-read')
774 withsparseread = ui.configbool(b'experimental', b'sparse-read')
775 srdensitythres = float(ui.config(b'experimental',
775 srdensitythres = float(ui.config(b'experimental',
776 b'sparse-read.density-threshold'))
776 b'sparse-read.density-threshold'))
777 srmingapsize = ui.configbytes(b'experimental',
777 srmingapsize = ui.configbytes(b'experimental',
778 b'sparse-read.min-gap-size')
778 b'sparse-read.min-gap-size')
779 options[b'with-sparse-read'] = withsparseread
779 options[b'with-sparse-read'] = withsparseread
780 options[b'sparse-read-density-threshold'] = srdensitythres
780 options[b'sparse-read-density-threshold'] = srdensitythres
781 options[b'sparse-read-min-gap-size'] = srmingapsize
781 options[b'sparse-read-min-gap-size'] = srmingapsize
782
782
783 sparserevlog = SPARSEREVLOG_REQUIREMENT in requirements
783 sparserevlog = SPARSEREVLOG_REQUIREMENT in requirements
784 options[b'sparse-revlog'] = sparserevlog
784 options[b'sparse-revlog'] = sparserevlog
785 if sparserevlog:
785 if sparserevlog:
786 options[b'generaldelta'] = True
786 options[b'generaldelta'] = True
787
787
788 maxchainlen = None
788 maxchainlen = None
789 if sparserevlog:
789 if sparserevlog:
790 maxchainlen = revlogconst.SPARSE_REVLOG_MAX_CHAIN_LENGTH
790 maxchainlen = revlogconst.SPARSE_REVLOG_MAX_CHAIN_LENGTH
791 # experimental config: format.maxchainlen
791 # experimental config: format.maxchainlen
792 maxchainlen = ui.configint(b'format', b'maxchainlen', maxchainlen)
792 maxchainlen = ui.configint(b'format', b'maxchainlen', maxchainlen)
793 if maxchainlen is not None:
793 if maxchainlen is not None:
794 options[b'maxchainlen'] = maxchainlen
794 options[b'maxchainlen'] = maxchainlen
795
795
796 for r in requirements:
796 for r in requirements:
797 if r.startswith(b'exp-compression-'):
797 if r.startswith(b'exp-compression-'):
798 options[b'compengine'] = r[len(b'exp-compression-'):]
798 options[b'compengine'] = r[len(b'exp-compression-'):]
799
799
800 options[b'zlib.level'] = ui.configint(b'storage', b'revlog.zlib.level')
800 options[b'zlib.level'] = ui.configint(b'storage', b'revlog.zlib.level')
801 if options[b'zlib.level'] is not None:
801 if options[b'zlib.level'] is not None:
802 if not (0 <= options[b'zlib.level'] <= 9):
802 if not (0 <= options[b'zlib.level'] <= 9):
803 msg = _('invalid value for `storage.revlog.zlib.level` config: %d')
803 msg = _('invalid value for `storage.revlog.zlib.level` config: %d')
804 raise error.Abort(msg % options[b'zlib.level'])
804 raise error.Abort(msg % options[b'zlib.level'])
805 options[b'zstd.level'] = ui.configint(b'storage', b'revlog.zstd.level')
805 options[b'zstd.level'] = ui.configint(b'storage', b'revlog.zstd.level')
806 if options[b'zstd.level'] is not None:
806 if options[b'zstd.level'] is not None:
807 if not (0 <= options[b'zstd.level'] <= 22):
807 if not (0 <= options[b'zstd.level'] <= 22):
808 msg = _('invalid value for `storage.revlog.zstd.level` config: %d')
808 msg = _('invalid value for `storage.revlog.zstd.level` config: %d')
809 raise error.Abort(msg % options[b'zstd.level'])
809 raise error.Abort(msg % options[b'zstd.level'])
810
810
811 if repository.NARROW_REQUIREMENT in requirements:
811 if repository.NARROW_REQUIREMENT in requirements:
812 options[b'enableellipsis'] = True
812 options[b'enableellipsis'] = True
813
813
814 return options
814 return options
815
815
816 def makemain(**kwargs):
816 def makemain(**kwargs):
817 """Produce a type conforming to ``ilocalrepositorymain``."""
817 """Produce a type conforming to ``ilocalrepositorymain``."""
818 return localrepository
818 return localrepository
819
819
820 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
820 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
821 class revlogfilestorage(object):
821 class revlogfilestorage(object):
822 """File storage when using revlogs."""
822 """File storage when using revlogs."""
823
823
824 def file(self, path):
824 def file(self, path):
825 if path[0] == b'/':
825 if path[0] == b'/':
826 path = path[1:]
826 path = path[1:]
827
827
828 return filelog.filelog(self.svfs, path)
828 return filelog.filelog(self.svfs, path)
829
829
830 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
830 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
831 class revlognarrowfilestorage(object):
831 class revlognarrowfilestorage(object):
832 """File storage when using revlogs and narrow files."""
832 """File storage when using revlogs and narrow files."""
833
833
834 def file(self, path):
834 def file(self, path):
835 if path[0] == b'/':
835 if path[0] == b'/':
836 path = path[1:]
836 path = path[1:]
837
837
838 return filelog.narrowfilelog(self.svfs, path, self._storenarrowmatch)
838 return filelog.narrowfilelog(self.svfs, path, self._storenarrowmatch)
839
839
840 def makefilestorage(requirements, features, **kwargs):
840 def makefilestorage(requirements, features, **kwargs):
841 """Produce a type conforming to ``ilocalrepositoryfilestorage``."""
841 """Produce a type conforming to ``ilocalrepositoryfilestorage``."""
842 features.add(repository.REPO_FEATURE_REVLOG_FILE_STORAGE)
842 features.add(repository.REPO_FEATURE_REVLOG_FILE_STORAGE)
843 features.add(repository.REPO_FEATURE_STREAM_CLONE)
843 features.add(repository.REPO_FEATURE_STREAM_CLONE)
844
844
845 if repository.NARROW_REQUIREMENT in requirements:
845 if repository.NARROW_REQUIREMENT in requirements:
846 return revlognarrowfilestorage
846 return revlognarrowfilestorage
847 else:
847 else:
848 return revlogfilestorage
848 return revlogfilestorage
849
849
850 # List of repository interfaces and factory functions for them. Each
850 # List of repository interfaces and factory functions for them. Each
851 # will be called in order during ``makelocalrepository()`` to iteratively
851 # will be called in order during ``makelocalrepository()`` to iteratively
852 # derive the final type for a local repository instance. We capture the
852 # derive the final type for a local repository instance. We capture the
853 # function as a lambda so we don't hold a reference and the module-level
853 # function as a lambda so we don't hold a reference and the module-level
854 # functions can be wrapped.
854 # functions can be wrapped.
855 REPO_INTERFACES = [
855 REPO_INTERFACES = [
856 (repository.ilocalrepositorymain, lambda: makemain),
856 (repository.ilocalrepositorymain, lambda: makemain),
857 (repository.ilocalrepositoryfilestorage, lambda: makefilestorage),
857 (repository.ilocalrepositoryfilestorage, lambda: makefilestorage),
858 ]
858 ]
859
859
860 @interfaceutil.implementer(repository.ilocalrepositorymain)
860 @interfaceutil.implementer(repository.ilocalrepositorymain)
861 class localrepository(object):
861 class localrepository(object):
862 """Main class for representing local repositories.
862 """Main class for representing local repositories.
863
863
864 All local repositories are instances of this class.
864 All local repositories are instances of this class.
865
865
866 Constructed on its own, instances of this class are not usable as
866 Constructed on its own, instances of this class are not usable as
867 repository objects. To obtain a usable repository object, call
867 repository objects. To obtain a usable repository object, call
868 ``hg.repository()``, ``localrepo.instance()``, or
868 ``hg.repository()``, ``localrepo.instance()``, or
869 ``localrepo.makelocalrepository()``. The latter is the lowest-level.
869 ``localrepo.makelocalrepository()``. The latter is the lowest-level.
870 ``instance()`` adds support for creating new repositories.
870 ``instance()`` adds support for creating new repositories.
871 ``hg.repository()`` adds more extension integration, including calling
871 ``hg.repository()`` adds more extension integration, including calling
872 ``reposetup()``. Generally speaking, ``hg.repository()`` should be
872 ``reposetup()``. Generally speaking, ``hg.repository()`` should be
873 used.
873 used.
874 """
874 """
875
875
876 # obsolete experimental requirements:
876 # obsolete experimental requirements:
877 # - manifestv2: An experimental new manifest format that allowed
877 # - manifestv2: An experimental new manifest format that allowed
878 # for stem compression of long paths. Experiment ended up not
878 # for stem compression of long paths. Experiment ended up not
879 # being successful (repository sizes went up due to worse delta
879 # being successful (repository sizes went up due to worse delta
880 # chains), and the code was deleted in 4.6.
880 # chains), and the code was deleted in 4.6.
881 supportedformats = {
881 supportedformats = {
882 'revlogv1',
882 'revlogv1',
883 'generaldelta',
883 'generaldelta',
884 'treemanifest',
884 'treemanifest',
885 REVLOGV2_REQUIREMENT,
885 REVLOGV2_REQUIREMENT,
886 SPARSEREVLOG_REQUIREMENT,
886 SPARSEREVLOG_REQUIREMENT,
887 }
887 }
888 _basesupported = supportedformats | {
888 _basesupported = supportedformats | {
889 'store',
889 'store',
890 'fncache',
890 'fncache',
891 'shared',
891 'shared',
892 'relshared',
892 'relshared',
893 'dotencode',
893 'dotencode',
894 'exp-sparse',
894 'exp-sparse',
895 'internal-phase'
895 'internal-phase'
896 }
896 }
897
897
898 # list of prefix for file which can be written without 'wlock'
898 # list of prefix for file which can be written without 'wlock'
899 # Extensions should extend this list when needed
899 # Extensions should extend this list when needed
900 _wlockfreeprefix = {
900 _wlockfreeprefix = {
901 # We migh consider requiring 'wlock' for the next
901 # We migh consider requiring 'wlock' for the next
902 # two, but pretty much all the existing code assume
902 # two, but pretty much all the existing code assume
903 # wlock is not needed so we keep them excluded for
903 # wlock is not needed so we keep them excluded for
904 # now.
904 # now.
905 'hgrc',
905 'hgrc',
906 'requires',
906 'requires',
907 # XXX cache is a complicatged business someone
907 # XXX cache is a complicatged business someone
908 # should investigate this in depth at some point
908 # should investigate this in depth at some point
909 'cache/',
909 'cache/',
910 # XXX shouldn't be dirstate covered by the wlock?
910 # XXX shouldn't be dirstate covered by the wlock?
911 'dirstate',
911 'dirstate',
912 # XXX bisect was still a bit too messy at the time
912 # XXX bisect was still a bit too messy at the time
913 # this changeset was introduced. Someone should fix
913 # this changeset was introduced. Someone should fix
914 # the remainig bit and drop this line
914 # the remainig bit and drop this line
915 'bisect.state',
915 'bisect.state',
916 }
916 }
917
917
918 def __init__(self, baseui, ui, origroot, wdirvfs, hgvfs, requirements,
918 def __init__(self, baseui, ui, origroot, wdirvfs, hgvfs, requirements,
919 supportedrequirements, sharedpath, store, cachevfs, wcachevfs,
919 supportedrequirements, sharedpath, store, cachevfs, wcachevfs,
920 features, intents=None):
920 features, intents=None):
921 """Create a new local repository instance.
921 """Create a new local repository instance.
922
922
923 Most callers should use ``hg.repository()``, ``localrepo.instance()``,
923 Most callers should use ``hg.repository()``, ``localrepo.instance()``,
924 or ``localrepo.makelocalrepository()`` for obtaining a new repository
924 or ``localrepo.makelocalrepository()`` for obtaining a new repository
925 object.
925 object.
926
926
927 Arguments:
927 Arguments:
928
928
929 baseui
929 baseui
930 ``ui.ui`` instance that ``ui`` argument was based off of.
930 ``ui.ui`` instance that ``ui`` argument was based off of.
931
931
932 ui
932 ui
933 ``ui.ui`` instance for use by the repository.
933 ``ui.ui`` instance for use by the repository.
934
934
935 origroot
935 origroot
936 ``bytes`` path to working directory root of this repository.
936 ``bytes`` path to working directory root of this repository.
937
937
938 wdirvfs
938 wdirvfs
939 ``vfs.vfs`` rooted at the working directory.
939 ``vfs.vfs`` rooted at the working directory.
940
940
941 hgvfs
941 hgvfs
942 ``vfs.vfs`` rooted at .hg/
942 ``vfs.vfs`` rooted at .hg/
943
943
944 requirements
944 requirements
945 ``set`` of bytestrings representing repository opening requirements.
945 ``set`` of bytestrings representing repository opening requirements.
946
946
947 supportedrequirements
947 supportedrequirements
948 ``set`` of bytestrings representing repository requirements that we
948 ``set`` of bytestrings representing repository requirements that we
949 know how to open. May be a supetset of ``requirements``.
949 know how to open. May be a supetset of ``requirements``.
950
950
951 sharedpath
951 sharedpath
952 ``bytes`` Defining path to storage base directory. Points to a
952 ``bytes`` Defining path to storage base directory. Points to a
953 ``.hg/`` directory somewhere.
953 ``.hg/`` directory somewhere.
954
954
955 store
955 store
956 ``store.basicstore`` (or derived) instance providing access to
956 ``store.basicstore`` (or derived) instance providing access to
957 versioned storage.
957 versioned storage.
958
958
959 cachevfs
959 cachevfs
960 ``vfs.vfs`` used for cache files.
960 ``vfs.vfs`` used for cache files.
961
961
962 wcachevfs
962 wcachevfs
963 ``vfs.vfs`` used for cache files related to the working copy.
963 ``vfs.vfs`` used for cache files related to the working copy.
964
964
965 features
965 features
966 ``set`` of bytestrings defining features/capabilities of this
966 ``set`` of bytestrings defining features/capabilities of this
967 instance.
967 instance.
968
968
969 intents
969 intents
970 ``set`` of system strings indicating what this repo will be used
970 ``set`` of system strings indicating what this repo will be used
971 for.
971 for.
972 """
972 """
973 self.baseui = baseui
973 self.baseui = baseui
974 self.ui = ui
974 self.ui = ui
975 self.origroot = origroot
975 self.origroot = origroot
976 # vfs rooted at working directory.
976 # vfs rooted at working directory.
977 self.wvfs = wdirvfs
977 self.wvfs = wdirvfs
978 self.root = wdirvfs.base
978 self.root = wdirvfs.base
979 # vfs rooted at .hg/. Used to access most non-store paths.
979 # vfs rooted at .hg/. Used to access most non-store paths.
980 self.vfs = hgvfs
980 self.vfs = hgvfs
981 self.path = hgvfs.base
981 self.path = hgvfs.base
982 self.requirements = requirements
982 self.requirements = requirements
983 self.supported = supportedrequirements
983 self.supported = supportedrequirements
984 self.sharedpath = sharedpath
984 self.sharedpath = sharedpath
985 self.store = store
985 self.store = store
986 self.cachevfs = cachevfs
986 self.cachevfs = cachevfs
987 self.wcachevfs = wcachevfs
987 self.wcachevfs = wcachevfs
988 self.features = features
988 self.features = features
989
989
990 self.filtername = None
990 self.filtername = None
991
991
992 if (self.ui.configbool('devel', 'all-warnings') or
992 if (self.ui.configbool('devel', 'all-warnings') or
993 self.ui.configbool('devel', 'check-locks')):
993 self.ui.configbool('devel', 'check-locks')):
994 self.vfs.audit = self._getvfsward(self.vfs.audit)
994 self.vfs.audit = self._getvfsward(self.vfs.audit)
995 # A list of callback to shape the phase if no data were found.
995 # A list of callback to shape the phase if no data were found.
996 # Callback are in the form: func(repo, roots) --> processed root.
996 # Callback are in the form: func(repo, roots) --> processed root.
997 # This list it to be filled by extension during repo setup
997 # This list it to be filled by extension during repo setup
998 self._phasedefaults = []
998 self._phasedefaults = []
999
999
1000 color.setup(self.ui)
1000 color.setup(self.ui)
1001
1001
1002 self.spath = self.store.path
1002 self.spath = self.store.path
1003 self.svfs = self.store.vfs
1003 self.svfs = self.store.vfs
1004 self.sjoin = self.store.join
1004 self.sjoin = self.store.join
1005 if (self.ui.configbool('devel', 'all-warnings') or
1005 if (self.ui.configbool('devel', 'all-warnings') or
1006 self.ui.configbool('devel', 'check-locks')):
1006 self.ui.configbool('devel', 'check-locks')):
1007 if util.safehasattr(self.svfs, 'vfs'): # this is filtervfs
1007 if util.safehasattr(self.svfs, 'vfs'): # this is filtervfs
1008 self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit)
1008 self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit)
1009 else: # standard vfs
1009 else: # standard vfs
1010 self.svfs.audit = self._getsvfsward(self.svfs.audit)
1010 self.svfs.audit = self._getsvfsward(self.svfs.audit)
1011
1011
1012 self._dirstatevalidatewarned = False
1012 self._dirstatevalidatewarned = False
1013
1013
1014 self._branchcaches = branchmap.BranchMapCache()
1014 self._branchcaches = branchmap.BranchMapCache()
1015 self._revbranchcache = None
1015 self._revbranchcache = None
1016 self._filterpats = {}
1016 self._filterpats = {}
1017 self._datafilters = {}
1017 self._datafilters = {}
1018 self._transref = self._lockref = self._wlockref = None
1018 self._transref = self._lockref = self._wlockref = None
1019
1019
1020 # A cache for various files under .hg/ that tracks file changes,
1020 # A cache for various files under .hg/ that tracks file changes,
1021 # (used by the filecache decorator)
1021 # (used by the filecache decorator)
1022 #
1022 #
1023 # Maps a property name to its util.filecacheentry
1023 # Maps a property name to its util.filecacheentry
1024 self._filecache = {}
1024 self._filecache = {}
1025
1025
1026 # hold sets of revision to be filtered
1026 # hold sets of revision to be filtered
1027 # should be cleared when something might have changed the filter value:
1027 # should be cleared when something might have changed the filter value:
1028 # - new changesets,
1028 # - new changesets,
1029 # - phase change,
1029 # - phase change,
1030 # - new obsolescence marker,
1030 # - new obsolescence marker,
1031 # - working directory parent change,
1031 # - working directory parent change,
1032 # - bookmark changes
1032 # - bookmark changes
1033 self.filteredrevcache = {}
1033 self.filteredrevcache = {}
1034
1034
1035 # post-dirstate-status hooks
1035 # post-dirstate-status hooks
1036 self._postdsstatus = []
1036 self._postdsstatus = []
1037
1037
1038 # generic mapping between names and nodes
1038 # generic mapping between names and nodes
1039 self.names = namespaces.namespaces()
1039 self.names = namespaces.namespaces()
1040
1040
1041 # Key to signature value.
1041 # Key to signature value.
1042 self._sparsesignaturecache = {}
1042 self._sparsesignaturecache = {}
1043 # Signature to cached matcher instance.
1043 # Signature to cached matcher instance.
1044 self._sparsematchercache = {}
1044 self._sparsematchercache = {}
1045
1045
1046 def _getvfsward(self, origfunc):
1046 def _getvfsward(self, origfunc):
1047 """build a ward for self.vfs"""
1047 """build a ward for self.vfs"""
1048 rref = weakref.ref(self)
1048 rref = weakref.ref(self)
1049 def checkvfs(path, mode=None):
1049 def checkvfs(path, mode=None):
1050 ret = origfunc(path, mode=mode)
1050 ret = origfunc(path, mode=mode)
1051 repo = rref()
1051 repo = rref()
1052 if (repo is None
1052 if (repo is None
1053 or not util.safehasattr(repo, '_wlockref')
1053 or not util.safehasattr(repo, '_wlockref')
1054 or not util.safehasattr(repo, '_lockref')):
1054 or not util.safehasattr(repo, '_lockref')):
1055 return
1055 return
1056 if mode in (None, 'r', 'rb'):
1056 if mode in (None, 'r', 'rb'):
1057 return
1057 return
1058 if path.startswith(repo.path):
1058 if path.startswith(repo.path):
1059 # truncate name relative to the repository (.hg)
1059 # truncate name relative to the repository (.hg)
1060 path = path[len(repo.path) + 1:]
1060 path = path[len(repo.path) + 1:]
1061 if path.startswith('cache/'):
1061 if path.startswith('cache/'):
1062 msg = 'accessing cache with vfs instead of cachevfs: "%s"'
1062 msg = 'accessing cache with vfs instead of cachevfs: "%s"'
1063 repo.ui.develwarn(msg % path, stacklevel=3, config="cache-vfs")
1063 repo.ui.develwarn(msg % path, stacklevel=3, config="cache-vfs")
1064 if path.startswith('journal.') or path.startswith('undo.'):
1064 if path.startswith('journal.') or path.startswith('undo.'):
1065 # journal is covered by 'lock'
1065 # journal is covered by 'lock'
1066 if repo._currentlock(repo._lockref) is None:
1066 if repo._currentlock(repo._lockref) is None:
1067 repo.ui.develwarn('write with no lock: "%s"' % path,
1067 repo.ui.develwarn('write with no lock: "%s"' % path,
1068 stacklevel=3, config='check-locks')
1068 stacklevel=3, config='check-locks')
1069 elif repo._currentlock(repo._wlockref) is None:
1069 elif repo._currentlock(repo._wlockref) is None:
1070 # rest of vfs files are covered by 'wlock'
1070 # rest of vfs files are covered by 'wlock'
1071 #
1071 #
1072 # exclude special files
1072 # exclude special files
1073 for prefix in self._wlockfreeprefix:
1073 for prefix in self._wlockfreeprefix:
1074 if path.startswith(prefix):
1074 if path.startswith(prefix):
1075 return
1075 return
1076 repo.ui.develwarn('write with no wlock: "%s"' % path,
1076 repo.ui.develwarn('write with no wlock: "%s"' % path,
1077 stacklevel=3, config='check-locks')
1077 stacklevel=3, config='check-locks')
1078 return ret
1078 return ret
1079 return checkvfs
1079 return checkvfs
1080
1080
1081 def _getsvfsward(self, origfunc):
1081 def _getsvfsward(self, origfunc):
1082 """build a ward for self.svfs"""
1082 """build a ward for self.svfs"""
1083 rref = weakref.ref(self)
1083 rref = weakref.ref(self)
1084 def checksvfs(path, mode=None):
1084 def checksvfs(path, mode=None):
1085 ret = origfunc(path, mode=mode)
1085 ret = origfunc(path, mode=mode)
1086 repo = rref()
1086 repo = rref()
1087 if repo is None or not util.safehasattr(repo, '_lockref'):
1087 if repo is None or not util.safehasattr(repo, '_lockref'):
1088 return
1088 return
1089 if mode in (None, 'r', 'rb'):
1089 if mode in (None, 'r', 'rb'):
1090 return
1090 return
1091 if path.startswith(repo.sharedpath):
1091 if path.startswith(repo.sharedpath):
1092 # truncate name relative to the repository (.hg)
1092 # truncate name relative to the repository (.hg)
1093 path = path[len(repo.sharedpath) + 1:]
1093 path = path[len(repo.sharedpath) + 1:]
1094 if repo._currentlock(repo._lockref) is None:
1094 if repo._currentlock(repo._lockref) is None:
1095 repo.ui.develwarn('write with no lock: "%s"' % path,
1095 repo.ui.develwarn('write with no lock: "%s"' % path,
1096 stacklevel=4)
1096 stacklevel=4)
1097 return ret
1097 return ret
1098 return checksvfs
1098 return checksvfs
1099
1099
1100 def close(self):
1100 def close(self):
1101 self._writecaches()
1101 self._writecaches()
1102
1102
1103 def _writecaches(self):
1103 def _writecaches(self):
1104 if self._revbranchcache:
1104 if self._revbranchcache:
1105 self._revbranchcache.write()
1105 self._revbranchcache.write()
1106
1106
1107 def _restrictcapabilities(self, caps):
1107 def _restrictcapabilities(self, caps):
1108 if self.ui.configbool('experimental', 'bundle2-advertise'):
1108 if self.ui.configbool('experimental', 'bundle2-advertise'):
1109 caps = set(caps)
1109 caps = set(caps)
1110 capsblob = bundle2.encodecaps(bundle2.getrepocaps(self,
1110 capsblob = bundle2.encodecaps(bundle2.getrepocaps(self,
1111 role='client'))
1111 role='client'))
1112 caps.add('bundle2=' + urlreq.quote(capsblob))
1112 caps.add('bundle2=' + urlreq.quote(capsblob))
1113 return caps
1113 return caps
1114
1114
1115 def _writerequirements(self):
1115 def _writerequirements(self):
1116 scmutil.writerequires(self.vfs, self.requirements)
1116 scmutil.writerequires(self.vfs, self.requirements)
1117
1117
1118 # Don't cache auditor/nofsauditor, or you'll end up with reference cycle:
1118 # Don't cache auditor/nofsauditor, or you'll end up with reference cycle:
1119 # self -> auditor -> self._checknested -> self
1119 # self -> auditor -> self._checknested -> self
1120
1120
1121 @property
1121 @property
1122 def auditor(self):
1122 def auditor(self):
1123 # This is only used by context.workingctx.match in order to
1123 # This is only used by context.workingctx.match in order to
1124 # detect files in subrepos.
1124 # detect files in subrepos.
1125 return pathutil.pathauditor(self.root, callback=self._checknested)
1125 return pathutil.pathauditor(self.root, callback=self._checknested)
1126
1126
1127 @property
1127 @property
1128 def nofsauditor(self):
1128 def nofsauditor(self):
1129 # This is only used by context.basectx.match in order to detect
1129 # This is only used by context.basectx.match in order to detect
1130 # files in subrepos.
1130 # files in subrepos.
1131 return pathutil.pathauditor(self.root, callback=self._checknested,
1131 return pathutil.pathauditor(self.root, callback=self._checknested,
1132 realfs=False, cached=True)
1132 realfs=False, cached=True)
1133
1133
1134 def _checknested(self, path):
1134 def _checknested(self, path):
1135 """Determine if path is a legal nested repository."""
1135 """Determine if path is a legal nested repository."""
1136 if not path.startswith(self.root):
1136 if not path.startswith(self.root):
1137 return False
1137 return False
1138 subpath = path[len(self.root) + 1:]
1138 subpath = path[len(self.root) + 1:]
1139 normsubpath = util.pconvert(subpath)
1139 normsubpath = util.pconvert(subpath)
1140
1140
1141 # XXX: Checking against the current working copy is wrong in
1141 # XXX: Checking against the current working copy is wrong in
1142 # the sense that it can reject things like
1142 # the sense that it can reject things like
1143 #
1143 #
1144 # $ hg cat -r 10 sub/x.txt
1144 # $ hg cat -r 10 sub/x.txt
1145 #
1145 #
1146 # if sub/ is no longer a subrepository in the working copy
1146 # if sub/ is no longer a subrepository in the working copy
1147 # parent revision.
1147 # parent revision.
1148 #
1148 #
1149 # However, it can of course also allow things that would have
1149 # However, it can of course also allow things that would have
1150 # been rejected before, such as the above cat command if sub/
1150 # been rejected before, such as the above cat command if sub/
1151 # is a subrepository now, but was a normal directory before.
1151 # is a subrepository now, but was a normal directory before.
1152 # The old path auditor would have rejected by mistake since it
1152 # The old path auditor would have rejected by mistake since it
1153 # panics when it sees sub/.hg/.
1153 # panics when it sees sub/.hg/.
1154 #
1154 #
1155 # All in all, checking against the working copy seems sensible
1155 # All in all, checking against the working copy seems sensible
1156 # since we want to prevent access to nested repositories on
1156 # since we want to prevent access to nested repositories on
1157 # the filesystem *now*.
1157 # the filesystem *now*.
1158 ctx = self[None]
1158 ctx = self[None]
1159 parts = util.splitpath(subpath)
1159 parts = util.splitpath(subpath)
1160 while parts:
1160 while parts:
1161 prefix = '/'.join(parts)
1161 prefix = '/'.join(parts)
1162 if prefix in ctx.substate:
1162 if prefix in ctx.substate:
1163 if prefix == normsubpath:
1163 if prefix == normsubpath:
1164 return True
1164 return True
1165 else:
1165 else:
1166 sub = ctx.sub(prefix)
1166 sub = ctx.sub(prefix)
1167 return sub.checknested(subpath[len(prefix) + 1:])
1167 return sub.checknested(subpath[len(prefix) + 1:])
1168 else:
1168 else:
1169 parts.pop()
1169 parts.pop()
1170 return False
1170 return False
1171
1171
1172 def peer(self):
1172 def peer(self):
1173 return localpeer(self) # not cached to avoid reference cycle
1173 return localpeer(self) # not cached to avoid reference cycle
1174
1174
1175 def unfiltered(self):
1175 def unfiltered(self):
1176 """Return unfiltered version of the repository
1176 """Return unfiltered version of the repository
1177
1177
1178 Intended to be overwritten by filtered repo."""
1178 Intended to be overwritten by filtered repo."""
1179 return self
1179 return self
1180
1180
1181 def filtered(self, name, visibilityexceptions=None):
1181 def filtered(self, name, visibilityexceptions=None):
1182 """Return a filtered version of a repository"""
1182 """Return a filtered version of a repository"""
1183 cls = repoview.newtype(self.unfiltered().__class__)
1183 cls = repoview.newtype(self.unfiltered().__class__)
1184 return cls(self, name, visibilityexceptions)
1184 return cls(self, name, visibilityexceptions)
1185
1185
1186 @repofilecache('bookmarks', 'bookmarks.current')
1186 @repofilecache('bookmarks', 'bookmarks.current')
1187 def _bookmarks(self):
1187 def _bookmarks(self):
1188 return bookmarks.bmstore(self)
1188 return bookmarks.bmstore(self)
1189
1189
1190 @property
1190 @property
1191 def _activebookmark(self):
1191 def _activebookmark(self):
1192 return self._bookmarks.active
1192 return self._bookmarks.active
1193
1193
1194 # _phasesets depend on changelog. what we need is to call
1194 # _phasesets depend on changelog. what we need is to call
1195 # _phasecache.invalidate() if '00changelog.i' was changed, but it
1195 # _phasecache.invalidate() if '00changelog.i' was changed, but it
1196 # can't be easily expressed in filecache mechanism.
1196 # can't be easily expressed in filecache mechanism.
1197 @storecache('phaseroots', '00changelog.i')
1197 @storecache('phaseroots', '00changelog.i')
1198 def _phasecache(self):
1198 def _phasecache(self):
1199 return phases.phasecache(self, self._phasedefaults)
1199 return phases.phasecache(self, self._phasedefaults)
1200
1200
1201 @storecache('obsstore')
1201 @storecache('obsstore')
1202 def obsstore(self):
1202 def obsstore(self):
1203 return obsolete.makestore(self.ui, self)
1203 return obsolete.makestore(self.ui, self)
1204
1204
1205 @storecache('00changelog.i')
1205 @storecache('00changelog.i')
1206 def changelog(self):
1206 def changelog(self):
1207 return changelog.changelog(self.svfs,
1207 return changelog.changelog(self.svfs,
1208 trypending=txnutil.mayhavepending(self.root))
1208 trypending=txnutil.mayhavepending(self.root))
1209
1209
1210 @storecache('00manifest.i')
1210 @storecache('00manifest.i')
1211 def manifestlog(self):
1211 def manifestlog(self):
1212 rootstore = manifest.manifestrevlog(self.svfs)
1212 rootstore = manifest.manifestrevlog(self.svfs)
1213 return manifest.manifestlog(self.svfs, self, rootstore,
1213 return manifest.manifestlog(self.svfs, self, rootstore,
1214 self._storenarrowmatch)
1214 self._storenarrowmatch)
1215
1215
1216 @repofilecache('dirstate')
1216 @repofilecache('dirstate')
1217 def dirstate(self):
1217 def dirstate(self):
1218 return self._makedirstate()
1218 return self._makedirstate()
1219
1219
1220 def _makedirstate(self):
1220 def _makedirstate(self):
1221 """Extension point for wrapping the dirstate per-repo."""
1221 """Extension point for wrapping the dirstate per-repo."""
1222 sparsematchfn = lambda: sparse.matcher(self)
1222 sparsematchfn = lambda: sparse.matcher(self)
1223
1223
1224 return dirstate.dirstate(self.vfs, self.ui, self.root,
1224 return dirstate.dirstate(self.vfs, self.ui, self.root,
1225 self._dirstatevalidate, sparsematchfn)
1225 self._dirstatevalidate, sparsematchfn)
1226
1226
1227 def _dirstatevalidate(self, node):
1227 def _dirstatevalidate(self, node):
1228 try:
1228 try:
1229 self.changelog.rev(node)
1229 self.changelog.rev(node)
1230 return node
1230 return node
1231 except error.LookupError:
1231 except error.LookupError:
1232 if not self._dirstatevalidatewarned:
1232 if not self._dirstatevalidatewarned:
1233 self._dirstatevalidatewarned = True
1233 self._dirstatevalidatewarned = True
1234 self.ui.warn(_("warning: ignoring unknown"
1234 self.ui.warn(_("warning: ignoring unknown"
1235 " working parent %s!\n") % short(node))
1235 " working parent %s!\n") % short(node))
1236 return nullid
1236 return nullid
1237
1237
1238 @storecache(narrowspec.FILENAME)
1238 @storecache(narrowspec.FILENAME)
1239 def narrowpats(self):
1239 def narrowpats(self):
1240 """matcher patterns for this repository's narrowspec
1240 """matcher patterns for this repository's narrowspec
1241
1241
1242 A tuple of (includes, excludes).
1242 A tuple of (includes, excludes).
1243 """
1243 """
1244 return narrowspec.load(self)
1244 return narrowspec.load(self)
1245
1245
1246 @storecache(narrowspec.FILENAME)
1246 @storecache(narrowspec.FILENAME)
1247 def _storenarrowmatch(self):
1247 def _storenarrowmatch(self):
1248 if repository.NARROW_REQUIREMENT not in self.requirements:
1248 if repository.NARROW_REQUIREMENT not in self.requirements:
1249 return matchmod.always()
1249 return matchmod.always()
1250 include, exclude = self.narrowpats
1250 include, exclude = self.narrowpats
1251 return narrowspec.match(self.root, include=include, exclude=exclude)
1251 return narrowspec.match(self.root, include=include, exclude=exclude)
1252
1252
1253 @storecache(narrowspec.FILENAME)
1253 @storecache(narrowspec.FILENAME)
1254 def _narrowmatch(self):
1254 def _narrowmatch(self):
1255 if repository.NARROW_REQUIREMENT not in self.requirements:
1255 if repository.NARROW_REQUIREMENT not in self.requirements:
1256 return matchmod.always()
1256 return matchmod.always()
1257 narrowspec.checkworkingcopynarrowspec(self)
1257 narrowspec.checkworkingcopynarrowspec(self)
1258 include, exclude = self.narrowpats
1258 include, exclude = self.narrowpats
1259 return narrowspec.match(self.root, include=include, exclude=exclude)
1259 return narrowspec.match(self.root, include=include, exclude=exclude)
1260
1260
1261 def narrowmatch(self, match=None, includeexact=False):
1261 def narrowmatch(self, match=None, includeexact=False):
1262 """matcher corresponding the the repo's narrowspec
1262 """matcher corresponding the the repo's narrowspec
1263
1263
1264 If `match` is given, then that will be intersected with the narrow
1264 If `match` is given, then that will be intersected with the narrow
1265 matcher.
1265 matcher.
1266
1266
1267 If `includeexact` is True, then any exact matches from `match` will
1267 If `includeexact` is True, then any exact matches from `match` will
1268 be included even if they're outside the narrowspec.
1268 be included even if they're outside the narrowspec.
1269 """
1269 """
1270 if match:
1270 if match:
1271 if includeexact and not self._narrowmatch.always():
1271 if includeexact and not self._narrowmatch.always():
1272 # do not exclude explicitly-specified paths so that they can
1272 # do not exclude explicitly-specified paths so that they can
1273 # be warned later on
1273 # be warned later on
1274 em = matchmod.exact(match.files())
1274 em = matchmod.exact(match.files())
1275 nm = matchmod.unionmatcher([self._narrowmatch, em])
1275 nm = matchmod.unionmatcher([self._narrowmatch, em])
1276 return matchmod.intersectmatchers(match, nm)
1276 return matchmod.intersectmatchers(match, nm)
1277 return matchmod.intersectmatchers(match, self._narrowmatch)
1277 return matchmod.intersectmatchers(match, self._narrowmatch)
1278 return self._narrowmatch
1278 return self._narrowmatch
1279
1279
1280 def setnarrowpats(self, newincludes, newexcludes):
1280 def setnarrowpats(self, newincludes, newexcludes):
1281 narrowspec.save(self, newincludes, newexcludes)
1281 narrowspec.save(self, newincludes, newexcludes)
1282 self.invalidate(clearfilecache=True)
1282 self.invalidate(clearfilecache=True)
1283
1283
1284 def __getitem__(self, changeid):
1284 def __getitem__(self, changeid):
1285 if changeid is None:
1285 if changeid is None:
1286 return context.workingctx(self)
1286 return context.workingctx(self)
1287 if isinstance(changeid, context.basectx):
1287 if isinstance(changeid, context.basectx):
1288 return changeid
1288 return changeid
1289 if isinstance(changeid, slice):
1289 if isinstance(changeid, slice):
1290 # wdirrev isn't contiguous so the slice shouldn't include it
1290 # wdirrev isn't contiguous so the slice shouldn't include it
1291 return [self[i]
1291 return [self[i]
1292 for i in pycompat.xrange(*changeid.indices(len(self)))
1292 for i in pycompat.xrange(*changeid.indices(len(self)))
1293 if i not in self.changelog.filteredrevs]
1293 if i not in self.changelog.filteredrevs]
1294 try:
1294 try:
1295 if isinstance(changeid, int):
1295 if isinstance(changeid, int):
1296 node = self.changelog.node(changeid)
1296 node = self.changelog.node(changeid)
1297 rev = changeid
1297 rev = changeid
1298 elif changeid == 'null':
1298 elif changeid == 'null':
1299 node = nullid
1299 node = nullid
1300 rev = nullrev
1300 rev = nullrev
1301 elif changeid == 'tip':
1301 elif changeid == 'tip':
1302 node = self.changelog.tip()
1302 node = self.changelog.tip()
1303 rev = self.changelog.rev(node)
1303 rev = self.changelog.rev(node)
1304 elif changeid == '.':
1304 elif changeid == '.':
1305 # this is a hack to delay/avoid loading obsmarkers
1305 # this is a hack to delay/avoid loading obsmarkers
1306 # when we know that '.' won't be hidden
1306 # when we know that '.' won't be hidden
1307 node = self.dirstate.p1()
1307 node = self.dirstate.p1()
1308 rev = self.unfiltered().changelog.rev(node)
1308 rev = self.unfiltered().changelog.rev(node)
1309 elif len(changeid) == 20:
1309 elif len(changeid) == 20:
1310 try:
1310 try:
1311 node = changeid
1311 node = changeid
1312 rev = self.changelog.rev(changeid)
1312 rev = self.changelog.rev(changeid)
1313 except error.FilteredLookupError:
1313 except error.FilteredLookupError:
1314 changeid = hex(changeid) # for the error message
1314 changeid = hex(changeid) # for the error message
1315 raise
1315 raise
1316 except LookupError:
1316 except LookupError:
1317 # check if it might have come from damaged dirstate
1317 # check if it might have come from damaged dirstate
1318 #
1318 #
1319 # XXX we could avoid the unfiltered if we had a recognizable
1319 # XXX we could avoid the unfiltered if we had a recognizable
1320 # exception for filtered changeset access
1320 # exception for filtered changeset access
1321 if (self.local()
1321 if (self.local()
1322 and changeid in self.unfiltered().dirstate.parents()):
1322 and changeid in self.unfiltered().dirstate.parents()):
1323 msg = _("working directory has unknown parent '%s'!")
1323 msg = _("working directory has unknown parent '%s'!")
1324 raise error.Abort(msg % short(changeid))
1324 raise error.Abort(msg % short(changeid))
1325 changeid = hex(changeid) # for the error message
1325 changeid = hex(changeid) # for the error message
1326 raise
1326 raise
1327
1327
1328 elif len(changeid) == 40:
1328 elif len(changeid) == 40:
1329 node = bin(changeid)
1329 node = bin(changeid)
1330 rev = self.changelog.rev(node)
1330 rev = self.changelog.rev(node)
1331 else:
1331 else:
1332 raise error.ProgrammingError(
1332 raise error.ProgrammingError(
1333 "unsupported changeid '%s' of type %s" %
1333 "unsupported changeid '%s' of type %s" %
1334 (changeid, type(changeid)))
1334 (changeid, type(changeid)))
1335
1335
1336 return context.changectx(self, rev, node)
1336 return context.changectx(self, rev, node)
1337
1337
1338 except (error.FilteredIndexError, error.FilteredLookupError):
1338 except (error.FilteredIndexError, error.FilteredLookupError):
1339 raise error.FilteredRepoLookupError(_("filtered revision '%s'")
1339 raise error.FilteredRepoLookupError(_("filtered revision '%s'")
1340 % pycompat.bytestr(changeid))
1340 % pycompat.bytestr(changeid))
1341 except (IndexError, LookupError):
1341 except (IndexError, LookupError):
1342 raise error.RepoLookupError(
1342 raise error.RepoLookupError(
1343 _("unknown revision '%s'") % pycompat.bytestr(changeid))
1343 _("unknown revision '%s'") % pycompat.bytestr(changeid))
1344 except error.WdirUnsupported:
1344 except error.WdirUnsupported:
1345 return context.workingctx(self)
1345 return context.workingctx(self)
1346
1346
1347 def __contains__(self, changeid):
1347 def __contains__(self, changeid):
1348 """True if the given changeid exists
1348 """True if the given changeid exists
1349
1349
1350 error.AmbiguousPrefixLookupError is raised if an ambiguous node
1350 error.AmbiguousPrefixLookupError is raised if an ambiguous node
1351 specified.
1351 specified.
1352 """
1352 """
1353 try:
1353 try:
1354 self[changeid]
1354 self[changeid]
1355 return True
1355 return True
1356 except error.RepoLookupError:
1356 except error.RepoLookupError:
1357 return False
1357 return False
1358
1358
1359 def __nonzero__(self):
1359 def __nonzero__(self):
1360 return True
1360 return True
1361
1361
1362 __bool__ = __nonzero__
1362 __bool__ = __nonzero__
1363
1363
1364 def __len__(self):
1364 def __len__(self):
1365 # no need to pay the cost of repoview.changelog
1365 # no need to pay the cost of repoview.changelog
1366 unfi = self.unfiltered()
1366 unfi = self.unfiltered()
1367 return len(unfi.changelog)
1367 return len(unfi.changelog)
1368
1368
1369 def __iter__(self):
1369 def __iter__(self):
1370 return iter(self.changelog)
1370 return iter(self.changelog)
1371
1371
1372 def revs(self, expr, *args):
1372 def revs(self, expr, *args):
1373 '''Find revisions matching a revset.
1373 '''Find revisions matching a revset.
1374
1374
1375 The revset is specified as a string ``expr`` that may contain
1375 The revset is specified as a string ``expr`` that may contain
1376 %-formatting to escape certain types. See ``revsetlang.formatspec``.
1376 %-formatting to escape certain types. See ``revsetlang.formatspec``.
1377
1377
1378 Revset aliases from the configuration are not expanded. To expand
1378 Revset aliases from the configuration are not expanded. To expand
1379 user aliases, consider calling ``scmutil.revrange()`` or
1379 user aliases, consider calling ``scmutil.revrange()`` or
1380 ``repo.anyrevs([expr], user=True)``.
1380 ``repo.anyrevs([expr], user=True)``.
1381
1381
1382 Returns a revset.abstractsmartset, which is a list-like interface
1382 Returns a revset.abstractsmartset, which is a list-like interface
1383 that contains integer revisions.
1383 that contains integer revisions.
1384 '''
1384 '''
1385 tree = revsetlang.spectree(expr, *args)
1385 tree = revsetlang.spectree(expr, *args)
1386 return revset.makematcher(tree)(self)
1386 return revset.makematcher(tree)(self)
1387
1387
1388 def set(self, expr, *args):
1388 def set(self, expr, *args):
1389 '''Find revisions matching a revset and emit changectx instances.
1389 '''Find revisions matching a revset and emit changectx instances.
1390
1390
1391 This is a convenience wrapper around ``revs()`` that iterates the
1391 This is a convenience wrapper around ``revs()`` that iterates the
1392 result and is a generator of changectx instances.
1392 result and is a generator of changectx instances.
1393
1393
1394 Revset aliases from the configuration are not expanded. To expand
1394 Revset aliases from the configuration are not expanded. To expand
1395 user aliases, consider calling ``scmutil.revrange()``.
1395 user aliases, consider calling ``scmutil.revrange()``.
1396 '''
1396 '''
1397 for r in self.revs(expr, *args):
1397 for r in self.revs(expr, *args):
1398 yield self[r]
1398 yield self[r]
1399
1399
1400 def anyrevs(self, specs, user=False, localalias=None):
1400 def anyrevs(self, specs, user=False, localalias=None):
1401 '''Find revisions matching one of the given revsets.
1401 '''Find revisions matching one of the given revsets.
1402
1402
1403 Revset aliases from the configuration are not expanded by default. To
1403 Revset aliases from the configuration are not expanded by default. To
1404 expand user aliases, specify ``user=True``. To provide some local
1404 expand user aliases, specify ``user=True``. To provide some local
1405 definitions overriding user aliases, set ``localalias`` to
1405 definitions overriding user aliases, set ``localalias`` to
1406 ``{name: definitionstring}``.
1406 ``{name: definitionstring}``.
1407 '''
1407 '''
1408 if user:
1408 if user:
1409 m = revset.matchany(self.ui, specs,
1409 m = revset.matchany(self.ui, specs,
1410 lookup=revset.lookupfn(self),
1410 lookup=revset.lookupfn(self),
1411 localalias=localalias)
1411 localalias=localalias)
1412 else:
1412 else:
1413 m = revset.matchany(None, specs, localalias=localalias)
1413 m = revset.matchany(None, specs, localalias=localalias)
1414 return m(self)
1414 return m(self)
1415
1415
1416 def url(self):
1416 def url(self):
1417 return 'file:' + self.root
1417 return 'file:' + self.root
1418
1418
1419 def hook(self, name, throw=False, **args):
1419 def hook(self, name, throw=False, **args):
1420 """Call a hook, passing this repo instance.
1420 """Call a hook, passing this repo instance.
1421
1421
1422 This a convenience method to aid invoking hooks. Extensions likely
1422 This a convenience method to aid invoking hooks. Extensions likely
1423 won't call this unless they have registered a custom hook or are
1423 won't call this unless they have registered a custom hook or are
1424 replacing code that is expected to call a hook.
1424 replacing code that is expected to call a hook.
1425 """
1425 """
1426 return hook.hook(self.ui, self, name, throw, **args)
1426 return hook.hook(self.ui, self, name, throw, **args)
1427
1427
1428 @filteredpropertycache
1428 @filteredpropertycache
1429 def _tagscache(self):
1429 def _tagscache(self):
1430 '''Returns a tagscache object that contains various tags related
1430 '''Returns a tagscache object that contains various tags related
1431 caches.'''
1431 caches.'''
1432
1432
1433 # This simplifies its cache management by having one decorated
1433 # This simplifies its cache management by having one decorated
1434 # function (this one) and the rest simply fetch things from it.
1434 # function (this one) and the rest simply fetch things from it.
1435 class tagscache(object):
1435 class tagscache(object):
1436 def __init__(self):
1436 def __init__(self):
1437 # These two define the set of tags for this repository. tags
1437 # These two define the set of tags for this repository. tags
1438 # maps tag name to node; tagtypes maps tag name to 'global' or
1438 # maps tag name to node; tagtypes maps tag name to 'global' or
1439 # 'local'. (Global tags are defined by .hgtags across all
1439 # 'local'. (Global tags are defined by .hgtags across all
1440 # heads, and local tags are defined in .hg/localtags.)
1440 # heads, and local tags are defined in .hg/localtags.)
1441 # They constitute the in-memory cache of tags.
1441 # They constitute the in-memory cache of tags.
1442 self.tags = self.tagtypes = None
1442 self.tags = self.tagtypes = None
1443
1443
1444 self.nodetagscache = self.tagslist = None
1444 self.nodetagscache = self.tagslist = None
1445
1445
1446 cache = tagscache()
1446 cache = tagscache()
1447 cache.tags, cache.tagtypes = self._findtags()
1447 cache.tags, cache.tagtypes = self._findtags()
1448
1448
1449 return cache
1449 return cache
1450
1450
1451 def tags(self):
1451 def tags(self):
1452 '''return a mapping of tag to node'''
1452 '''return a mapping of tag to node'''
1453 t = {}
1453 t = {}
1454 if self.changelog.filteredrevs:
1454 if self.changelog.filteredrevs:
1455 tags, tt = self._findtags()
1455 tags, tt = self._findtags()
1456 else:
1456 else:
1457 tags = self._tagscache.tags
1457 tags = self._tagscache.tags
1458 rev = self.changelog.rev
1458 rev = self.changelog.rev
1459 for k, v in tags.iteritems():
1459 for k, v in tags.iteritems():
1460 try:
1460 try:
1461 # ignore tags to unknown nodes
1461 # ignore tags to unknown nodes
1462 rev(v)
1462 rev(v)
1463 t[k] = v
1463 t[k] = v
1464 except (error.LookupError, ValueError):
1464 except (error.LookupError, ValueError):
1465 pass
1465 pass
1466 return t
1466 return t
1467
1467
1468 def _findtags(self):
1468 def _findtags(self):
1469 '''Do the hard work of finding tags. Return a pair of dicts
1469 '''Do the hard work of finding tags. Return a pair of dicts
1470 (tags, tagtypes) where tags maps tag name to node, and tagtypes
1470 (tags, tagtypes) where tags maps tag name to node, and tagtypes
1471 maps tag name to a string like \'global\' or \'local\'.
1471 maps tag name to a string like \'global\' or \'local\'.
1472 Subclasses or extensions are free to add their own tags, but
1472 Subclasses or extensions are free to add their own tags, but
1473 should be aware that the returned dicts will be retained for the
1473 should be aware that the returned dicts will be retained for the
1474 duration of the localrepo object.'''
1474 duration of the localrepo object.'''
1475
1475
1476 # XXX what tagtype should subclasses/extensions use? Currently
1476 # XXX what tagtype should subclasses/extensions use? Currently
1477 # mq and bookmarks add tags, but do not set the tagtype at all.
1477 # mq and bookmarks add tags, but do not set the tagtype at all.
1478 # Should each extension invent its own tag type? Should there
1478 # Should each extension invent its own tag type? Should there
1479 # be one tagtype for all such "virtual" tags? Or is the status
1479 # be one tagtype for all such "virtual" tags? Or is the status
1480 # quo fine?
1480 # quo fine?
1481
1481
1482
1482
1483 # map tag name to (node, hist)
1483 # map tag name to (node, hist)
1484 alltags = tagsmod.findglobaltags(self.ui, self)
1484 alltags = tagsmod.findglobaltags(self.ui, self)
1485 # map tag name to tag type
1485 # map tag name to tag type
1486 tagtypes = dict((tag, 'global') for tag in alltags)
1486 tagtypes = dict((tag, 'global') for tag in alltags)
1487
1487
1488 tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
1488 tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
1489
1489
1490 # Build the return dicts. Have to re-encode tag names because
1490 # Build the return dicts. Have to re-encode tag names because
1491 # the tags module always uses UTF-8 (in order not to lose info
1491 # the tags module always uses UTF-8 (in order not to lose info
1492 # writing to the cache), but the rest of Mercurial wants them in
1492 # writing to the cache), but the rest of Mercurial wants them in
1493 # local encoding.
1493 # local encoding.
1494 tags = {}
1494 tags = {}
1495 for (name, (node, hist)) in alltags.iteritems():
1495 for (name, (node, hist)) in alltags.iteritems():
1496 if node != nullid:
1496 if node != nullid:
1497 tags[encoding.tolocal(name)] = node
1497 tags[encoding.tolocal(name)] = node
1498 tags['tip'] = self.changelog.tip()
1498 tags['tip'] = self.changelog.tip()
1499 tagtypes = dict([(encoding.tolocal(name), value)
1499 tagtypes = dict([(encoding.tolocal(name), value)
1500 for (name, value) in tagtypes.iteritems()])
1500 for (name, value) in tagtypes.iteritems()])
1501 return (tags, tagtypes)
1501 return (tags, tagtypes)
1502
1502
1503 def tagtype(self, tagname):
1503 def tagtype(self, tagname):
1504 '''
1504 '''
1505 return the type of the given tag. result can be:
1505 return the type of the given tag. result can be:
1506
1506
1507 'local' : a local tag
1507 'local' : a local tag
1508 'global' : a global tag
1508 'global' : a global tag
1509 None : tag does not exist
1509 None : tag does not exist
1510 '''
1510 '''
1511
1511
1512 return self._tagscache.tagtypes.get(tagname)
1512 return self._tagscache.tagtypes.get(tagname)
1513
1513
1514 def tagslist(self):
1514 def tagslist(self):
1515 '''return a list of tags ordered by revision'''
1515 '''return a list of tags ordered by revision'''
1516 if not self._tagscache.tagslist:
1516 if not self._tagscache.tagslist:
1517 l = []
1517 l = []
1518 for t, n in self.tags().iteritems():
1518 for t, n in self.tags().iteritems():
1519 l.append((self.changelog.rev(n), t, n))
1519 l.append((self.changelog.rev(n), t, n))
1520 self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)]
1520 self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)]
1521
1521
1522 return self._tagscache.tagslist
1522 return self._tagscache.tagslist
1523
1523
1524 def nodetags(self, node):
1524 def nodetags(self, node):
1525 '''return the tags associated with a node'''
1525 '''return the tags associated with a node'''
1526 if not self._tagscache.nodetagscache:
1526 if not self._tagscache.nodetagscache:
1527 nodetagscache = {}
1527 nodetagscache = {}
1528 for t, n in self._tagscache.tags.iteritems():
1528 for t, n in self._tagscache.tags.iteritems():
1529 nodetagscache.setdefault(n, []).append(t)
1529 nodetagscache.setdefault(n, []).append(t)
1530 for tags in nodetagscache.itervalues():
1530 for tags in nodetagscache.itervalues():
1531 tags.sort()
1531 tags.sort()
1532 self._tagscache.nodetagscache = nodetagscache
1532 self._tagscache.nodetagscache = nodetagscache
1533 return self._tagscache.nodetagscache.get(node, [])
1533 return self._tagscache.nodetagscache.get(node, [])
1534
1534
1535 def nodebookmarks(self, node):
1535 def nodebookmarks(self, node):
1536 """return the list of bookmarks pointing to the specified node"""
1536 """return the list of bookmarks pointing to the specified node"""
1537 return self._bookmarks.names(node)
1537 return self._bookmarks.names(node)
1538
1538
1539 def branchmap(self):
1539 def branchmap(self):
1540 '''returns a dictionary {branch: [branchheads]} with branchheads
1540 '''returns a dictionary {branch: [branchheads]} with branchheads
1541 ordered by increasing revision number'''
1541 ordered by increasing revision number'''
1542 return self._branchcaches[self]
1542 return self._branchcaches[self]
1543
1543
1544 @unfilteredmethod
1544 @unfilteredmethod
1545 def revbranchcache(self):
1545 def revbranchcache(self):
1546 if not self._revbranchcache:
1546 if not self._revbranchcache:
1547 self._revbranchcache = branchmap.revbranchcache(self.unfiltered())
1547 self._revbranchcache = branchmap.revbranchcache(self.unfiltered())
1548 return self._revbranchcache
1548 return self._revbranchcache
1549
1549
1550 def branchtip(self, branch, ignoremissing=False):
1550 def branchtip(self, branch, ignoremissing=False):
1551 '''return the tip node for a given branch
1551 '''return the tip node for a given branch
1552
1552
1553 If ignoremissing is True, then this method will not raise an error.
1553 If ignoremissing is True, then this method will not raise an error.
1554 This is helpful for callers that only expect None for a missing branch
1554 This is helpful for callers that only expect None for a missing branch
1555 (e.g. namespace).
1555 (e.g. namespace).
1556
1556
1557 '''
1557 '''
1558 try:
1558 try:
1559 return self.branchmap().branchtip(branch)
1559 return self.branchmap().branchtip(branch)
1560 except KeyError:
1560 except KeyError:
1561 if not ignoremissing:
1561 if not ignoremissing:
1562 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
1562 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
1563 else:
1563 else:
1564 pass
1564 pass
1565
1565
1566 def lookup(self, key):
1566 def lookup(self, key):
1567 return scmutil.revsymbol(self, key).node()
1567 return scmutil.revsymbol(self, key).node()
1568
1568
1569 def lookupbranch(self, key):
1569 def lookupbranch(self, key):
1570 if self.branchmap().hasbranch(key):
1570 if self.branchmap().hasbranch(key):
1571 return key
1571 return key
1572
1572
1573 return scmutil.revsymbol(self, key).branch()
1573 return scmutil.revsymbol(self, key).branch()
1574
1574
1575 def known(self, nodes):
1575 def known(self, nodes):
1576 cl = self.changelog
1576 cl = self.changelog
1577 nm = cl.nodemap
1577 nm = cl.nodemap
1578 filtered = cl.filteredrevs
1578 filtered = cl.filteredrevs
1579 result = []
1579 result = []
1580 for n in nodes:
1580 for n in nodes:
1581 r = nm.get(n)
1581 r = nm.get(n)
1582 resp = not (r is None or r in filtered)
1582 resp = not (r is None or r in filtered)
1583 result.append(resp)
1583 result.append(resp)
1584 return result
1584 return result
1585
1585
1586 def local(self):
1586 def local(self):
1587 return self
1587 return self
1588
1588
1589 def publishing(self):
1589 def publishing(self):
1590 # it's safe (and desirable) to trust the publish flag unconditionally
1590 # it's safe (and desirable) to trust the publish flag unconditionally
1591 # so that we don't finalize changes shared between users via ssh or nfs
1591 # so that we don't finalize changes shared between users via ssh or nfs
1592 return self.ui.configbool('phases', 'publish', untrusted=True)
1592 return self.ui.configbool('phases', 'publish', untrusted=True)
1593
1593
1594 def cancopy(self):
1594 def cancopy(self):
1595 # so statichttprepo's override of local() works
1595 # so statichttprepo's override of local() works
1596 if not self.local():
1596 if not self.local():
1597 return False
1597 return False
1598 if not self.publishing():
1598 if not self.publishing():
1599 return True
1599 return True
1600 # if publishing we can't copy if there is filtered content
1600 # if publishing we can't copy if there is filtered content
1601 return not self.filtered('visible').changelog.filteredrevs
1601 return not self.filtered('visible').changelog.filteredrevs
1602
1602
1603 def shared(self):
1603 def shared(self):
1604 '''the type of shared repository (None if not shared)'''
1604 '''the type of shared repository (None if not shared)'''
1605 if self.sharedpath != self.path:
1605 if self.sharedpath != self.path:
1606 return 'store'
1606 return 'store'
1607 return None
1607 return None
1608
1608
1609 def wjoin(self, f, *insidef):
1609 def wjoin(self, f, *insidef):
1610 return self.vfs.reljoin(self.root, f, *insidef)
1610 return self.vfs.reljoin(self.root, f, *insidef)
1611
1611
1612 def setparents(self, p1, p2=nullid):
1612 def setparents(self, p1, p2=nullid):
1613 with self.dirstate.parentchange():
1613 with self.dirstate.parentchange():
1614 copies = self.dirstate.setparents(p1, p2)
1614 copies = self.dirstate.setparents(p1, p2)
1615 pctx = self[p1]
1615 pctx = self[p1]
1616 if copies:
1616 if copies:
1617 # Adjust copy records, the dirstate cannot do it, it
1617 # Adjust copy records, the dirstate cannot do it, it
1618 # requires access to parents manifests. Preserve them
1618 # requires access to parents manifests. Preserve them
1619 # only for entries added to first parent.
1619 # only for entries added to first parent.
1620 for f in copies:
1620 for f in copies:
1621 if f not in pctx and copies[f] in pctx:
1621 if f not in pctx and copies[f] in pctx:
1622 self.dirstate.copy(copies[f], f)
1622 self.dirstate.copy(copies[f], f)
1623 if p2 == nullid:
1623 if p2 == nullid:
1624 for f, s in sorted(self.dirstate.copies().items()):
1624 for f, s in sorted(self.dirstate.copies().items()):
1625 if f not in pctx and s not in pctx:
1625 if f not in pctx and s not in pctx:
1626 self.dirstate.copy(None, f)
1626 self.dirstate.copy(None, f)
1627
1627
1628 def filectx(self, path, changeid=None, fileid=None, changectx=None):
1628 def filectx(self, path, changeid=None, fileid=None, changectx=None):
1629 """changeid must be a changeset revision, if specified.
1629 """changeid must be a changeset revision, if specified.
1630 fileid can be a file revision or node."""
1630 fileid can be a file revision or node."""
1631 return context.filectx(self, path, changeid, fileid,
1631 return context.filectx(self, path, changeid, fileid,
1632 changectx=changectx)
1632 changectx=changectx)
1633
1633
1634 def getcwd(self):
1634 def getcwd(self):
1635 return self.dirstate.getcwd()
1635 return self.dirstate.getcwd()
1636
1636
1637 def pathto(self, f, cwd=None):
1637 def pathto(self, f, cwd=None):
1638 return self.dirstate.pathto(f, cwd)
1638 return self.dirstate.pathto(f, cwd)
1639
1639
1640 def _loadfilter(self, filter):
1640 def _loadfilter(self, filter):
1641 if filter not in self._filterpats:
1641 if filter not in self._filterpats:
1642 l = []
1642 l = []
1643 for pat, cmd in self.ui.configitems(filter):
1643 for pat, cmd in self.ui.configitems(filter):
1644 if cmd == '!':
1644 if cmd == '!':
1645 continue
1645 continue
1646 mf = matchmod.match(self.root, '', [pat])
1646 mf = matchmod.match(self.root, '', [pat])
1647 fn = None
1647 fn = None
1648 params = cmd
1648 params = cmd
1649 for name, filterfn in self._datafilters.iteritems():
1649 for name, filterfn in self._datafilters.iteritems():
1650 if cmd.startswith(name):
1650 if cmd.startswith(name):
1651 fn = filterfn
1651 fn = filterfn
1652 params = cmd[len(name):].lstrip()
1652 params = cmd[len(name):].lstrip()
1653 break
1653 break
1654 if not fn:
1654 if not fn:
1655 fn = lambda s, c, **kwargs: procutil.filter(s, c)
1655 fn = lambda s, c, **kwargs: procutil.filter(s, c)
1656 # Wrap old filters not supporting keyword arguments
1656 # Wrap old filters not supporting keyword arguments
1657 if not pycompat.getargspec(fn)[2]:
1657 if not pycompat.getargspec(fn)[2]:
1658 oldfn = fn
1658 oldfn = fn
1659 fn = lambda s, c, **kwargs: oldfn(s, c)
1659 fn = lambda s, c, **kwargs: oldfn(s, c)
1660 l.append((mf, fn, params))
1660 l.append((mf, fn, params))
1661 self._filterpats[filter] = l
1661 self._filterpats[filter] = l
1662 return self._filterpats[filter]
1662 return self._filterpats[filter]
1663
1663
1664 def _filter(self, filterpats, filename, data):
1664 def _filter(self, filterpats, filename, data):
1665 for mf, fn, cmd in filterpats:
1665 for mf, fn, cmd in filterpats:
1666 if mf(filename):
1666 if mf(filename):
1667 self.ui.debug("filtering %s through %s\n" % (filename, cmd))
1667 self.ui.debug("filtering %s through %s\n" % (filename, cmd))
1668 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
1668 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
1669 break
1669 break
1670
1670
1671 return data
1671 return data
1672
1672
1673 @unfilteredpropertycache
1673 @unfilteredpropertycache
1674 def _encodefilterpats(self):
1674 def _encodefilterpats(self):
1675 return self._loadfilter('encode')
1675 return self._loadfilter('encode')
1676
1676
1677 @unfilteredpropertycache
1677 @unfilteredpropertycache
1678 def _decodefilterpats(self):
1678 def _decodefilterpats(self):
1679 return self._loadfilter('decode')
1679 return self._loadfilter('decode')
1680
1680
1681 def adddatafilter(self, name, filter):
1681 def adddatafilter(self, name, filter):
1682 self._datafilters[name] = filter
1682 self._datafilters[name] = filter
1683
1683
1684 def wread(self, filename):
1684 def wread(self, filename):
1685 if self.wvfs.islink(filename):
1685 if self.wvfs.islink(filename):
1686 data = self.wvfs.readlink(filename)
1686 data = self.wvfs.readlink(filename)
1687 else:
1687 else:
1688 data = self.wvfs.read(filename)
1688 data = self.wvfs.read(filename)
1689 return self._filter(self._encodefilterpats, filename, data)
1689 return self._filter(self._encodefilterpats, filename, data)
1690
1690
1691 def wwrite(self, filename, data, flags, backgroundclose=False, **kwargs):
1691 def wwrite(self, filename, data, flags, backgroundclose=False, **kwargs):
1692 """write ``data`` into ``filename`` in the working directory
1692 """write ``data`` into ``filename`` in the working directory
1693
1693
1694 This returns length of written (maybe decoded) data.
1694 This returns length of written (maybe decoded) data.
1695 """
1695 """
1696 data = self._filter(self._decodefilterpats, filename, data)
1696 data = self._filter(self._decodefilterpats, filename, data)
1697 if 'l' in flags:
1697 if 'l' in flags:
1698 self.wvfs.symlink(data, filename)
1698 self.wvfs.symlink(data, filename)
1699 else:
1699 else:
1700 self.wvfs.write(filename, data, backgroundclose=backgroundclose,
1700 self.wvfs.write(filename, data, backgroundclose=backgroundclose,
1701 **kwargs)
1701 **kwargs)
1702 if 'x' in flags:
1702 if 'x' in flags:
1703 self.wvfs.setflags(filename, False, True)
1703 self.wvfs.setflags(filename, False, True)
1704 else:
1704 else:
1705 self.wvfs.setflags(filename, False, False)
1705 self.wvfs.setflags(filename, False, False)
1706 return len(data)
1706 return len(data)
1707
1707
1708 def wwritedata(self, filename, data):
1708 def wwritedata(self, filename, data):
1709 return self._filter(self._decodefilterpats, filename, data)
1709 return self._filter(self._decodefilterpats, filename, data)
1710
1710
1711 def currenttransaction(self):
1711 def currenttransaction(self):
1712 """return the current transaction or None if non exists"""
1712 """return the current transaction or None if non exists"""
1713 if self._transref:
1713 if self._transref:
1714 tr = self._transref()
1714 tr = self._transref()
1715 else:
1715 else:
1716 tr = None
1716 tr = None
1717
1717
1718 if tr and tr.running():
1718 if tr and tr.running():
1719 return tr
1719 return tr
1720 return None
1720 return None
1721
1721
1722 def transaction(self, desc, report=None):
1722 def transaction(self, desc, report=None):
1723 if (self.ui.configbool('devel', 'all-warnings')
1723 if (self.ui.configbool('devel', 'all-warnings')
1724 or self.ui.configbool('devel', 'check-locks')):
1724 or self.ui.configbool('devel', 'check-locks')):
1725 if self._currentlock(self._lockref) is None:
1725 if self._currentlock(self._lockref) is None:
1726 raise error.ProgrammingError('transaction requires locking')
1726 raise error.ProgrammingError('transaction requires locking')
1727 tr = self.currenttransaction()
1727 tr = self.currenttransaction()
1728 if tr is not None:
1728 if tr is not None:
1729 return tr.nest(name=desc)
1729 return tr.nest(name=desc)
1730
1730
1731 # abort here if the journal already exists
1731 # abort here if the journal already exists
1732 if self.svfs.exists("journal"):
1732 if self.svfs.exists("journal"):
1733 raise error.RepoError(
1733 raise error.RepoError(
1734 _("abandoned transaction found"),
1734 _("abandoned transaction found"),
1735 hint=_("run 'hg recover' to clean up transaction"))
1735 hint=_("run 'hg recover' to clean up transaction"))
1736
1736
1737 idbase = "%.40f#%f" % (random.random(), time.time())
1737 idbase = "%.40f#%f" % (random.random(), time.time())
1738 ha = hex(hashlib.sha1(idbase).digest())
1738 ha = hex(hashlib.sha1(idbase).digest())
1739 txnid = 'TXN:' + ha
1739 txnid = 'TXN:' + ha
1740 self.hook('pretxnopen', throw=True, txnname=desc, txnid=txnid)
1740 self.hook('pretxnopen', throw=True, txnname=desc, txnid=txnid)
1741
1741
1742 self._writejournal(desc)
1742 self._writejournal(desc)
1743 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()]
1743 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()]
1744 if report:
1744 if report:
1745 rp = report
1745 rp = report
1746 else:
1746 else:
1747 rp = self.ui.warn
1747 rp = self.ui.warn
1748 vfsmap = {'plain': self.vfs, 'store': self.svfs} # root of .hg/
1748 vfsmap = {'plain': self.vfs, 'store': self.svfs} # root of .hg/
1749 # we must avoid cyclic reference between repo and transaction.
1749 # we must avoid cyclic reference between repo and transaction.
1750 reporef = weakref.ref(self)
1750 reporef = weakref.ref(self)
1751 # Code to track tag movement
1751 # Code to track tag movement
1752 #
1752 #
1753 # Since tags are all handled as file content, it is actually quite hard
1753 # Since tags are all handled as file content, it is actually quite hard
1754 # to track these movement from a code perspective. So we fallback to a
1754 # to track these movement from a code perspective. So we fallback to a
1755 # tracking at the repository level. One could envision to track changes
1755 # tracking at the repository level. One could envision to track changes
1756 # to the '.hgtags' file through changegroup apply but that fails to
1756 # to the '.hgtags' file through changegroup apply but that fails to
1757 # cope with case where transaction expose new heads without changegroup
1757 # cope with case where transaction expose new heads without changegroup
1758 # being involved (eg: phase movement).
1758 # being involved (eg: phase movement).
1759 #
1759 #
1760 # For now, We gate the feature behind a flag since this likely comes
1760 # For now, We gate the feature behind a flag since this likely comes
1761 # with performance impacts. The current code run more often than needed
1761 # with performance impacts. The current code run more often than needed
1762 # and do not use caches as much as it could. The current focus is on
1762 # and do not use caches as much as it could. The current focus is on
1763 # the behavior of the feature so we disable it by default. The flag
1763 # the behavior of the feature so we disable it by default. The flag
1764 # will be removed when we are happy with the performance impact.
1764 # will be removed when we are happy with the performance impact.
1765 #
1765 #
1766 # Once this feature is no longer experimental move the following
1766 # Once this feature is no longer experimental move the following
1767 # documentation to the appropriate help section:
1767 # documentation to the appropriate help section:
1768 #
1768 #
1769 # The ``HG_TAG_MOVED`` variable will be set if the transaction touched
1769 # The ``HG_TAG_MOVED`` variable will be set if the transaction touched
1770 # tags (new or changed or deleted tags). In addition the details of
1770 # tags (new or changed or deleted tags). In addition the details of
1771 # these changes are made available in a file at:
1771 # these changes are made available in a file at:
1772 # ``REPOROOT/.hg/changes/tags.changes``.
1772 # ``REPOROOT/.hg/changes/tags.changes``.
1773 # Make sure you check for HG_TAG_MOVED before reading that file as it
1773 # Make sure you check for HG_TAG_MOVED before reading that file as it
1774 # might exist from a previous transaction even if no tag were touched
1774 # might exist from a previous transaction even if no tag were touched
1775 # in this one. Changes are recorded in a line base format::
1775 # in this one. Changes are recorded in a line base format::
1776 #
1776 #
1777 # <action> <hex-node> <tag-name>\n
1777 # <action> <hex-node> <tag-name>\n
1778 #
1778 #
1779 # Actions are defined as follow:
1779 # Actions are defined as follow:
1780 # "-R": tag is removed,
1780 # "-R": tag is removed,
1781 # "+A": tag is added,
1781 # "+A": tag is added,
1782 # "-M": tag is moved (old value),
1782 # "-M": tag is moved (old value),
1783 # "+M": tag is moved (new value),
1783 # "+M": tag is moved (new value),
1784 tracktags = lambda x: None
1784 tracktags = lambda x: None
1785 # experimental config: experimental.hook-track-tags
1785 # experimental config: experimental.hook-track-tags
1786 shouldtracktags = self.ui.configbool('experimental', 'hook-track-tags')
1786 shouldtracktags = self.ui.configbool('experimental', 'hook-track-tags')
1787 if desc != 'strip' and shouldtracktags:
1787 if desc != 'strip' and shouldtracktags:
1788 oldheads = self.changelog.headrevs()
1788 oldheads = self.changelog.headrevs()
1789 def tracktags(tr2):
1789 def tracktags(tr2):
1790 repo = reporef()
1790 repo = reporef()
1791 oldfnodes = tagsmod.fnoderevs(repo.ui, repo, oldheads)
1791 oldfnodes = tagsmod.fnoderevs(repo.ui, repo, oldheads)
1792 newheads = repo.changelog.headrevs()
1792 newheads = repo.changelog.headrevs()
1793 newfnodes = tagsmod.fnoderevs(repo.ui, repo, newheads)
1793 newfnodes = tagsmod.fnoderevs(repo.ui, repo, newheads)
1794 # notes: we compare lists here.
1794 # notes: we compare lists here.
1795 # As we do it only once buiding set would not be cheaper
1795 # As we do it only once buiding set would not be cheaper
1796 changes = tagsmod.difftags(repo.ui, repo, oldfnodes, newfnodes)
1796 changes = tagsmod.difftags(repo.ui, repo, oldfnodes, newfnodes)
1797 if changes:
1797 if changes:
1798 tr2.hookargs['tag_moved'] = '1'
1798 tr2.hookargs['tag_moved'] = '1'
1799 with repo.vfs('changes/tags.changes', 'w',
1799 with repo.vfs('changes/tags.changes', 'w',
1800 atomictemp=True) as changesfile:
1800 atomictemp=True) as changesfile:
1801 # note: we do not register the file to the transaction
1801 # note: we do not register the file to the transaction
1802 # because we needs it to still exist on the transaction
1802 # because we needs it to still exist on the transaction
1803 # is close (for txnclose hooks)
1803 # is close (for txnclose hooks)
1804 tagsmod.writediff(changesfile, changes)
1804 tagsmod.writediff(changesfile, changes)
1805 def validate(tr2):
1805 def validate(tr2):
1806 """will run pre-closing hooks"""
1806 """will run pre-closing hooks"""
1807 # XXX the transaction API is a bit lacking here so we take a hacky
1807 # XXX the transaction API is a bit lacking here so we take a hacky
1808 # path for now
1808 # path for now
1809 #
1809 #
1810 # We cannot add this as a "pending" hooks since the 'tr.hookargs'
1810 # We cannot add this as a "pending" hooks since the 'tr.hookargs'
1811 # dict is copied before these run. In addition we needs the data
1811 # dict is copied before these run. In addition we needs the data
1812 # available to in memory hooks too.
1812 # available to in memory hooks too.
1813 #
1813 #
1814 # Moreover, we also need to make sure this runs before txnclose
1814 # Moreover, we also need to make sure this runs before txnclose
1815 # hooks and there is no "pending" mechanism that would execute
1815 # hooks and there is no "pending" mechanism that would execute
1816 # logic only if hooks are about to run.
1816 # logic only if hooks are about to run.
1817 #
1817 #
1818 # Fixing this limitation of the transaction is also needed to track
1818 # Fixing this limitation of the transaction is also needed to track
1819 # other families of changes (bookmarks, phases, obsolescence).
1819 # other families of changes (bookmarks, phases, obsolescence).
1820 #
1820 #
1821 # This will have to be fixed before we remove the experimental
1821 # This will have to be fixed before we remove the experimental
1822 # gating.
1822 # gating.
1823 tracktags(tr2)
1823 tracktags(tr2)
1824 repo = reporef()
1824 repo = reporef()
1825 if repo.ui.configbool('experimental', 'single-head-per-branch'):
1825 if repo.ui.configbool('experimental', 'single-head-per-branch'):
1826 scmutil.enforcesinglehead(repo, tr2, desc)
1826 scmutil.enforcesinglehead(repo, tr2, desc)
1827 if hook.hashook(repo.ui, 'pretxnclose-bookmark'):
1827 if hook.hashook(repo.ui, 'pretxnclose-bookmark'):
1828 for name, (old, new) in sorted(tr.changes['bookmarks'].items()):
1828 for name, (old, new) in sorted(tr.changes['bookmarks'].items()):
1829 args = tr.hookargs.copy()
1829 args = tr.hookargs.copy()
1830 args.update(bookmarks.preparehookargs(name, old, new))
1830 args.update(bookmarks.preparehookargs(name, old, new))
1831 repo.hook('pretxnclose-bookmark', throw=True,
1831 repo.hook('pretxnclose-bookmark', throw=True,
1832 **pycompat.strkwargs(args))
1832 **pycompat.strkwargs(args))
1833 if hook.hashook(repo.ui, 'pretxnclose-phase'):
1833 if hook.hashook(repo.ui, 'pretxnclose-phase'):
1834 cl = repo.unfiltered().changelog
1834 cl = repo.unfiltered().changelog
1835 for rev, (old, new) in tr.changes['phases'].items():
1835 for rev, (old, new) in tr.changes['phases'].items():
1836 args = tr.hookargs.copy()
1836 args = tr.hookargs.copy()
1837 node = hex(cl.node(rev))
1837 node = hex(cl.node(rev))
1838 args.update(phases.preparehookargs(node, old, new))
1838 args.update(phases.preparehookargs(node, old, new))
1839 repo.hook('pretxnclose-phase', throw=True,
1839 repo.hook('pretxnclose-phase', throw=True,
1840 **pycompat.strkwargs(args))
1840 **pycompat.strkwargs(args))
1841
1841
1842 repo.hook('pretxnclose', throw=True,
1842 repo.hook('pretxnclose', throw=True,
1843 **pycompat.strkwargs(tr.hookargs))
1843 **pycompat.strkwargs(tr.hookargs))
1844 def releasefn(tr, success):
1844 def releasefn(tr, success):
1845 repo = reporef()
1845 repo = reporef()
1846 if success:
1846 if success:
1847 # this should be explicitly invoked here, because
1847 # this should be explicitly invoked here, because
1848 # in-memory changes aren't written out at closing
1848 # in-memory changes aren't written out at closing
1849 # transaction, if tr.addfilegenerator (via
1849 # transaction, if tr.addfilegenerator (via
1850 # dirstate.write or so) isn't invoked while
1850 # dirstate.write or so) isn't invoked while
1851 # transaction running
1851 # transaction running
1852 repo.dirstate.write(None)
1852 repo.dirstate.write(None)
1853 else:
1853 else:
1854 # discard all changes (including ones already written
1854 # discard all changes (including ones already written
1855 # out) in this transaction
1855 # out) in this transaction
1856 narrowspec.restorebackup(self, 'journal.narrowspec')
1856 narrowspec.restorebackup(self, 'journal.narrowspec')
1857 narrowspec.restorewcbackup(self, 'journal.narrowspec.dirstate')
1857 narrowspec.restorewcbackup(self, 'journal.narrowspec.dirstate')
1858 repo.dirstate.restorebackup(None, 'journal.dirstate')
1858 repo.dirstate.restorebackup(None, 'journal.dirstate')
1859
1859
1860 repo.invalidate(clearfilecache=True)
1860 repo.invalidate(clearfilecache=True)
1861
1861
1862 tr = transaction.transaction(rp, self.svfs, vfsmap,
1862 tr = transaction.transaction(rp, self.svfs, vfsmap,
1863 "journal",
1863 "journal",
1864 "undo",
1864 "undo",
1865 aftertrans(renames),
1865 aftertrans(renames),
1866 self.store.createmode,
1866 self.store.createmode,
1867 validator=validate,
1867 validator=validate,
1868 releasefn=releasefn,
1868 releasefn=releasefn,
1869 checkambigfiles=_cachedfiles,
1869 checkambigfiles=_cachedfiles,
1870 name=desc)
1870 name=desc)
1871 tr.changes['origrepolen'] = len(self)
1871 tr.changes['origrepolen'] = len(self)
1872 tr.changes['obsmarkers'] = set()
1872 tr.changes['obsmarkers'] = set()
1873 tr.changes['phases'] = {}
1873 tr.changes['phases'] = {}
1874 tr.changes['bookmarks'] = {}
1874 tr.changes['bookmarks'] = {}
1875
1875
1876 tr.hookargs['txnid'] = txnid
1876 tr.hookargs['txnid'] = txnid
1877 tr.hookargs['txnname'] = desc
1877 tr.hookargs['txnname'] = desc
1878 # note: writing the fncache only during finalize mean that the file is
1878 # note: writing the fncache only during finalize mean that the file is
1879 # outdated when running hooks. As fncache is used for streaming clone,
1879 # outdated when running hooks. As fncache is used for streaming clone,
1880 # this is not expected to break anything that happen during the hooks.
1880 # this is not expected to break anything that happen during the hooks.
1881 tr.addfinalize('flush-fncache', self.store.write)
1881 tr.addfinalize('flush-fncache', self.store.write)
1882 def txnclosehook(tr2):
1882 def txnclosehook(tr2):
1883 """To be run if transaction is successful, will schedule a hook run
1883 """To be run if transaction is successful, will schedule a hook run
1884 """
1884 """
1885 # Don't reference tr2 in hook() so we don't hold a reference.
1885 # Don't reference tr2 in hook() so we don't hold a reference.
1886 # This reduces memory consumption when there are multiple
1886 # This reduces memory consumption when there are multiple
1887 # transactions per lock. This can likely go away if issue5045
1887 # transactions per lock. This can likely go away if issue5045
1888 # fixes the function accumulation.
1888 # fixes the function accumulation.
1889 hookargs = tr2.hookargs
1889 hookargs = tr2.hookargs
1890
1890
1891 def hookfunc():
1891 def hookfunc():
1892 repo = reporef()
1892 repo = reporef()
1893 if hook.hashook(repo.ui, 'txnclose-bookmark'):
1893 if hook.hashook(repo.ui, 'txnclose-bookmark'):
1894 bmchanges = sorted(tr.changes['bookmarks'].items())
1894 bmchanges = sorted(tr.changes['bookmarks'].items())
1895 for name, (old, new) in bmchanges:
1895 for name, (old, new) in bmchanges:
1896 args = tr.hookargs.copy()
1896 args = tr.hookargs.copy()
1897 args.update(bookmarks.preparehookargs(name, old, new))
1897 args.update(bookmarks.preparehookargs(name, old, new))
1898 repo.hook('txnclose-bookmark', throw=False,
1898 repo.hook('txnclose-bookmark', throw=False,
1899 **pycompat.strkwargs(args))
1899 **pycompat.strkwargs(args))
1900
1900
1901 if hook.hashook(repo.ui, 'txnclose-phase'):
1901 if hook.hashook(repo.ui, 'txnclose-phase'):
1902 cl = repo.unfiltered().changelog
1902 cl = repo.unfiltered().changelog
1903 phasemv = sorted(tr.changes['phases'].items())
1903 phasemv = sorted(tr.changes['phases'].items())
1904 for rev, (old, new) in phasemv:
1904 for rev, (old, new) in phasemv:
1905 args = tr.hookargs.copy()
1905 args = tr.hookargs.copy()
1906 node = hex(cl.node(rev))
1906 node = hex(cl.node(rev))
1907 args.update(phases.preparehookargs(node, old, new))
1907 args.update(phases.preparehookargs(node, old, new))
1908 repo.hook('txnclose-phase', throw=False,
1908 repo.hook('txnclose-phase', throw=False,
1909 **pycompat.strkwargs(args))
1909 **pycompat.strkwargs(args))
1910
1910
1911 repo.hook('txnclose', throw=False,
1911 repo.hook('txnclose', throw=False,
1912 **pycompat.strkwargs(hookargs))
1912 **pycompat.strkwargs(hookargs))
1913 reporef()._afterlock(hookfunc)
1913 reporef()._afterlock(hookfunc)
1914 tr.addfinalize('txnclose-hook', txnclosehook)
1914 tr.addfinalize('txnclose-hook', txnclosehook)
1915 # Include a leading "-" to make it happen before the transaction summary
1915 # Include a leading "-" to make it happen before the transaction summary
1916 # reports registered via scmutil.registersummarycallback() whose names
1916 # reports registered via scmutil.registersummarycallback() whose names
1917 # are 00-txnreport etc. That way, the caches will be warm when the
1917 # are 00-txnreport etc. That way, the caches will be warm when the
1918 # callbacks run.
1918 # callbacks run.
1919 tr.addpostclose('-warm-cache', self._buildcacheupdater(tr))
1919 tr.addpostclose('-warm-cache', self._buildcacheupdater(tr))
1920 def txnaborthook(tr2):
1920 def txnaborthook(tr2):
1921 """To be run if transaction is aborted
1921 """To be run if transaction is aborted
1922 """
1922 """
1923 reporef().hook('txnabort', throw=False,
1923 reporef().hook('txnabort', throw=False,
1924 **pycompat.strkwargs(tr2.hookargs))
1924 **pycompat.strkwargs(tr2.hookargs))
1925 tr.addabort('txnabort-hook', txnaborthook)
1925 tr.addabort('txnabort-hook', txnaborthook)
1926 # avoid eager cache invalidation. in-memory data should be identical
1926 # avoid eager cache invalidation. in-memory data should be identical
1927 # to stored data if transaction has no error.
1927 # to stored data if transaction has no error.
1928 tr.addpostclose('refresh-filecachestats', self._refreshfilecachestats)
1928 tr.addpostclose('refresh-filecachestats', self._refreshfilecachestats)
1929 self._transref = weakref.ref(tr)
1929 self._transref = weakref.ref(tr)
1930 scmutil.registersummarycallback(self, tr, desc)
1930 scmutil.registersummarycallback(self, tr, desc)
1931 return tr
1931 return tr
1932
1932
1933 def _journalfiles(self):
1933 def _journalfiles(self):
1934 return ((self.svfs, 'journal'),
1934 return ((self.svfs, 'journal'),
1935 (self.svfs, 'journal.narrowspec'),
1935 (self.svfs, 'journal.narrowspec'),
1936 (self.vfs, 'journal.narrowspec.dirstate'),
1936 (self.vfs, 'journal.narrowspec.dirstate'),
1937 (self.vfs, 'journal.dirstate'),
1937 (self.vfs, 'journal.dirstate'),
1938 (self.vfs, 'journal.branch'),
1938 (self.vfs, 'journal.branch'),
1939 (self.vfs, 'journal.desc'),
1939 (self.vfs, 'journal.desc'),
1940 (self.vfs, 'journal.bookmarks'),
1940 (self.vfs, 'journal.bookmarks'),
1941 (self.svfs, 'journal.phaseroots'))
1941 (self.svfs, 'journal.phaseroots'))
1942
1942
1943 def undofiles(self):
1943 def undofiles(self):
1944 return [(vfs, undoname(x)) for vfs, x in self._journalfiles()]
1944 return [(vfs, undoname(x)) for vfs, x in self._journalfiles()]
1945
1945
1946 @unfilteredmethod
1946 @unfilteredmethod
1947 def _writejournal(self, desc):
1947 def _writejournal(self, desc):
1948 self.dirstate.savebackup(None, 'journal.dirstate')
1948 self.dirstate.savebackup(None, 'journal.dirstate')
1949 narrowspec.savewcbackup(self, 'journal.narrowspec.dirstate')
1949 narrowspec.savewcbackup(self, 'journal.narrowspec.dirstate')
1950 narrowspec.savebackup(self, 'journal.narrowspec')
1950 narrowspec.savebackup(self, 'journal.narrowspec')
1951 self.vfs.write("journal.branch",
1951 self.vfs.write("journal.branch",
1952 encoding.fromlocal(self.dirstate.branch()))
1952 encoding.fromlocal(self.dirstate.branch()))
1953 self.vfs.write("journal.desc",
1953 self.vfs.write("journal.desc",
1954 "%d\n%s\n" % (len(self), desc))
1954 "%d\n%s\n" % (len(self), desc))
1955 self.vfs.write("journal.bookmarks",
1955 self.vfs.write("journal.bookmarks",
1956 self.vfs.tryread("bookmarks"))
1956 self.vfs.tryread("bookmarks"))
1957 self.svfs.write("journal.phaseroots",
1957 self.svfs.write("journal.phaseroots",
1958 self.svfs.tryread("phaseroots"))
1958 self.svfs.tryread("phaseroots"))
1959
1959
1960 def recover(self):
1960 def recover(self):
1961 with self.lock():
1961 with self.lock():
1962 if self.svfs.exists("journal"):
1962 if self.svfs.exists("journal"):
1963 self.ui.status(_("rolling back interrupted transaction\n"))
1963 self.ui.status(_("rolling back interrupted transaction\n"))
1964 vfsmap = {'': self.svfs,
1964 vfsmap = {'': self.svfs,
1965 'plain': self.vfs,}
1965 'plain': self.vfs,}
1966 transaction.rollback(self.svfs, vfsmap, "journal",
1966 transaction.rollback(self.svfs, vfsmap, "journal",
1967 self.ui.warn,
1967 self.ui.warn,
1968 checkambigfiles=_cachedfiles)
1968 checkambigfiles=_cachedfiles)
1969 self.invalidate()
1969 self.invalidate()
1970 return True
1970 return True
1971 else:
1971 else:
1972 self.ui.warn(_("no interrupted transaction available\n"))
1972 self.ui.warn(_("no interrupted transaction available\n"))
1973 return False
1973 return False
1974
1974
1975 def rollback(self, dryrun=False, force=False):
1975 def rollback(self, dryrun=False, force=False):
1976 wlock = lock = dsguard = None
1976 wlock = lock = dsguard = None
1977 try:
1977 try:
1978 wlock = self.wlock()
1978 wlock = self.wlock()
1979 lock = self.lock()
1979 lock = self.lock()
1980 if self.svfs.exists("undo"):
1980 if self.svfs.exists("undo"):
1981 dsguard = dirstateguard.dirstateguard(self, 'rollback')
1981 dsguard = dirstateguard.dirstateguard(self, 'rollback')
1982
1982
1983 return self._rollback(dryrun, force, dsguard)
1983 return self._rollback(dryrun, force, dsguard)
1984 else:
1984 else:
1985 self.ui.warn(_("no rollback information available\n"))
1985 self.ui.warn(_("no rollback information available\n"))
1986 return 1
1986 return 1
1987 finally:
1987 finally:
1988 release(dsguard, lock, wlock)
1988 release(dsguard, lock, wlock)
1989
1989
1990 @unfilteredmethod # Until we get smarter cache management
1990 @unfilteredmethod # Until we get smarter cache management
1991 def _rollback(self, dryrun, force, dsguard):
1991 def _rollback(self, dryrun, force, dsguard):
1992 ui = self.ui
1992 ui = self.ui
1993 try:
1993 try:
1994 args = self.vfs.read('undo.desc').splitlines()
1994 args = self.vfs.read('undo.desc').splitlines()
1995 (oldlen, desc, detail) = (int(args[0]), args[1], None)
1995 (oldlen, desc, detail) = (int(args[0]), args[1], None)
1996 if len(args) >= 3:
1996 if len(args) >= 3:
1997 detail = args[2]
1997 detail = args[2]
1998 oldtip = oldlen - 1
1998 oldtip = oldlen - 1
1999
1999
2000 if detail and ui.verbose:
2000 if detail and ui.verbose:
2001 msg = (_('repository tip rolled back to revision %d'
2001 msg = (_('repository tip rolled back to revision %d'
2002 ' (undo %s: %s)\n')
2002 ' (undo %s: %s)\n')
2003 % (oldtip, desc, detail))
2003 % (oldtip, desc, detail))
2004 else:
2004 else:
2005 msg = (_('repository tip rolled back to revision %d'
2005 msg = (_('repository tip rolled back to revision %d'
2006 ' (undo %s)\n')
2006 ' (undo %s)\n')
2007 % (oldtip, desc))
2007 % (oldtip, desc))
2008 except IOError:
2008 except IOError:
2009 msg = _('rolling back unknown transaction\n')
2009 msg = _('rolling back unknown transaction\n')
2010 desc = None
2010 desc = None
2011
2011
2012 if not force and self['.'] != self['tip'] and desc == 'commit':
2012 if not force and self['.'] != self['tip'] and desc == 'commit':
2013 raise error.Abort(
2013 raise error.Abort(
2014 _('rollback of last commit while not checked out '
2014 _('rollback of last commit while not checked out '
2015 'may lose data'), hint=_('use -f to force'))
2015 'may lose data'), hint=_('use -f to force'))
2016
2016
2017 ui.status(msg)
2017 ui.status(msg)
2018 if dryrun:
2018 if dryrun:
2019 return 0
2019 return 0
2020
2020
2021 parents = self.dirstate.parents()
2021 parents = self.dirstate.parents()
2022 self.destroying()
2022 self.destroying()
2023 vfsmap = {'plain': self.vfs, '': self.svfs}
2023 vfsmap = {'plain': self.vfs, '': self.svfs}
2024 transaction.rollback(self.svfs, vfsmap, 'undo', ui.warn,
2024 transaction.rollback(self.svfs, vfsmap, 'undo', ui.warn,
2025 checkambigfiles=_cachedfiles)
2025 checkambigfiles=_cachedfiles)
2026 if self.vfs.exists('undo.bookmarks'):
2026 if self.vfs.exists('undo.bookmarks'):
2027 self.vfs.rename('undo.bookmarks', 'bookmarks', checkambig=True)
2027 self.vfs.rename('undo.bookmarks', 'bookmarks', checkambig=True)
2028 if self.svfs.exists('undo.phaseroots'):
2028 if self.svfs.exists('undo.phaseroots'):
2029 self.svfs.rename('undo.phaseroots', 'phaseroots', checkambig=True)
2029 self.svfs.rename('undo.phaseroots', 'phaseroots', checkambig=True)
2030 self.invalidate()
2030 self.invalidate()
2031
2031
2032 parentgone = any(p not in self.changelog.nodemap for p in parents)
2032 parentgone = any(p not in self.changelog.nodemap for p in parents)
2033 if parentgone:
2033 if parentgone:
2034 # prevent dirstateguard from overwriting already restored one
2034 # prevent dirstateguard from overwriting already restored one
2035 dsguard.close()
2035 dsguard.close()
2036
2036
2037 narrowspec.restorebackup(self, 'undo.narrowspec')
2037 narrowspec.restorebackup(self, 'undo.narrowspec')
2038 narrowspec.restorewcbackup(self, 'undo.narrowspec.dirstate')
2038 narrowspec.restorewcbackup(self, 'undo.narrowspec.dirstate')
2039 self.dirstate.restorebackup(None, 'undo.dirstate')
2039 self.dirstate.restorebackup(None, 'undo.dirstate')
2040 try:
2040 try:
2041 branch = self.vfs.read('undo.branch')
2041 branch = self.vfs.read('undo.branch')
2042 self.dirstate.setbranch(encoding.tolocal(branch))
2042 self.dirstate.setbranch(encoding.tolocal(branch))
2043 except IOError:
2043 except IOError:
2044 ui.warn(_('named branch could not be reset: '
2044 ui.warn(_('named branch could not be reset: '
2045 'current branch is still \'%s\'\n')
2045 'current branch is still \'%s\'\n')
2046 % self.dirstate.branch())
2046 % self.dirstate.branch())
2047
2047
2048 parents = tuple([p.rev() for p in self[None].parents()])
2048 parents = tuple([p.rev() for p in self[None].parents()])
2049 if len(parents) > 1:
2049 if len(parents) > 1:
2050 ui.status(_('working directory now based on '
2050 ui.status(_('working directory now based on '
2051 'revisions %d and %d\n') % parents)
2051 'revisions %d and %d\n') % parents)
2052 else:
2052 else:
2053 ui.status(_('working directory now based on '
2053 ui.status(_('working directory now based on '
2054 'revision %d\n') % parents)
2054 'revision %d\n') % parents)
2055 mergemod.mergestate.clean(self, self['.'].node())
2055 mergemod.mergestate.clean(self, self['.'].node())
2056
2056
2057 # TODO: if we know which new heads may result from this rollback, pass
2057 # TODO: if we know which new heads may result from this rollback, pass
2058 # them to destroy(), which will prevent the branchhead cache from being
2058 # them to destroy(), which will prevent the branchhead cache from being
2059 # invalidated.
2059 # invalidated.
2060 self.destroyed()
2060 self.destroyed()
2061 return 0
2061 return 0
2062
2062
2063 def _buildcacheupdater(self, newtransaction):
2063 def _buildcacheupdater(self, newtransaction):
2064 """called during transaction to build the callback updating cache
2064 """called during transaction to build the callback updating cache
2065
2065
2066 Lives on the repository to help extension who might want to augment
2066 Lives on the repository to help extension who might want to augment
2067 this logic. For this purpose, the created transaction is passed to the
2067 this logic. For this purpose, the created transaction is passed to the
2068 method.
2068 method.
2069 """
2069 """
2070 # we must avoid cyclic reference between repo and transaction.
2070 # we must avoid cyclic reference between repo and transaction.
2071 reporef = weakref.ref(self)
2071 reporef = weakref.ref(self)
2072 def updater(tr):
2072 def updater(tr):
2073 repo = reporef()
2073 repo = reporef()
2074 repo.updatecaches(tr)
2074 repo.updatecaches(tr)
2075 return updater
2075 return updater
2076
2076
2077 @unfilteredmethod
2077 @unfilteredmethod
2078 def updatecaches(self, tr=None, full=False):
2078 def updatecaches(self, tr=None, full=False):
2079 """warm appropriate caches
2079 """warm appropriate caches
2080
2080
2081 If this function is called after a transaction closed. The transaction
2081 If this function is called after a transaction closed. The transaction
2082 will be available in the 'tr' argument. This can be used to selectively
2082 will be available in the 'tr' argument. This can be used to selectively
2083 update caches relevant to the changes in that transaction.
2083 update caches relevant to the changes in that transaction.
2084
2084
2085 If 'full' is set, make sure all caches the function knows about have
2085 If 'full' is set, make sure all caches the function knows about have
2086 up-to-date data. Even the ones usually loaded more lazily.
2086 up-to-date data. Even the ones usually loaded more lazily.
2087 """
2087 """
2088 if tr is not None and tr.hookargs.get('source') == 'strip':
2088 if tr is not None and tr.hookargs.get('source') == 'strip':
2089 # During strip, many caches are invalid but
2089 # During strip, many caches are invalid but
2090 # later call to `destroyed` will refresh them.
2090 # later call to `destroyed` will refresh them.
2091 return
2091 return
2092
2092
2093 if tr is None or tr.changes['origrepolen'] < len(self):
2093 if tr is None or tr.changes['origrepolen'] < len(self):
2094 # accessing the 'ser ved' branchmap should refresh all the others,
2094 # accessing the 'ser ved' branchmap should refresh all the others,
2095 self.ui.debug('updating the branch cache\n')
2095 self.ui.debug('updating the branch cache\n')
2096 self.filtered('served').branchmap()
2096 self.filtered('served').branchmap()
2097
2097
2098 if full:
2098 if full:
2099 unfi = self.unfiltered()
2099 unfi = self.unfiltered()
2100 rbc = unfi.revbranchcache()
2100 rbc = unfi.revbranchcache()
2101 for r in unfi.changelog:
2101 for r in unfi.changelog:
2102 rbc.branchinfo(r)
2102 rbc.branchinfo(r)
2103 rbc.write()
2103 rbc.write()
2104
2104
2105 # ensure the working copy parents are in the manifestfulltextcache
2105 # ensure the working copy parents are in the manifestfulltextcache
2106 for ctx in self['.'].parents():
2106 for ctx in self['.'].parents():
2107 ctx.manifest() # accessing the manifest is enough
2107 ctx.manifest() # accessing the manifest is enough
2108
2108
2109 # accessing tags warm the cache
2109 # accessing tags warm the cache
2110 self.tags()
2110 self.tags()
2111 self.filtered('served').tags()
2111 self.filtered('served').tags()
2112
2112
2113 def invalidatecaches(self):
2113 def invalidatecaches(self):
2114
2114
2115 if r'_tagscache' in vars(self):
2115 if r'_tagscache' in vars(self):
2116 # can't use delattr on proxy
2116 # can't use delattr on proxy
2117 del self.__dict__[r'_tagscache']
2117 del self.__dict__[r'_tagscache']
2118
2118
2119 self._branchcaches.clear()
2119 self._branchcaches.clear()
2120 self.invalidatevolatilesets()
2120 self.invalidatevolatilesets()
2121 self._sparsesignaturecache.clear()
2121 self._sparsesignaturecache.clear()
2122
2122
2123 def invalidatevolatilesets(self):
2123 def invalidatevolatilesets(self):
2124 self.filteredrevcache.clear()
2124 self.filteredrevcache.clear()
2125 obsolete.clearobscaches(self)
2125 obsolete.clearobscaches(self)
2126
2126
2127 def invalidatedirstate(self):
2127 def invalidatedirstate(self):
2128 '''Invalidates the dirstate, causing the next call to dirstate
2128 '''Invalidates the dirstate, causing the next call to dirstate
2129 to check if it was modified since the last time it was read,
2129 to check if it was modified since the last time it was read,
2130 rereading it if it has.
2130 rereading it if it has.
2131
2131
2132 This is different to dirstate.invalidate() that it doesn't always
2132 This is different to dirstate.invalidate() that it doesn't always
2133 rereads the dirstate. Use dirstate.invalidate() if you want to
2133 rereads the dirstate. Use dirstate.invalidate() if you want to
2134 explicitly read the dirstate again (i.e. restoring it to a previous
2134 explicitly read the dirstate again (i.e. restoring it to a previous
2135 known good state).'''
2135 known good state).'''
2136 if hasunfilteredcache(self, r'dirstate'):
2136 if hasunfilteredcache(self, r'dirstate'):
2137 for k in self.dirstate._filecache:
2137 for k in self.dirstate._filecache:
2138 try:
2138 try:
2139 delattr(self.dirstate, k)
2139 delattr(self.dirstate, k)
2140 except AttributeError:
2140 except AttributeError:
2141 pass
2141 pass
2142 delattr(self.unfiltered(), r'dirstate')
2142 delattr(self.unfiltered(), r'dirstate')
2143
2143
2144 def invalidate(self, clearfilecache=False):
2144 def invalidate(self, clearfilecache=False):
2145 '''Invalidates both store and non-store parts other than dirstate
2145 '''Invalidates both store and non-store parts other than dirstate
2146
2146
2147 If a transaction is running, invalidation of store is omitted,
2147 If a transaction is running, invalidation of store is omitted,
2148 because discarding in-memory changes might cause inconsistency
2148 because discarding in-memory changes might cause inconsistency
2149 (e.g. incomplete fncache causes unintentional failure, but
2149 (e.g. incomplete fncache causes unintentional failure, but
2150 redundant one doesn't).
2150 redundant one doesn't).
2151 '''
2151 '''
2152 unfiltered = self.unfiltered() # all file caches are stored unfiltered
2152 unfiltered = self.unfiltered() # all file caches are stored unfiltered
2153 for k in list(self._filecache.keys()):
2153 for k in list(self._filecache.keys()):
2154 # dirstate is invalidated separately in invalidatedirstate()
2154 # dirstate is invalidated separately in invalidatedirstate()
2155 if k == 'dirstate':
2155 if k == 'dirstate':
2156 continue
2156 continue
2157 if (k == 'changelog' and
2157 if (k == 'changelog' and
2158 self.currenttransaction() and
2158 self.currenttransaction() and
2159 self.changelog._delayed):
2159 self.changelog._delayed):
2160 # The changelog object may store unwritten revisions. We don't
2160 # The changelog object may store unwritten revisions. We don't
2161 # want to lose them.
2161 # want to lose them.
2162 # TODO: Solve the problem instead of working around it.
2162 # TODO: Solve the problem instead of working around it.
2163 continue
2163 continue
2164
2164
2165 if clearfilecache:
2165 if clearfilecache:
2166 del self._filecache[k]
2166 del self._filecache[k]
2167 try:
2167 try:
2168 delattr(unfiltered, k)
2168 delattr(unfiltered, k)
2169 except AttributeError:
2169 except AttributeError:
2170 pass
2170 pass
2171 self.invalidatecaches()
2171 self.invalidatecaches()
2172 if not self.currenttransaction():
2172 if not self.currenttransaction():
2173 # TODO: Changing contents of store outside transaction
2173 # TODO: Changing contents of store outside transaction
2174 # causes inconsistency. We should make in-memory store
2174 # causes inconsistency. We should make in-memory store
2175 # changes detectable, and abort if changed.
2175 # changes detectable, and abort if changed.
2176 self.store.invalidatecaches()
2176 self.store.invalidatecaches()
2177
2177
2178 def invalidateall(self):
2178 def invalidateall(self):
2179 '''Fully invalidates both store and non-store parts, causing the
2179 '''Fully invalidates both store and non-store parts, causing the
2180 subsequent operation to reread any outside changes.'''
2180 subsequent operation to reread any outside changes.'''
2181 # extension should hook this to invalidate its caches
2181 # extension should hook this to invalidate its caches
2182 self.invalidate()
2182 self.invalidate()
2183 self.invalidatedirstate()
2183 self.invalidatedirstate()
2184
2184
2185 @unfilteredmethod
2185 @unfilteredmethod
2186 def _refreshfilecachestats(self, tr):
2186 def _refreshfilecachestats(self, tr):
2187 """Reload stats of cached files so that they are flagged as valid"""
2187 """Reload stats of cached files so that they are flagged as valid"""
2188 for k, ce in self._filecache.items():
2188 for k, ce in self._filecache.items():
2189 k = pycompat.sysstr(k)
2189 k = pycompat.sysstr(k)
2190 if k == r'dirstate' or k not in self.__dict__:
2190 if k == r'dirstate' or k not in self.__dict__:
2191 continue
2191 continue
2192 ce.refresh()
2192 ce.refresh()
2193
2193
2194 def _lock(self, vfs, lockname, wait, releasefn, acquirefn, desc,
2194 def _lock(self, vfs, lockname, wait, releasefn, acquirefn, desc,
2195 inheritchecker=None, parentenvvar=None):
2195 inheritchecker=None, parentenvvar=None):
2196 parentlock = None
2196 parentlock = None
2197 # the contents of parentenvvar are used by the underlying lock to
2197 # the contents of parentenvvar are used by the underlying lock to
2198 # determine whether it can be inherited
2198 # determine whether it can be inherited
2199 if parentenvvar is not None:
2199 if parentenvvar is not None:
2200 parentlock = encoding.environ.get(parentenvvar)
2200 parentlock = encoding.environ.get(parentenvvar)
2201
2201
2202 timeout = 0
2202 timeout = 0
2203 warntimeout = 0
2203 warntimeout = 0
2204 if wait:
2204 if wait:
2205 timeout = self.ui.configint("ui", "timeout")
2205 timeout = self.ui.configint("ui", "timeout")
2206 warntimeout = self.ui.configint("ui", "timeout.warn")
2206 warntimeout = self.ui.configint("ui", "timeout.warn")
2207 # internal config: ui.signal-safe-lock
2207 # internal config: ui.signal-safe-lock
2208 signalsafe = self.ui.configbool('ui', 'signal-safe-lock')
2208 signalsafe = self.ui.configbool('ui', 'signal-safe-lock')
2209
2209
2210 l = lockmod.trylock(self.ui, vfs, lockname, timeout, warntimeout,
2210 l = lockmod.trylock(self.ui, vfs, lockname, timeout, warntimeout,
2211 releasefn=releasefn,
2211 releasefn=releasefn,
2212 acquirefn=acquirefn, desc=desc,
2212 acquirefn=acquirefn, desc=desc,
2213 inheritchecker=inheritchecker,
2213 inheritchecker=inheritchecker,
2214 parentlock=parentlock,
2214 parentlock=parentlock,
2215 signalsafe=signalsafe)
2215 signalsafe=signalsafe)
2216 return l
2216 return l
2217
2217
2218 def _afterlock(self, callback):
2218 def _afterlock(self, callback):
2219 """add a callback to be run when the repository is fully unlocked
2219 """add a callback to be run when the repository is fully unlocked
2220
2220
2221 The callback will be executed when the outermost lock is released
2221 The callback will be executed when the outermost lock is released
2222 (with wlock being higher level than 'lock')."""
2222 (with wlock being higher level than 'lock')."""
2223 for ref in (self._wlockref, self._lockref):
2223 for ref in (self._wlockref, self._lockref):
2224 l = ref and ref()
2224 l = ref and ref()
2225 if l and l.held:
2225 if l and l.held:
2226 l.postrelease.append(callback)
2226 l.postrelease.append(callback)
2227 break
2227 break
2228 else: # no lock have been found.
2228 else: # no lock have been found.
2229 callback()
2229 callback()
2230
2230
2231 def lock(self, wait=True):
2231 def lock(self, wait=True):
2232 '''Lock the repository store (.hg/store) and return a weak reference
2232 '''Lock the repository store (.hg/store) and return a weak reference
2233 to the lock. Use this before modifying the store (e.g. committing or
2233 to the lock. Use this before modifying the store (e.g. committing or
2234 stripping). If you are opening a transaction, get a lock as well.)
2234 stripping). If you are opening a transaction, get a lock as well.)
2235
2235
2236 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2236 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2237 'wlock' first to avoid a dead-lock hazard.'''
2237 'wlock' first to avoid a dead-lock hazard.'''
2238 l = self._currentlock(self._lockref)
2238 l = self._currentlock(self._lockref)
2239 if l is not None:
2239 if l is not None:
2240 l.lock()
2240 l.lock()
2241 return l
2241 return l
2242
2242
2243 l = self._lock(vfs=self.svfs,
2243 l = self._lock(vfs=self.svfs,
2244 lockname="lock",
2244 lockname="lock",
2245 wait=wait,
2245 wait=wait,
2246 releasefn=None,
2246 releasefn=None,
2247 acquirefn=self.invalidate,
2247 acquirefn=self.invalidate,
2248 desc=_('repository %s') % self.origroot)
2248 desc=_('repository %s') % self.origroot)
2249 self._lockref = weakref.ref(l)
2249 self._lockref = weakref.ref(l)
2250 return l
2250 return l
2251
2251
2252 def _wlockchecktransaction(self):
2252 def _wlockchecktransaction(self):
2253 if self.currenttransaction() is not None:
2253 if self.currenttransaction() is not None:
2254 raise error.LockInheritanceContractViolation(
2254 raise error.LockInheritanceContractViolation(
2255 'wlock cannot be inherited in the middle of a transaction')
2255 'wlock cannot be inherited in the middle of a transaction')
2256
2256
2257 def wlock(self, wait=True):
2257 def wlock(self, wait=True):
2258 '''Lock the non-store parts of the repository (everything under
2258 '''Lock the non-store parts of the repository (everything under
2259 .hg except .hg/store) and return a weak reference to the lock.
2259 .hg except .hg/store) and return a weak reference to the lock.
2260
2260
2261 Use this before modifying files in .hg.
2261 Use this before modifying files in .hg.
2262
2262
2263 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2263 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2264 'wlock' first to avoid a dead-lock hazard.'''
2264 'wlock' first to avoid a dead-lock hazard.'''
2265 l = self._wlockref and self._wlockref()
2265 l = self._wlockref and self._wlockref()
2266 if l is not None and l.held:
2266 if l is not None and l.held:
2267 l.lock()
2267 l.lock()
2268 return l
2268 return l
2269
2269
2270 # We do not need to check for non-waiting lock acquisition. Such
2270 # We do not need to check for non-waiting lock acquisition. Such
2271 # acquisition would not cause dead-lock as they would just fail.
2271 # acquisition would not cause dead-lock as they would just fail.
2272 if wait and (self.ui.configbool('devel', 'all-warnings')
2272 if wait and (self.ui.configbool('devel', 'all-warnings')
2273 or self.ui.configbool('devel', 'check-locks')):
2273 or self.ui.configbool('devel', 'check-locks')):
2274 if self._currentlock(self._lockref) is not None:
2274 if self._currentlock(self._lockref) is not None:
2275 self.ui.develwarn('"wlock" acquired after "lock"')
2275 self.ui.develwarn('"wlock" acquired after "lock"')
2276
2276
2277 def unlock():
2277 def unlock():
2278 if self.dirstate.pendingparentchange():
2278 if self.dirstate.pendingparentchange():
2279 self.dirstate.invalidate()
2279 self.dirstate.invalidate()
2280 else:
2280 else:
2281 self.dirstate.write(None)
2281 self.dirstate.write(None)
2282
2282
2283 self._filecache['dirstate'].refresh()
2283 self._filecache['dirstate'].refresh()
2284
2284
2285 l = self._lock(self.vfs, "wlock", wait, unlock,
2285 l = self._lock(self.vfs, "wlock", wait, unlock,
2286 self.invalidatedirstate, _('working directory of %s') %
2286 self.invalidatedirstate, _('working directory of %s') %
2287 self.origroot,
2287 self.origroot,
2288 inheritchecker=self._wlockchecktransaction,
2288 inheritchecker=self._wlockchecktransaction,
2289 parentenvvar='HG_WLOCK_LOCKER')
2289 parentenvvar='HG_WLOCK_LOCKER')
2290 self._wlockref = weakref.ref(l)
2290 self._wlockref = weakref.ref(l)
2291 return l
2291 return l
2292
2292
2293 def _currentlock(self, lockref):
2293 def _currentlock(self, lockref):
2294 """Returns the lock if it's held, or None if it's not."""
2294 """Returns the lock if it's held, or None if it's not."""
2295 if lockref is None:
2295 if lockref is None:
2296 return None
2296 return None
2297 l = lockref()
2297 l = lockref()
2298 if l is None or not l.held:
2298 if l is None or not l.held:
2299 return None
2299 return None
2300 return l
2300 return l
2301
2301
2302 def currentwlock(self):
2302 def currentwlock(self):
2303 """Returns the wlock if it's held, or None if it's not."""
2303 """Returns the wlock if it's held, or None if it's not."""
2304 return self._currentlock(self._wlockref)
2304 return self._currentlock(self._wlockref)
2305
2305
2306 def _filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist):
2306 def _filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist):
2307 """
2307 """
2308 commit an individual file as part of a larger transaction
2308 commit an individual file as part of a larger transaction
2309 """
2309 """
2310
2310
2311 fname = fctx.path()
2311 fname = fctx.path()
2312 fparent1 = manifest1.get(fname, nullid)
2312 fparent1 = manifest1.get(fname, nullid)
2313 fparent2 = manifest2.get(fname, nullid)
2313 fparent2 = manifest2.get(fname, nullid)
2314 if isinstance(fctx, context.filectx):
2314 if isinstance(fctx, context.filectx):
2315 node = fctx.filenode()
2315 node = fctx.filenode()
2316 if node in [fparent1, fparent2]:
2316 if node in [fparent1, fparent2]:
2317 self.ui.debug('reusing %s filelog entry\n' % fname)
2317 self.ui.debug('reusing %s filelog entry\n' % fname)
2318 if manifest1.flags(fname) != fctx.flags():
2318 if manifest1.flags(fname) != fctx.flags():
2319 changelist.append(fname)
2319 changelist.append(fname)
2320 return node
2320 return node
2321
2321
2322 flog = self.file(fname)
2322 flog = self.file(fname)
2323 meta = {}
2323 meta = {}
2324 cfname = fctx.copysource()
2324 cfname = fctx.copysource()
2325 if cfname and cfname != fname:
2325 if cfname and cfname != fname:
2326 # Mark the new revision of this file as a copy of another
2326 # Mark the new revision of this file as a copy of another
2327 # file. This copy data will effectively act as a parent
2327 # file. This copy data will effectively act as a parent
2328 # of this new revision. If this is a merge, the first
2328 # of this new revision. If this is a merge, the first
2329 # parent will be the nullid (meaning "look up the copy data")
2329 # parent will be the nullid (meaning "look up the copy data")
2330 # and the second one will be the other parent. For example:
2330 # and the second one will be the other parent. For example:
2331 #
2331 #
2332 # 0 --- 1 --- 3 rev1 changes file foo
2332 # 0 --- 1 --- 3 rev1 changes file foo
2333 # \ / rev2 renames foo to bar and changes it
2333 # \ / rev2 renames foo to bar and changes it
2334 # \- 2 -/ rev3 should have bar with all changes and
2334 # \- 2 -/ rev3 should have bar with all changes and
2335 # should record that bar descends from
2335 # should record that bar descends from
2336 # bar in rev2 and foo in rev1
2336 # bar in rev2 and foo in rev1
2337 #
2337 #
2338 # this allows this merge to succeed:
2338 # this allows this merge to succeed:
2339 #
2339 #
2340 # 0 --- 1 --- 3 rev4 reverts the content change from rev2
2340 # 0 --- 1 --- 3 rev4 reverts the content change from rev2
2341 # \ / merging rev3 and rev4 should use bar@rev2
2341 # \ / merging rev3 and rev4 should use bar@rev2
2342 # \- 2 --- 4 as the merge base
2342 # \- 2 --- 4 as the merge base
2343 #
2343 #
2344
2344
2345 crev = manifest1.get(cfname)
2345 crev = manifest1.get(cfname)
2346 newfparent = fparent2
2346 newfparent = fparent2
2347
2347
2348 if manifest2: # branch merge
2348 if manifest2: # branch merge
2349 if fparent2 == nullid or crev is None: # copied on remote side
2349 if fparent2 == nullid or crev is None: # copied on remote side
2350 if cfname in manifest2:
2350 if cfname in manifest2:
2351 crev = manifest2[cfname]
2351 crev = manifest2[cfname]
2352 newfparent = fparent1
2352 newfparent = fparent1
2353
2353
2354 # Here, we used to search backwards through history to try to find
2354 # Here, we used to search backwards through history to try to find
2355 # where the file copy came from if the source of a copy was not in
2355 # where the file copy came from if the source of a copy was not in
2356 # the parent directory. However, this doesn't actually make sense to
2356 # the parent directory. However, this doesn't actually make sense to
2357 # do (what does a copy from something not in your working copy even
2357 # do (what does a copy from something not in your working copy even
2358 # mean?) and it causes bugs (eg, issue4476). Instead, we will warn
2358 # mean?) and it causes bugs (eg, issue4476). Instead, we will warn
2359 # the user that copy information was dropped, so if they didn't
2359 # the user that copy information was dropped, so if they didn't
2360 # expect this outcome it can be fixed, but this is the correct
2360 # expect this outcome it can be fixed, but this is the correct
2361 # behavior in this circumstance.
2361 # behavior in this circumstance.
2362
2362
2363 if crev:
2363 if crev:
2364 self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(crev)))
2364 self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(crev)))
2365 meta["copy"] = cfname
2365 meta["copy"] = cfname
2366 meta["copyrev"] = hex(crev)
2366 meta["copyrev"] = hex(crev)
2367 fparent1, fparent2 = nullid, newfparent
2367 fparent1, fparent2 = nullid, newfparent
2368 else:
2368 else:
2369 self.ui.warn(_("warning: can't find ancestor for '%s' "
2369 self.ui.warn(_("warning: can't find ancestor for '%s' "
2370 "copied from '%s'!\n") % (fname, cfname))
2370 "copied from '%s'!\n") % (fname, cfname))
2371
2371
2372 elif fparent1 == nullid:
2372 elif fparent1 == nullid:
2373 fparent1, fparent2 = fparent2, nullid
2373 fparent1, fparent2 = fparent2, nullid
2374 elif fparent2 != nullid:
2374 elif fparent2 != nullid:
2375 # is one parent an ancestor of the other?
2375 # is one parent an ancestor of the other?
2376 fparentancestors = flog.commonancestorsheads(fparent1, fparent2)
2376 fparentancestors = flog.commonancestorsheads(fparent1, fparent2)
2377 if fparent1 in fparentancestors:
2377 if fparent1 in fparentancestors:
2378 fparent1, fparent2 = fparent2, nullid
2378 fparent1, fparent2 = fparent2, nullid
2379 elif fparent2 in fparentancestors:
2379 elif fparent2 in fparentancestors:
2380 fparent2 = nullid
2380 fparent2 = nullid
2381
2381
2382 # is the file changed?
2382 # is the file changed?
2383 text = fctx.data()
2383 text = fctx.data()
2384 if fparent2 != nullid or flog.cmp(fparent1, text) or meta:
2384 if fparent2 != nullid or flog.cmp(fparent1, text) or meta:
2385 changelist.append(fname)
2385 changelist.append(fname)
2386 return flog.add(text, meta, tr, linkrev, fparent1, fparent2)
2386 return flog.add(text, meta, tr, linkrev, fparent1, fparent2)
2387 # are just the flags changed during merge?
2387 # are just the flags changed during merge?
2388 elif fname in manifest1 and manifest1.flags(fname) != fctx.flags():
2388 elif fname in manifest1 and manifest1.flags(fname) != fctx.flags():
2389 changelist.append(fname)
2389 changelist.append(fname)
2390
2390
2391 return fparent1
2391 return fparent1
2392
2392
2393 def checkcommitpatterns(self, wctx, vdirs, match, status, fail):
2393 def checkcommitpatterns(self, wctx, vdirs, match, status, fail):
2394 """check for commit arguments that aren't committable"""
2394 """check for commit arguments that aren't committable"""
2395 if match.isexact() or match.prefix():
2395 if match.isexact() or match.prefix():
2396 matched = set(status.modified + status.added + status.removed)
2396 matched = set(status.modified + status.added + status.removed)
2397
2397
2398 for f in match.files():
2398 for f in match.files():
2399 f = self.dirstate.normalize(f)
2399 f = self.dirstate.normalize(f)
2400 if f == '.' or f in matched or f in wctx.substate:
2400 if f == '.' or f in matched or f in wctx.substate:
2401 continue
2401 continue
2402 if f in status.deleted:
2402 if f in status.deleted:
2403 fail(f, _('file not found!'))
2403 fail(f, _('file not found!'))
2404 if f in vdirs: # visited directory
2404 if f in vdirs: # visited directory
2405 d = f + '/'
2405 d = f + '/'
2406 for mf in matched:
2406 for mf in matched:
2407 if mf.startswith(d):
2407 if mf.startswith(d):
2408 break
2408 break
2409 else:
2409 else:
2410 fail(f, _("no match under directory!"))
2410 fail(f, _("no match under directory!"))
2411 elif f not in self.dirstate:
2411 elif f not in self.dirstate:
2412 fail(f, _("file not tracked!"))
2412 fail(f, _("file not tracked!"))
2413
2413
2414 @unfilteredmethod
2414 @unfilteredmethod
2415 def commit(self, text="", user=None, date=None, match=None, force=False,
2415 def commit(self, text="", user=None, date=None, match=None, force=False,
2416 editor=False, extra=None):
2416 editor=False, extra=None):
2417 """Add a new revision to current repository.
2417 """Add a new revision to current repository.
2418
2418
2419 Revision information is gathered from the working directory,
2419 Revision information is gathered from the working directory,
2420 match can be used to filter the committed files. If editor is
2420 match can be used to filter the committed files. If editor is
2421 supplied, it is called to get a commit message.
2421 supplied, it is called to get a commit message.
2422 """
2422 """
2423 if extra is None:
2423 if extra is None:
2424 extra = {}
2424 extra = {}
2425
2425
2426 def fail(f, msg):
2426 def fail(f, msg):
2427 raise error.Abort('%s: %s' % (f, msg))
2427 raise error.Abort('%s: %s' % (f, msg))
2428
2428
2429 if not match:
2429 if not match:
2430 match = matchmod.always()
2430 match = matchmod.always()
2431
2431
2432 if not force:
2432 if not force:
2433 vdirs = []
2433 vdirs = []
2434 match.explicitdir = vdirs.append
2434 match.explicitdir = vdirs.append
2435 match.bad = fail
2435 match.bad = fail
2436
2436
2437 # lock() for recent changelog (see issue4368)
2437 # lock() for recent changelog (see issue4368)
2438 with self.wlock(), self.lock():
2438 with self.wlock(), self.lock():
2439 wctx = self[None]
2439 wctx = self[None]
2440 merge = len(wctx.parents()) > 1
2440 merge = len(wctx.parents()) > 1
2441
2441
2442 if not force and merge and not match.always():
2442 if not force and merge and not match.always():
2443 raise error.Abort(_('cannot partially commit a merge '
2443 raise error.Abort(_('cannot partially commit a merge '
2444 '(do not specify files or patterns)'))
2444 '(do not specify files or patterns)'))
2445
2445
2446 status = self.status(match=match, clean=force)
2446 status = self.status(match=match, clean=force)
2447 if force:
2447 if force:
2448 status.modified.extend(status.clean) # mq may commit clean files
2448 status.modified.extend(status.clean) # mq may commit clean files
2449
2449
2450 # check subrepos
2450 # check subrepos
2451 subs, commitsubs, newstate = subrepoutil.precommit(
2451 subs, commitsubs, newstate = subrepoutil.precommit(
2452 self.ui, wctx, status, match, force=force)
2452 self.ui, wctx, status, match, force=force)
2453
2453
2454 # make sure all explicit patterns are matched
2454 # make sure all explicit patterns are matched
2455 if not force:
2455 if not force:
2456 self.checkcommitpatterns(wctx, vdirs, match, status, fail)
2456 self.checkcommitpatterns(wctx, vdirs, match, status, fail)
2457
2457
2458 cctx = context.workingcommitctx(self, status,
2458 cctx = context.workingcommitctx(self, status,
2459 text, user, date, extra)
2459 text, user, date, extra)
2460
2460
2461 # internal config: ui.allowemptycommit
2461 # internal config: ui.allowemptycommit
2462 allowemptycommit = (wctx.branch() != wctx.p1().branch()
2462 allowemptycommit = (wctx.branch() != wctx.p1().branch()
2463 or extra.get('close') or merge or cctx.files()
2463 or extra.get('close') or merge or cctx.files()
2464 or self.ui.configbool('ui', 'allowemptycommit'))
2464 or self.ui.configbool('ui', 'allowemptycommit'))
2465 if not allowemptycommit:
2465 if not allowemptycommit:
2466 return None
2466 return None
2467
2467
2468 if merge and cctx.deleted():
2468 if merge and cctx.deleted():
2469 raise error.Abort(_("cannot commit merge with missing files"))
2469 raise error.Abort(_("cannot commit merge with missing files"))
2470
2470
2471 ms = mergemod.mergestate.read(self)
2471 ms = mergemod.mergestate.read(self)
2472 mergeutil.checkunresolved(ms)
2472 mergeutil.checkunresolved(ms)
2473
2473
2474 if editor:
2474 if editor:
2475 cctx._text = editor(self, cctx, subs)
2475 cctx._text = editor(self, cctx, subs)
2476 edited = (text != cctx._text)
2476 edited = (text != cctx._text)
2477
2477
2478 # Save commit message in case this transaction gets rolled back
2478 # Save commit message in case this transaction gets rolled back
2479 # (e.g. by a pretxncommit hook). Leave the content alone on
2479 # (e.g. by a pretxncommit hook). Leave the content alone on
2480 # the assumption that the user will use the same editor again.
2480 # the assumption that the user will use the same editor again.
2481 msgfn = self.savecommitmessage(cctx._text)
2481 msgfn = self.savecommitmessage(cctx._text)
2482
2482
2483 # commit subs and write new state
2483 # commit subs and write new state
2484 if subs:
2484 if subs:
2485 uipathfn = scmutil.getuipathfn(self)
2485 uipathfn = scmutil.getuipathfn(self)
2486 for s in sorted(commitsubs):
2486 for s in sorted(commitsubs):
2487 sub = wctx.sub(s)
2487 sub = wctx.sub(s)
2488 self.ui.status(_('committing subrepository %s\n') %
2488 self.ui.status(_('committing subrepository %s\n') %
2489 uipathfn(subrepoutil.subrelpath(sub)))
2489 uipathfn(subrepoutil.subrelpath(sub)))
2490 sr = sub.commit(cctx._text, user, date)
2490 sr = sub.commit(cctx._text, user, date)
2491 newstate[s] = (newstate[s][0], sr)
2491 newstate[s] = (newstate[s][0], sr)
2492 subrepoutil.writestate(self, newstate)
2492 subrepoutil.writestate(self, newstate)
2493
2493
2494 p1, p2 = self.dirstate.parents()
2494 p1, p2 = self.dirstate.parents()
2495 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
2495 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
2496 try:
2496 try:
2497 self.hook("precommit", throw=True, parent1=hookp1,
2497 self.hook("precommit", throw=True, parent1=hookp1,
2498 parent2=hookp2)
2498 parent2=hookp2)
2499 with self.transaction('commit'):
2499 with self.transaction('commit'):
2500 ret = self.commitctx(cctx, True)
2500 ret = self.commitctx(cctx, True)
2501 # update bookmarks, dirstate and mergestate
2501 # update bookmarks, dirstate and mergestate
2502 bookmarks.update(self, [p1, p2], ret)
2502 bookmarks.update(self, [p1, p2], ret)
2503 cctx.markcommitted(ret)
2503 cctx.markcommitted(ret)
2504 ms.reset()
2504 ms.reset()
2505 except: # re-raises
2505 except: # re-raises
2506 if edited:
2506 if edited:
2507 self.ui.write(
2507 self.ui.write(
2508 _('note: commit message saved in %s\n') % msgfn)
2508 _('note: commit message saved in %s\n') % msgfn)
2509 raise
2509 raise
2510
2510
2511 def commithook(node=hex(ret), parent1=hookp1, parent2=hookp2):
2511 def commithook(node=hex(ret), parent1=hookp1, parent2=hookp2):
2512 # hack for command that use a temporary commit (eg: histedit)
2512 # hack for command that use a temporary commit (eg: histedit)
2513 # temporary commit got stripped before hook release
2513 # temporary commit got stripped before hook release
2514 if self.changelog.hasnode(ret):
2514 if self.changelog.hasnode(ret):
2515 self.hook("commit", node=node, parent1=parent1,
2515 self.hook("commit", node=node, parent1=parent1,
2516 parent2=parent2)
2516 parent2=parent2)
2517 self._afterlock(commithook)
2517 self._afterlock(commithook)
2518 return ret
2518 return ret
2519
2519
2520 @unfilteredmethod
2520 @unfilteredmethod
2521 def commitctx(self, ctx, error=False):
2521 def commitctx(self, ctx, error=False):
2522 """Add a new revision to current repository.
2522 """Add a new revision to current repository.
2523 Revision information is passed via the context argument.
2523 Revision information is passed via the context argument.
2524
2524
2525 ctx.files() should list all files involved in this commit, i.e.
2525 ctx.files() should list all files involved in this commit, i.e.
2526 modified/added/removed files. On merge, it may be wider than the
2526 modified/added/removed files. On merge, it may be wider than the
2527 ctx.files() to be committed, since any file nodes derived directly
2527 ctx.files() to be committed, since any file nodes derived directly
2528 from p1 or p2 are excluded from the committed ctx.files().
2528 from p1 or p2 are excluded from the committed ctx.files().
2529 """
2529 """
2530
2530
2531 p1, p2 = ctx.p1(), ctx.p2()
2531 p1, p2 = ctx.p1(), ctx.p2()
2532 user = ctx.user()
2532 user = ctx.user()
2533
2533
2534 with self.lock(), self.transaction("commit") as tr:
2534 with self.lock(), self.transaction("commit") as tr:
2535 trp = weakref.proxy(tr)
2535 trp = weakref.proxy(tr)
2536
2536
2537 if ctx.manifestnode():
2537 if ctx.manifestnode():
2538 # reuse an existing manifest revision
2538 # reuse an existing manifest revision
2539 self.ui.debug('reusing known manifest\n')
2539 self.ui.debug('reusing known manifest\n')
2540 mn = ctx.manifestnode()
2540 mn = ctx.manifestnode()
2541 files = ctx.files()
2541 files = ctx.files()
2542 elif ctx.files():
2542 elif ctx.files():
2543 m1ctx = p1.manifestctx()
2543 m1ctx = p1.manifestctx()
2544 m2ctx = p2.manifestctx()
2544 m2ctx = p2.manifestctx()
2545 mctx = m1ctx.copy()
2545 mctx = m1ctx.copy()
2546
2546
2547 m = mctx.read()
2547 m = mctx.read()
2548 m1 = m1ctx.read()
2548 m1 = m1ctx.read()
2549 m2 = m2ctx.read()
2549 m2 = m2ctx.read()
2550
2550
2551 # check in files
2551 # check in files
2552 added = []
2552 added = []
2553 changed = []
2553 changed = []
2554 removed = list(ctx.removed())
2554 removed = list(ctx.removed())
2555 linkrev = len(self)
2555 linkrev = len(self)
2556 self.ui.note(_("committing files:\n"))
2556 self.ui.note(_("committing files:\n"))
2557 uipathfn = scmutil.getuipathfn(self)
2557 uipathfn = scmutil.getuipathfn(self)
2558 for f in sorted(ctx.modified() + ctx.added()):
2558 for f in sorted(ctx.modified() + ctx.added()):
2559 self.ui.note(uipathfn(f) + "\n")
2559 self.ui.note(uipathfn(f) + "\n")
2560 try:
2560 try:
2561 fctx = ctx[f]
2561 fctx = ctx[f]
2562 if fctx is None:
2562 if fctx is None:
2563 removed.append(f)
2563 removed.append(f)
2564 else:
2564 else:
2565 added.append(f)
2565 added.append(f)
2566 m[f] = self._filecommit(fctx, m1, m2, linkrev,
2566 m[f] = self._filecommit(fctx, m1, m2, linkrev,
2567 trp, changed)
2567 trp, changed)
2568 m.setflag(f, fctx.flags())
2568 m.setflag(f, fctx.flags())
2569 except OSError:
2569 except OSError:
2570 self.ui.warn(_("trouble committing %s!\n") %
2570 self.ui.warn(_("trouble committing %s!\n") %
2571 uipathfn(f))
2571 uipathfn(f))
2572 raise
2572 raise
2573 except IOError as inst:
2573 except IOError as inst:
2574 errcode = getattr(inst, 'errno', errno.ENOENT)
2574 errcode = getattr(inst, 'errno', errno.ENOENT)
2575 if error or errcode and errcode != errno.ENOENT:
2575 if error or errcode and errcode != errno.ENOENT:
2576 self.ui.warn(_("trouble committing %s!\n") %
2576 self.ui.warn(_("trouble committing %s!\n") %
2577 uipathfn(f))
2577 uipathfn(f))
2578 raise
2578 raise
2579
2579
2580 # update manifest
2580 # update manifest
2581 removed = [f for f in sorted(removed) if f in m1 or f in m2]
2581 removed = [f for f in sorted(removed) if f in m1 or f in m2]
2582 drop = [f for f in removed if f in m]
2582 drop = [f for f in removed if f in m]
2583 for f in drop:
2583 for f in drop:
2584 del m[f]
2584 del m[f]
2585 files = changed + removed
2585 files = changed + removed
2586 md = None
2586 md = None
2587 if not files:
2587 if not files:
2588 # if no "files" actually changed in terms of the changelog,
2588 # if no "files" actually changed in terms of the changelog,
2589 # try hard to detect unmodified manifest entry so that the
2589 # try hard to detect unmodified manifest entry so that the
2590 # exact same commit can be reproduced later on convert.
2590 # exact same commit can be reproduced later on convert.
2591 md = m1.diff(m, scmutil.matchfiles(self, ctx.files()))
2591 md = m1.diff(m, scmutil.matchfiles(self, ctx.files()))
2592 if not files and md:
2592 if not files and md:
2593 self.ui.debug('not reusing manifest (no file change in '
2593 self.ui.debug('not reusing manifest (no file change in '
2594 'changelog, but manifest differs)\n')
2594 'changelog, but manifest differs)\n')
2595 if files or md:
2595 if files or md:
2596 self.ui.note(_("committing manifest\n"))
2596 self.ui.note(_("committing manifest\n"))
2597 # we're using narrowmatch here since it's already applied at
2597 # we're using narrowmatch here since it's already applied at
2598 # other stages (such as dirstate.walk), so we're already
2598 # other stages (such as dirstate.walk), so we're already
2599 # ignoring things outside of narrowspec in most cases. The
2599 # ignoring things outside of narrowspec in most cases. The
2600 # one case where we might have files outside the narrowspec
2600 # one case where we might have files outside the narrowspec
2601 # at this point is merges, and we already error out in the
2601 # at this point is merges, and we already error out in the
2602 # case where the merge has files outside of the narrowspec,
2602 # case where the merge has files outside of the narrowspec,
2603 # so this is safe.
2603 # so this is safe.
2604 mn = mctx.write(trp, linkrev,
2604 mn = mctx.write(trp, linkrev,
2605 p1.manifestnode(), p2.manifestnode(),
2605 p1.manifestnode(), p2.manifestnode(),
2606 added, drop, match=self.narrowmatch())
2606 added, drop, match=self.narrowmatch())
2607 else:
2607 else:
2608 self.ui.debug('reusing manifest form p1 (listed files '
2608 self.ui.debug('reusing manifest form p1 (listed files '
2609 'actually unchanged)\n')
2609 'actually unchanged)\n')
2610 mn = p1.manifestnode()
2610 mn = p1.manifestnode()
2611 else:
2611 else:
2612 self.ui.debug('reusing manifest from p1 (no file change)\n')
2612 self.ui.debug('reusing manifest from p1 (no file change)\n')
2613 mn = p1.manifestnode()
2613 mn = p1.manifestnode()
2614 files = []
2614 files = []
2615
2615
2616 # update changelog
2616 # update changelog
2617 self.ui.note(_("committing changelog\n"))
2617 self.ui.note(_("committing changelog\n"))
2618 self.changelog.delayupdate(tr)
2618 self.changelog.delayupdate(tr)
2619 n = self.changelog.add(mn, files, ctx.description(),
2619 n = self.changelog.add(mn, files, ctx.description(),
2620 trp, p1.node(), p2.node(),
2620 trp, p1.node(), p2.node(),
2621 user, ctx.date(), ctx.extra().copy())
2621 user, ctx.date(), ctx.extra().copy())
2622 xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
2622 xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
2623 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
2623 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
2624 parent2=xp2)
2624 parent2=xp2)
2625 # set the new commit is proper phase
2625 # set the new commit is proper phase
2626 targetphase = subrepoutil.newcommitphase(self.ui, ctx)
2626 targetphase = subrepoutil.newcommitphase(self.ui, ctx)
2627 if targetphase:
2627 if targetphase:
2628 # retract boundary do not alter parent changeset.
2628 # retract boundary do not alter parent changeset.
2629 # if a parent have higher the resulting phase will
2629 # if a parent have higher the resulting phase will
2630 # be compliant anyway
2630 # be compliant anyway
2631 #
2631 #
2632 # if minimal phase was 0 we don't need to retract anything
2632 # if minimal phase was 0 we don't need to retract anything
2633 phases.registernew(self, tr, targetphase, [n])
2633 phases.registernew(self, tr, targetphase, [n])
2634 return n
2634 return n
2635
2635
2636 @unfilteredmethod
2636 @unfilteredmethod
2637 def destroying(self):
2637 def destroying(self):
2638 '''Inform the repository that nodes are about to be destroyed.
2638 '''Inform the repository that nodes are about to be destroyed.
2639 Intended for use by strip and rollback, so there's a common
2639 Intended for use by strip and rollback, so there's a common
2640 place for anything that has to be done before destroying history.
2640 place for anything that has to be done before destroying history.
2641
2641
2642 This is mostly useful for saving state that is in memory and waiting
2642 This is mostly useful for saving state that is in memory and waiting
2643 to be flushed when the current lock is released. Because a call to
2643 to be flushed when the current lock is released. Because a call to
2644 destroyed is imminent, the repo will be invalidated causing those
2644 destroyed is imminent, the repo will be invalidated causing those
2645 changes to stay in memory (waiting for the next unlock), or vanish
2645 changes to stay in memory (waiting for the next unlock), or vanish
2646 completely.
2646 completely.
2647 '''
2647 '''
2648 # When using the same lock to commit and strip, the phasecache is left
2648 # When using the same lock to commit and strip, the phasecache is left
2649 # dirty after committing. Then when we strip, the repo is invalidated,
2649 # dirty after committing. Then when we strip, the repo is invalidated,
2650 # causing those changes to disappear.
2650 # causing those changes to disappear.
2651 if '_phasecache' in vars(self):
2651 if '_phasecache' in vars(self):
2652 self._phasecache.write()
2652 self._phasecache.write()
2653
2653
2654 @unfilteredmethod
2654 @unfilteredmethod
2655 def destroyed(self):
2655 def destroyed(self):
2656 '''Inform the repository that nodes have been destroyed.
2656 '''Inform the repository that nodes have been destroyed.
2657 Intended for use by strip and rollback, so there's a common
2657 Intended for use by strip and rollback, so there's a common
2658 place for anything that has to be done after destroying history.
2658 place for anything that has to be done after destroying history.
2659 '''
2659 '''
2660 # When one tries to:
2660 # When one tries to:
2661 # 1) destroy nodes thus calling this method (e.g. strip)
2661 # 1) destroy nodes thus calling this method (e.g. strip)
2662 # 2) use phasecache somewhere (e.g. commit)
2662 # 2) use phasecache somewhere (e.g. commit)
2663 #
2663 #
2664 # then 2) will fail because the phasecache contains nodes that were
2664 # then 2) will fail because the phasecache contains nodes that were
2665 # removed. We can either remove phasecache from the filecache,
2665 # removed. We can either remove phasecache from the filecache,
2666 # causing it to reload next time it is accessed, or simply filter
2666 # causing it to reload next time it is accessed, or simply filter
2667 # the removed nodes now and write the updated cache.
2667 # the removed nodes now and write the updated cache.
2668 self._phasecache.filterunknown(self)
2668 self._phasecache.filterunknown(self)
2669 self._phasecache.write()
2669 self._phasecache.write()
2670
2670
2671 # refresh all repository caches
2671 # refresh all repository caches
2672 self.updatecaches()
2672 self.updatecaches()
2673
2673
2674 # Ensure the persistent tag cache is updated. Doing it now
2674 # Ensure the persistent tag cache is updated. Doing it now
2675 # means that the tag cache only has to worry about destroyed
2675 # means that the tag cache only has to worry about destroyed
2676 # heads immediately after a strip/rollback. That in turn
2676 # heads immediately after a strip/rollback. That in turn
2677 # guarantees that "cachetip == currenttip" (comparing both rev
2677 # guarantees that "cachetip == currenttip" (comparing both rev
2678 # and node) always means no nodes have been added or destroyed.
2678 # and node) always means no nodes have been added or destroyed.
2679
2679
2680 # XXX this is suboptimal when qrefresh'ing: we strip the current
2680 # XXX this is suboptimal when qrefresh'ing: we strip the current
2681 # head, refresh the tag cache, then immediately add a new head.
2681 # head, refresh the tag cache, then immediately add a new head.
2682 # But I think doing it this way is necessary for the "instant
2682 # But I think doing it this way is necessary for the "instant
2683 # tag cache retrieval" case to work.
2683 # tag cache retrieval" case to work.
2684 self.invalidate()
2684 self.invalidate()
2685
2685
2686 def status(self, node1='.', node2=None, match=None,
2686 def status(self, node1='.', node2=None, match=None,
2687 ignored=False, clean=False, unknown=False,
2687 ignored=False, clean=False, unknown=False,
2688 listsubrepos=False):
2688 listsubrepos=False):
2689 '''a convenience method that calls node1.status(node2)'''
2689 '''a convenience method that calls node1.status(node2)'''
2690 return self[node1].status(node2, match, ignored, clean, unknown,
2690 return self[node1].status(node2, match, ignored, clean, unknown,
2691 listsubrepos)
2691 listsubrepos)
2692
2692
2693 def addpostdsstatus(self, ps):
2693 def addpostdsstatus(self, ps):
2694 """Add a callback to run within the wlock, at the point at which status
2694 """Add a callback to run within the wlock, at the point at which status
2695 fixups happen.
2695 fixups happen.
2696
2696
2697 On status completion, callback(wctx, status) will be called with the
2697 On status completion, callback(wctx, status) will be called with the
2698 wlock held, unless the dirstate has changed from underneath or the wlock
2698 wlock held, unless the dirstate has changed from underneath or the wlock
2699 couldn't be grabbed.
2699 couldn't be grabbed.
2700
2700
2701 Callbacks should not capture and use a cached copy of the dirstate --
2701 Callbacks should not capture and use a cached copy of the dirstate --
2702 it might change in the meanwhile. Instead, they should access the
2702 it might change in the meanwhile. Instead, they should access the
2703 dirstate via wctx.repo().dirstate.
2703 dirstate via wctx.repo().dirstate.
2704
2704
2705 This list is emptied out after each status run -- extensions should
2705 This list is emptied out after each status run -- extensions should
2706 make sure it adds to this list each time dirstate.status is called.
2706 make sure it adds to this list each time dirstate.status is called.
2707 Extensions should also make sure they don't call this for statuses
2707 Extensions should also make sure they don't call this for statuses
2708 that don't involve the dirstate.
2708 that don't involve the dirstate.
2709 """
2709 """
2710
2710
2711 # The list is located here for uniqueness reasons -- it is actually
2711 # The list is located here for uniqueness reasons -- it is actually
2712 # managed by the workingctx, but that isn't unique per-repo.
2712 # managed by the workingctx, but that isn't unique per-repo.
2713 self._postdsstatus.append(ps)
2713 self._postdsstatus.append(ps)
2714
2714
2715 def postdsstatus(self):
2715 def postdsstatus(self):
2716 """Used by workingctx to get the list of post-dirstate-status hooks."""
2716 """Used by workingctx to get the list of post-dirstate-status hooks."""
2717 return self._postdsstatus
2717 return self._postdsstatus
2718
2718
2719 def clearpostdsstatus(self):
2719 def clearpostdsstatus(self):
2720 """Used by workingctx to clear post-dirstate-status hooks."""
2720 """Used by workingctx to clear post-dirstate-status hooks."""
2721 del self._postdsstatus[:]
2721 del self._postdsstatus[:]
2722
2722
2723 def heads(self, start=None):
2723 def heads(self, start=None):
2724 if start is None:
2724 if start is None:
2725 cl = self.changelog
2725 cl = self.changelog
2726 headrevs = reversed(cl.headrevs())
2726 headrevs = reversed(cl.headrevs())
2727 return [cl.node(rev) for rev in headrevs]
2727 return [cl.node(rev) for rev in headrevs]
2728
2728
2729 heads = self.changelog.heads(start)
2729 heads = self.changelog.heads(start)
2730 # sort the output in rev descending order
2730 # sort the output in rev descending order
2731 return sorted(heads, key=self.changelog.rev, reverse=True)
2731 return sorted(heads, key=self.changelog.rev, reverse=True)
2732
2732
2733 def branchheads(self, branch=None, start=None, closed=False):
2733 def branchheads(self, branch=None, start=None, closed=False):
2734 '''return a (possibly filtered) list of heads for the given branch
2734 '''return a (possibly filtered) list of heads for the given branch
2735
2735
2736 Heads are returned in topological order, from newest to oldest.
2736 Heads are returned in topological order, from newest to oldest.
2737 If branch is None, use the dirstate branch.
2737 If branch is None, use the dirstate branch.
2738 If start is not None, return only heads reachable from start.
2738 If start is not None, return only heads reachable from start.
2739 If closed is True, return heads that are marked as closed as well.
2739 If closed is True, return heads that are marked as closed as well.
2740 '''
2740 '''
2741 if branch is None:
2741 if branch is None:
2742 branch = self[None].branch()
2742 branch = self[None].branch()
2743 branches = self.branchmap()
2743 branches = self.branchmap()
2744 if not branches.hasbranch(branch):
2744 if not branches.hasbranch(branch):
2745 return []
2745 return []
2746 # the cache returns heads ordered lowest to highest
2746 # the cache returns heads ordered lowest to highest
2747 bheads = list(reversed(branches.branchheads(branch, closed=closed)))
2747 bheads = list(reversed(branches.branchheads(branch, closed=closed)))
2748 if start is not None:
2748 if start is not None:
2749 # filter out the heads that cannot be reached from startrev
2749 # filter out the heads that cannot be reached from startrev
2750 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
2750 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
2751 bheads = [h for h in bheads if h in fbheads]
2751 bheads = [h for h in bheads if h in fbheads]
2752 return bheads
2752 return bheads
2753
2753
2754 def branches(self, nodes):
2754 def branches(self, nodes):
2755 if not nodes:
2755 if not nodes:
2756 nodes = [self.changelog.tip()]
2756 nodes = [self.changelog.tip()]
2757 b = []
2757 b = []
2758 for n in nodes:
2758 for n in nodes:
2759 t = n
2759 t = n
2760 while True:
2760 while True:
2761 p = self.changelog.parents(n)
2761 p = self.changelog.parents(n)
2762 if p[1] != nullid or p[0] == nullid:
2762 if p[1] != nullid or p[0] == nullid:
2763 b.append((t, n, p[0], p[1]))
2763 b.append((t, n, p[0], p[1]))
2764 break
2764 break
2765 n = p[0]
2765 n = p[0]
2766 return b
2766 return b
2767
2767
2768 def between(self, pairs):
2768 def between(self, pairs):
2769 r = []
2769 r = []
2770
2770
2771 for top, bottom in pairs:
2771 for top, bottom in pairs:
2772 n, l, i = top, [], 0
2772 n, l, i = top, [], 0
2773 f = 1
2773 f = 1
2774
2774
2775 while n != bottom and n != nullid:
2775 while n != bottom and n != nullid:
2776 p = self.changelog.parents(n)[0]
2776 p = self.changelog.parents(n)[0]
2777 if i == f:
2777 if i == f:
2778 l.append(n)
2778 l.append(n)
2779 f = f * 2
2779 f = f * 2
2780 n = p
2780 n = p
2781 i += 1
2781 i += 1
2782
2782
2783 r.append(l)
2783 r.append(l)
2784
2784
2785 return r
2785 return r
2786
2786
2787 def checkpush(self, pushop):
2787 def checkpush(self, pushop):
2788 """Extensions can override this function if additional checks have
2788 """Extensions can override this function if additional checks have
2789 to be performed before pushing, or call it if they override push
2789 to be performed before pushing, or call it if they override push
2790 command.
2790 command.
2791 """
2791 """
2792
2792
2793 @unfilteredpropertycache
2793 @unfilteredpropertycache
2794 def prepushoutgoinghooks(self):
2794 def prepushoutgoinghooks(self):
2795 """Return util.hooks consists of a pushop with repo, remote, outgoing
2795 """Return util.hooks consists of a pushop with repo, remote, outgoing
2796 methods, which are called before pushing changesets.
2796 methods, which are called before pushing changesets.
2797 """
2797 """
2798 return util.hooks()
2798 return util.hooks()
2799
2799
2800 def pushkey(self, namespace, key, old, new):
2800 def pushkey(self, namespace, key, old, new):
2801 try:
2801 try:
2802 tr = self.currenttransaction()
2802 tr = self.currenttransaction()
2803 hookargs = {}
2803 hookargs = {}
2804 if tr is not None:
2804 if tr is not None:
2805 hookargs.update(tr.hookargs)
2805 hookargs.update(tr.hookargs)
2806 hookargs = pycompat.strkwargs(hookargs)
2806 hookargs = pycompat.strkwargs(hookargs)
2807 hookargs[r'namespace'] = namespace
2807 hookargs[r'namespace'] = namespace
2808 hookargs[r'key'] = key
2808 hookargs[r'key'] = key
2809 hookargs[r'old'] = old
2809 hookargs[r'old'] = old
2810 hookargs[r'new'] = new
2810 hookargs[r'new'] = new
2811 self.hook('prepushkey', throw=True, **hookargs)
2811 self.hook('prepushkey', throw=True, **hookargs)
2812 except error.HookAbort as exc:
2812 except error.HookAbort as exc:
2813 self.ui.write_err(_("pushkey-abort: %s\n") % exc)
2813 self.ui.write_err(_("pushkey-abort: %s\n") % exc)
2814 if exc.hint:
2814 if exc.hint:
2815 self.ui.write_err(_("(%s)\n") % exc.hint)
2815 self.ui.write_err(_("(%s)\n") % exc.hint)
2816 return False
2816 return False
2817 self.ui.debug('pushing key for "%s:%s"\n' % (namespace, key))
2817 self.ui.debug('pushing key for "%s:%s"\n' % (namespace, key))
2818 ret = pushkey.push(self, namespace, key, old, new)
2818 ret = pushkey.push(self, namespace, key, old, new)
2819 def runhook():
2819 def runhook():
2820 self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
2820 self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
2821 ret=ret)
2821 ret=ret)
2822 self._afterlock(runhook)
2822 self._afterlock(runhook)
2823 return ret
2823 return ret
2824
2824
2825 def listkeys(self, namespace):
2825 def listkeys(self, namespace):
2826 self.hook('prelistkeys', throw=True, namespace=namespace)
2826 self.hook('prelistkeys', throw=True, namespace=namespace)
2827 self.ui.debug('listing keys for "%s"\n' % namespace)
2827 self.ui.debug('listing keys for "%s"\n' % namespace)
2828 values = pushkey.list(self, namespace)
2828 values = pushkey.list(self, namespace)
2829 self.hook('listkeys', namespace=namespace, values=values)
2829 self.hook('listkeys', namespace=namespace, values=values)
2830 return values
2830 return values
2831
2831
2832 def debugwireargs(self, one, two, three=None, four=None, five=None):
2832 def debugwireargs(self, one, two, three=None, four=None, five=None):
2833 '''used to test argument passing over the wire'''
2833 '''used to test argument passing over the wire'''
2834 return "%s %s %s %s %s" % (one, two, pycompat.bytestr(three),
2834 return "%s %s %s %s %s" % (one, two, pycompat.bytestr(three),
2835 pycompat.bytestr(four),
2835 pycompat.bytestr(four),
2836 pycompat.bytestr(five))
2836 pycompat.bytestr(five))
2837
2837
2838 def savecommitmessage(self, text):
2838 def savecommitmessage(self, text):
2839 fp = self.vfs('last-message.txt', 'wb')
2839 fp = self.vfs('last-message.txt', 'wb')
2840 try:
2840 try:
2841 fp.write(text)
2841 fp.write(text)
2842 finally:
2842 finally:
2843 fp.close()
2843 fp.close()
2844 return self.pathto(fp.name[len(self.root) + 1:])
2844 return self.pathto(fp.name[len(self.root) + 1:])
2845
2845
2846 # used to avoid circular references so destructors work
2846 # used to avoid circular references so destructors work
2847 def aftertrans(files):
2847 def aftertrans(files):
2848 renamefiles = [tuple(t) for t in files]
2848 renamefiles = [tuple(t) for t in files]
2849 def a():
2849 def a():
2850 for vfs, src, dest in renamefiles:
2850 for vfs, src, dest in renamefiles:
2851 # if src and dest refer to a same file, vfs.rename is a no-op,
2851 # if src and dest refer to a same file, vfs.rename is a no-op,
2852 # leaving both src and dest on disk. delete dest to make sure
2852 # leaving both src and dest on disk. delete dest to make sure
2853 # the rename couldn't be such a no-op.
2853 # the rename couldn't be such a no-op.
2854 vfs.tryunlink(dest)
2854 vfs.tryunlink(dest)
2855 try:
2855 try:
2856 vfs.rename(src, dest)
2856 vfs.rename(src, dest)
2857 except OSError: # journal file does not yet exist
2857 except OSError: # journal file does not yet exist
2858 pass
2858 pass
2859 return a
2859 return a
2860
2860
2861 def undoname(fn):
2861 def undoname(fn):
2862 base, name = os.path.split(fn)
2862 base, name = os.path.split(fn)
2863 assert name.startswith('journal')
2863 assert name.startswith('journal')
2864 return os.path.join(base, name.replace('journal', 'undo', 1))
2864 return os.path.join(base, name.replace('journal', 'undo', 1))
2865
2865
2866 def instance(ui, path, create, intents=None, createopts=None):
2866 def instance(ui, path, create, intents=None, createopts=None):
2867 localpath = util.urllocalpath(path)
2867 localpath = util.urllocalpath(path)
2868 if create:
2868 if create:
2869 createrepository(ui, localpath, createopts=createopts)
2869 createrepository(ui, localpath, createopts=createopts)
2870
2870
2871 return makelocalrepository(ui, localpath, intents=intents)
2871 return makelocalrepository(ui, localpath, intents=intents)
2872
2872
2873 def islocal(path):
2873 def islocal(path):
2874 return True
2874 return True
2875
2875
2876 def defaultcreateopts(ui, createopts=None):
2876 def defaultcreateopts(ui, createopts=None):
2877 """Populate the default creation options for a repository.
2877 """Populate the default creation options for a repository.
2878
2878
2879 A dictionary of explicitly requested creation options can be passed
2879 A dictionary of explicitly requested creation options can be passed
2880 in. Missing keys will be populated.
2880 in. Missing keys will be populated.
2881 """
2881 """
2882 createopts = dict(createopts or {})
2882 createopts = dict(createopts or {})
2883
2883
2884 if 'backend' not in createopts:
2884 if 'backend' not in createopts:
2885 # experimental config: storage.new-repo-backend
2885 # experimental config: storage.new-repo-backend
2886 createopts['backend'] = ui.config('storage', 'new-repo-backend')
2886 createopts['backend'] = ui.config('storage', 'new-repo-backend')
2887
2887
2888 return createopts
2888 return createopts
2889
2889
2890 def newreporequirements(ui, createopts):
2890 def newreporequirements(ui, createopts):
2891 """Determine the set of requirements for a new local repository.
2891 """Determine the set of requirements for a new local repository.
2892
2892
2893 Extensions can wrap this function to specify custom requirements for
2893 Extensions can wrap this function to specify custom requirements for
2894 new repositories.
2894 new repositories.
2895 """
2895 """
2896 # If the repo is being created from a shared repository, we copy
2896 # If the repo is being created from a shared repository, we copy
2897 # its requirements.
2897 # its requirements.
2898 if 'sharedrepo' in createopts:
2898 if 'sharedrepo' in createopts:
2899 requirements = set(createopts['sharedrepo'].requirements)
2899 requirements = set(createopts['sharedrepo'].requirements)
2900 if createopts.get('sharedrelative'):
2900 if createopts.get('sharedrelative'):
2901 requirements.add('relshared')
2901 requirements.add('relshared')
2902 else:
2902 else:
2903 requirements.add('shared')
2903 requirements.add('shared')
2904
2904
2905 return requirements
2905 return requirements
2906
2906
2907 if 'backend' not in createopts:
2907 if 'backend' not in createopts:
2908 raise error.ProgrammingError('backend key not present in createopts; '
2908 raise error.ProgrammingError('backend key not present in createopts; '
2909 'was defaultcreateopts() called?')
2909 'was defaultcreateopts() called?')
2910
2910
2911 if createopts['backend'] != 'revlogv1':
2911 if createopts['backend'] != 'revlogv1':
2912 raise error.Abort(_('unable to determine repository requirements for '
2912 raise error.Abort(_('unable to determine repository requirements for '
2913 'storage backend: %s') % createopts['backend'])
2913 'storage backend: %s') % createopts['backend'])
2914
2914
2915 requirements = {'revlogv1'}
2915 requirements = {'revlogv1'}
2916 if ui.configbool('format', 'usestore'):
2916 if ui.configbool('format', 'usestore'):
2917 requirements.add('store')
2917 requirements.add('store')
2918 if ui.configbool('format', 'usefncache'):
2918 if ui.configbool('format', 'usefncache'):
2919 requirements.add('fncache')
2919 requirements.add('fncache')
2920 if ui.configbool('format', 'dotencode'):
2920 if ui.configbool('format', 'dotencode'):
2921 requirements.add('dotencode')
2921 requirements.add('dotencode')
2922
2922
2923 compengine = ui.config('experimental', 'format.compression')
2923 compengine = ui.config('format', 'revlog-compression')
2924 if compengine not in util.compengines:
2924 if compengine not in util.compengines:
2925 raise error.Abort(_('compression engine %s defined by '
2925 raise error.Abort(_('compression engine %s defined by '
2926 'experimental.format.compression not available') %
2926 'format.revlog-compression not available') %
2927 compengine,
2927 compengine,
2928 hint=_('run "hg debuginstall" to list available '
2928 hint=_('run "hg debuginstall" to list available '
2929 'compression engines'))
2929 'compression engines'))
2930
2930
2931 # zlib is the historical default and doesn't need an explicit requirement.
2931 # zlib is the historical default and doesn't need an explicit requirement.
2932 if compengine != 'zlib':
2932 if compengine != 'zlib':
2933 requirements.add('exp-compression-%s' % compengine)
2933 requirements.add('exp-compression-%s' % compengine)
2934
2934
2935 if scmutil.gdinitconfig(ui):
2935 if scmutil.gdinitconfig(ui):
2936 requirements.add('generaldelta')
2936 requirements.add('generaldelta')
2937 if ui.configbool('format', 'sparse-revlog'):
2937 if ui.configbool('format', 'sparse-revlog'):
2938 requirements.add(SPARSEREVLOG_REQUIREMENT)
2938 requirements.add(SPARSEREVLOG_REQUIREMENT)
2939 if ui.configbool('experimental', 'treemanifest'):
2939 if ui.configbool('experimental', 'treemanifest'):
2940 requirements.add('treemanifest')
2940 requirements.add('treemanifest')
2941
2941
2942 revlogv2 = ui.config('experimental', 'revlogv2')
2942 revlogv2 = ui.config('experimental', 'revlogv2')
2943 if revlogv2 == 'enable-unstable-format-and-corrupt-my-data':
2943 if revlogv2 == 'enable-unstable-format-and-corrupt-my-data':
2944 requirements.remove('revlogv1')
2944 requirements.remove('revlogv1')
2945 # generaldelta is implied by revlogv2.
2945 # generaldelta is implied by revlogv2.
2946 requirements.discard('generaldelta')
2946 requirements.discard('generaldelta')
2947 requirements.add(REVLOGV2_REQUIREMENT)
2947 requirements.add(REVLOGV2_REQUIREMENT)
2948 # experimental config: format.internal-phase
2948 # experimental config: format.internal-phase
2949 if ui.configbool('format', 'internal-phase'):
2949 if ui.configbool('format', 'internal-phase'):
2950 requirements.add('internal-phase')
2950 requirements.add('internal-phase')
2951
2951
2952 if createopts.get('narrowfiles'):
2952 if createopts.get('narrowfiles'):
2953 requirements.add(repository.NARROW_REQUIREMENT)
2953 requirements.add(repository.NARROW_REQUIREMENT)
2954
2954
2955 if createopts.get('lfs'):
2955 if createopts.get('lfs'):
2956 requirements.add('lfs')
2956 requirements.add('lfs')
2957
2957
2958 return requirements
2958 return requirements
2959
2959
2960 def filterknowncreateopts(ui, createopts):
2960 def filterknowncreateopts(ui, createopts):
2961 """Filters a dict of repo creation options against options that are known.
2961 """Filters a dict of repo creation options against options that are known.
2962
2962
2963 Receives a dict of repo creation options and returns a dict of those
2963 Receives a dict of repo creation options and returns a dict of those
2964 options that we don't know how to handle.
2964 options that we don't know how to handle.
2965
2965
2966 This function is called as part of repository creation. If the
2966 This function is called as part of repository creation. If the
2967 returned dict contains any items, repository creation will not
2967 returned dict contains any items, repository creation will not
2968 be allowed, as it means there was a request to create a repository
2968 be allowed, as it means there was a request to create a repository
2969 with options not recognized by loaded code.
2969 with options not recognized by loaded code.
2970
2970
2971 Extensions can wrap this function to filter out creation options
2971 Extensions can wrap this function to filter out creation options
2972 they know how to handle.
2972 they know how to handle.
2973 """
2973 """
2974 known = {
2974 known = {
2975 'backend',
2975 'backend',
2976 'lfs',
2976 'lfs',
2977 'narrowfiles',
2977 'narrowfiles',
2978 'sharedrepo',
2978 'sharedrepo',
2979 'sharedrelative',
2979 'sharedrelative',
2980 'shareditems',
2980 'shareditems',
2981 'shallowfilestore',
2981 'shallowfilestore',
2982 }
2982 }
2983
2983
2984 return {k: v for k, v in createopts.items() if k not in known}
2984 return {k: v for k, v in createopts.items() if k not in known}
2985
2985
2986 def createrepository(ui, path, createopts=None):
2986 def createrepository(ui, path, createopts=None):
2987 """Create a new repository in a vfs.
2987 """Create a new repository in a vfs.
2988
2988
2989 ``path`` path to the new repo's working directory.
2989 ``path`` path to the new repo's working directory.
2990 ``createopts`` options for the new repository.
2990 ``createopts`` options for the new repository.
2991
2991
2992 The following keys for ``createopts`` are recognized:
2992 The following keys for ``createopts`` are recognized:
2993
2993
2994 backend
2994 backend
2995 The storage backend to use.
2995 The storage backend to use.
2996 lfs
2996 lfs
2997 Repository will be created with ``lfs`` requirement. The lfs extension
2997 Repository will be created with ``lfs`` requirement. The lfs extension
2998 will automatically be loaded when the repository is accessed.
2998 will automatically be loaded when the repository is accessed.
2999 narrowfiles
2999 narrowfiles
3000 Set up repository to support narrow file storage.
3000 Set up repository to support narrow file storage.
3001 sharedrepo
3001 sharedrepo
3002 Repository object from which storage should be shared.
3002 Repository object from which storage should be shared.
3003 sharedrelative
3003 sharedrelative
3004 Boolean indicating if the path to the shared repo should be
3004 Boolean indicating if the path to the shared repo should be
3005 stored as relative. By default, the pointer to the "parent" repo
3005 stored as relative. By default, the pointer to the "parent" repo
3006 is stored as an absolute path.
3006 is stored as an absolute path.
3007 shareditems
3007 shareditems
3008 Set of items to share to the new repository (in addition to storage).
3008 Set of items to share to the new repository (in addition to storage).
3009 shallowfilestore
3009 shallowfilestore
3010 Indicates that storage for files should be shallow (not all ancestor
3010 Indicates that storage for files should be shallow (not all ancestor
3011 revisions are known).
3011 revisions are known).
3012 """
3012 """
3013 createopts = defaultcreateopts(ui, createopts=createopts)
3013 createopts = defaultcreateopts(ui, createopts=createopts)
3014
3014
3015 unknownopts = filterknowncreateopts(ui, createopts)
3015 unknownopts = filterknowncreateopts(ui, createopts)
3016
3016
3017 if not isinstance(unknownopts, dict):
3017 if not isinstance(unknownopts, dict):
3018 raise error.ProgrammingError('filterknowncreateopts() did not return '
3018 raise error.ProgrammingError('filterknowncreateopts() did not return '
3019 'a dict')
3019 'a dict')
3020
3020
3021 if unknownopts:
3021 if unknownopts:
3022 raise error.Abort(_('unable to create repository because of unknown '
3022 raise error.Abort(_('unable to create repository because of unknown '
3023 'creation option: %s') %
3023 'creation option: %s') %
3024 ', '.join(sorted(unknownopts)),
3024 ', '.join(sorted(unknownopts)),
3025 hint=_('is a required extension not loaded?'))
3025 hint=_('is a required extension not loaded?'))
3026
3026
3027 requirements = newreporequirements(ui, createopts=createopts)
3027 requirements = newreporequirements(ui, createopts=createopts)
3028
3028
3029 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
3029 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
3030
3030
3031 hgvfs = vfsmod.vfs(wdirvfs.join(b'.hg'))
3031 hgvfs = vfsmod.vfs(wdirvfs.join(b'.hg'))
3032 if hgvfs.exists():
3032 if hgvfs.exists():
3033 raise error.RepoError(_('repository %s already exists') % path)
3033 raise error.RepoError(_('repository %s already exists') % path)
3034
3034
3035 if 'sharedrepo' in createopts:
3035 if 'sharedrepo' in createopts:
3036 sharedpath = createopts['sharedrepo'].sharedpath
3036 sharedpath = createopts['sharedrepo'].sharedpath
3037
3037
3038 if createopts.get('sharedrelative'):
3038 if createopts.get('sharedrelative'):
3039 try:
3039 try:
3040 sharedpath = os.path.relpath(sharedpath, hgvfs.base)
3040 sharedpath = os.path.relpath(sharedpath, hgvfs.base)
3041 except (IOError, ValueError) as e:
3041 except (IOError, ValueError) as e:
3042 # ValueError is raised on Windows if the drive letters differ
3042 # ValueError is raised on Windows if the drive letters differ
3043 # on each path.
3043 # on each path.
3044 raise error.Abort(_('cannot calculate relative path'),
3044 raise error.Abort(_('cannot calculate relative path'),
3045 hint=stringutil.forcebytestr(e))
3045 hint=stringutil.forcebytestr(e))
3046
3046
3047 if not wdirvfs.exists():
3047 if not wdirvfs.exists():
3048 wdirvfs.makedirs()
3048 wdirvfs.makedirs()
3049
3049
3050 hgvfs.makedir(notindexed=True)
3050 hgvfs.makedir(notindexed=True)
3051 if 'sharedrepo' not in createopts:
3051 if 'sharedrepo' not in createopts:
3052 hgvfs.mkdir(b'cache')
3052 hgvfs.mkdir(b'cache')
3053 hgvfs.mkdir(b'wcache')
3053 hgvfs.mkdir(b'wcache')
3054
3054
3055 if b'store' in requirements and 'sharedrepo' not in createopts:
3055 if b'store' in requirements and 'sharedrepo' not in createopts:
3056 hgvfs.mkdir(b'store')
3056 hgvfs.mkdir(b'store')
3057
3057
3058 # We create an invalid changelog outside the store so very old
3058 # We create an invalid changelog outside the store so very old
3059 # Mercurial versions (which didn't know about the requirements
3059 # Mercurial versions (which didn't know about the requirements
3060 # file) encounter an error on reading the changelog. This
3060 # file) encounter an error on reading the changelog. This
3061 # effectively locks out old clients and prevents them from
3061 # effectively locks out old clients and prevents them from
3062 # mucking with a repo in an unknown format.
3062 # mucking with a repo in an unknown format.
3063 #
3063 #
3064 # The revlog header has version 2, which won't be recognized by
3064 # The revlog header has version 2, which won't be recognized by
3065 # such old clients.
3065 # such old clients.
3066 hgvfs.append(b'00changelog.i',
3066 hgvfs.append(b'00changelog.i',
3067 b'\0\0\0\2 dummy changelog to prevent using the old repo '
3067 b'\0\0\0\2 dummy changelog to prevent using the old repo '
3068 b'layout')
3068 b'layout')
3069
3069
3070 scmutil.writerequires(hgvfs, requirements)
3070 scmutil.writerequires(hgvfs, requirements)
3071
3071
3072 # Write out file telling readers where to find the shared store.
3072 # Write out file telling readers where to find the shared store.
3073 if 'sharedrepo' in createopts:
3073 if 'sharedrepo' in createopts:
3074 hgvfs.write(b'sharedpath', sharedpath)
3074 hgvfs.write(b'sharedpath', sharedpath)
3075
3075
3076 if createopts.get('shareditems'):
3076 if createopts.get('shareditems'):
3077 shared = b'\n'.join(sorted(createopts['shareditems'])) + b'\n'
3077 shared = b'\n'.join(sorted(createopts['shareditems'])) + b'\n'
3078 hgvfs.write(b'shared', shared)
3078 hgvfs.write(b'shared', shared)
3079
3079
3080 def poisonrepository(repo):
3080 def poisonrepository(repo):
3081 """Poison a repository instance so it can no longer be used."""
3081 """Poison a repository instance so it can no longer be used."""
3082 # Perform any cleanup on the instance.
3082 # Perform any cleanup on the instance.
3083 repo.close()
3083 repo.close()
3084
3084
3085 # Our strategy is to replace the type of the object with one that
3085 # Our strategy is to replace the type of the object with one that
3086 # has all attribute lookups result in error.
3086 # has all attribute lookups result in error.
3087 #
3087 #
3088 # But we have to allow the close() method because some constructors
3088 # But we have to allow the close() method because some constructors
3089 # of repos call close() on repo references.
3089 # of repos call close() on repo references.
3090 class poisonedrepository(object):
3090 class poisonedrepository(object):
3091 def __getattribute__(self, item):
3091 def __getattribute__(self, item):
3092 if item == r'close':
3092 if item == r'close':
3093 return object.__getattribute__(self, item)
3093 return object.__getattribute__(self, item)
3094
3094
3095 raise error.ProgrammingError('repo instances should not be used '
3095 raise error.ProgrammingError('repo instances should not be used '
3096 'after unshare')
3096 'after unshare')
3097
3097
3098 def close(self):
3098 def close(self):
3099 pass
3099 pass
3100
3100
3101 # We may have a repoview, which intercepts __setattr__. So be sure
3101 # We may have a repoview, which intercepts __setattr__. So be sure
3102 # we operate at the lowest level possible.
3102 # we operate at the lowest level possible.
3103 object.__setattr__(repo, r'__class__', poisonedrepository)
3103 object.__setattr__(repo, r'__class__', poisonedrepository)
@@ -1,949 +1,949 b''
1 # upgrade.py - functions for in place upgrade of Mercurial repository
1 # upgrade.py - functions for in place upgrade of Mercurial repository
2 #
2 #
3 # Copyright (c) 2016-present, Gregory Szorc
3 # Copyright (c) 2016-present, Gregory Szorc
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 stat
10 import stat
11
11
12 from .i18n import _
12 from .i18n import _
13 from . import (
13 from . import (
14 changelog,
14 changelog,
15 error,
15 error,
16 filelog,
16 filelog,
17 hg,
17 hg,
18 localrepo,
18 localrepo,
19 manifest,
19 manifest,
20 pycompat,
20 pycompat,
21 revlog,
21 revlog,
22 scmutil,
22 scmutil,
23 util,
23 util,
24 vfs as vfsmod,
24 vfs as vfsmod,
25 )
25 )
26
26
27 def requiredsourcerequirements(repo):
27 def requiredsourcerequirements(repo):
28 """Obtain requirements required to be present to upgrade a repo.
28 """Obtain requirements required to be present to upgrade a repo.
29
29
30 An upgrade will not be allowed if the repository doesn't have the
30 An upgrade will not be allowed if the repository doesn't have the
31 requirements returned by this function.
31 requirements returned by this function.
32 """
32 """
33 return {
33 return {
34 # Introduced in Mercurial 0.9.2.
34 # Introduced in Mercurial 0.9.2.
35 'revlogv1',
35 'revlogv1',
36 # Introduced in Mercurial 0.9.2.
36 # Introduced in Mercurial 0.9.2.
37 'store',
37 'store',
38 }
38 }
39
39
40 def blocksourcerequirements(repo):
40 def blocksourcerequirements(repo):
41 """Obtain requirements that will prevent an upgrade from occurring.
41 """Obtain requirements that will prevent an upgrade from occurring.
42
42
43 An upgrade cannot be performed if the source repository contains a
43 An upgrade cannot be performed if the source repository contains a
44 requirements in the returned set.
44 requirements in the returned set.
45 """
45 """
46 return {
46 return {
47 # The upgrade code does not yet support these experimental features.
47 # The upgrade code does not yet support these experimental features.
48 # This is an artificial limitation.
48 # This is an artificial limitation.
49 'treemanifest',
49 'treemanifest',
50 # This was a precursor to generaldelta and was never enabled by default.
50 # This was a precursor to generaldelta and was never enabled by default.
51 # It should (hopefully) not exist in the wild.
51 # It should (hopefully) not exist in the wild.
52 'parentdelta',
52 'parentdelta',
53 # Upgrade should operate on the actual store, not the shared link.
53 # Upgrade should operate on the actual store, not the shared link.
54 'shared',
54 'shared',
55 }
55 }
56
56
57 def supportremovedrequirements(repo):
57 def supportremovedrequirements(repo):
58 """Obtain requirements that can be removed during an upgrade.
58 """Obtain requirements that can be removed during an upgrade.
59
59
60 If an upgrade were to create a repository that dropped a requirement,
60 If an upgrade were to create a repository that dropped a requirement,
61 the dropped requirement must appear in the returned set for the upgrade
61 the dropped requirement must appear in the returned set for the upgrade
62 to be allowed.
62 to be allowed.
63 """
63 """
64 return {
64 return {
65 localrepo.SPARSEREVLOG_REQUIREMENT,
65 localrepo.SPARSEREVLOG_REQUIREMENT,
66 }
66 }
67
67
68 def supporteddestrequirements(repo):
68 def supporteddestrequirements(repo):
69 """Obtain requirements that upgrade supports in the destination.
69 """Obtain requirements that upgrade supports in the destination.
70
70
71 If the result of the upgrade would create requirements not in this set,
71 If the result of the upgrade would create requirements not in this set,
72 the upgrade is disallowed.
72 the upgrade is disallowed.
73
73
74 Extensions should monkeypatch this to add their custom requirements.
74 Extensions should monkeypatch this to add their custom requirements.
75 """
75 """
76 return {
76 return {
77 'dotencode',
77 'dotencode',
78 'fncache',
78 'fncache',
79 'generaldelta',
79 'generaldelta',
80 'revlogv1',
80 'revlogv1',
81 'store',
81 'store',
82 localrepo.SPARSEREVLOG_REQUIREMENT,
82 localrepo.SPARSEREVLOG_REQUIREMENT,
83 }
83 }
84
84
85 def allowednewrequirements(repo):
85 def allowednewrequirements(repo):
86 """Obtain requirements that can be added to a repository during upgrade.
86 """Obtain requirements that can be added to a repository during upgrade.
87
87
88 This is used to disallow proposed requirements from being added when
88 This is used to disallow proposed requirements from being added when
89 they weren't present before.
89 they weren't present before.
90
90
91 We use a list of allowed requirement additions instead of a list of known
91 We use a list of allowed requirement additions instead of a list of known
92 bad additions because the whitelist approach is safer and will prevent
92 bad additions because the whitelist approach is safer and will prevent
93 future, unknown requirements from accidentally being added.
93 future, unknown requirements from accidentally being added.
94 """
94 """
95 return {
95 return {
96 'dotencode',
96 'dotencode',
97 'fncache',
97 'fncache',
98 'generaldelta',
98 'generaldelta',
99 localrepo.SPARSEREVLOG_REQUIREMENT,
99 localrepo.SPARSEREVLOG_REQUIREMENT,
100 }
100 }
101
101
102 def preservedrequirements(repo):
102 def preservedrequirements(repo):
103 return set()
103 return set()
104
104
105 deficiency = 'deficiency'
105 deficiency = 'deficiency'
106 optimisation = 'optimization'
106 optimisation = 'optimization'
107
107
108 class improvement(object):
108 class improvement(object):
109 """Represents an improvement that can be made as part of an upgrade.
109 """Represents an improvement that can be made as part of an upgrade.
110
110
111 The following attributes are defined on each instance:
111 The following attributes are defined on each instance:
112
112
113 name
113 name
114 Machine-readable string uniquely identifying this improvement. It
114 Machine-readable string uniquely identifying this improvement. It
115 will be mapped to an action later in the upgrade process.
115 will be mapped to an action later in the upgrade process.
116
116
117 type
117 type
118 Either ``deficiency`` or ``optimisation``. A deficiency is an obvious
118 Either ``deficiency`` or ``optimisation``. A deficiency is an obvious
119 problem. An optimization is an action (sometimes optional) that
119 problem. An optimization is an action (sometimes optional) that
120 can be taken to further improve the state of the repository.
120 can be taken to further improve the state of the repository.
121
121
122 description
122 description
123 Message intended for humans explaining the improvement in more detail,
123 Message intended for humans explaining the improvement in more detail,
124 including the implications of it. For ``deficiency`` types, should be
124 including the implications of it. For ``deficiency`` types, should be
125 worded in the present tense. For ``optimisation`` types, should be
125 worded in the present tense. For ``optimisation`` types, should be
126 worded in the future tense.
126 worded in the future tense.
127
127
128 upgrademessage
128 upgrademessage
129 Message intended for humans explaining what an upgrade addressing this
129 Message intended for humans explaining what an upgrade addressing this
130 issue will do. Should be worded in the future tense.
130 issue will do. Should be worded in the future tense.
131 """
131 """
132 def __init__(self, name, type, description, upgrademessage):
132 def __init__(self, name, type, description, upgrademessage):
133 self.name = name
133 self.name = name
134 self.type = type
134 self.type = type
135 self.description = description
135 self.description = description
136 self.upgrademessage = upgrademessage
136 self.upgrademessage = upgrademessage
137
137
138 def __eq__(self, other):
138 def __eq__(self, other):
139 if not isinstance(other, improvement):
139 if not isinstance(other, improvement):
140 # This is what python tell use to do
140 # This is what python tell use to do
141 return NotImplemented
141 return NotImplemented
142 return self.name == other.name
142 return self.name == other.name
143
143
144 def __ne__(self, other):
144 def __ne__(self, other):
145 return not (self == other)
145 return not (self == other)
146
146
147 def __hash__(self):
147 def __hash__(self):
148 return hash(self.name)
148 return hash(self.name)
149
149
150 allformatvariant = []
150 allformatvariant = []
151
151
152 def registerformatvariant(cls):
152 def registerformatvariant(cls):
153 allformatvariant.append(cls)
153 allformatvariant.append(cls)
154 return cls
154 return cls
155
155
156 class formatvariant(improvement):
156 class formatvariant(improvement):
157 """an improvement subclass dedicated to repository format"""
157 """an improvement subclass dedicated to repository format"""
158 type = deficiency
158 type = deficiency
159 ### The following attributes should be defined for each class:
159 ### The following attributes should be defined for each class:
160
160
161 # machine-readable string uniquely identifying this improvement. it will be
161 # machine-readable string uniquely identifying this improvement. it will be
162 # mapped to an action later in the upgrade process.
162 # mapped to an action later in the upgrade process.
163 name = None
163 name = None
164
164
165 # message intended for humans explaining the improvement in more detail,
165 # message intended for humans explaining the improvement in more detail,
166 # including the implications of it ``deficiency`` types, should be worded
166 # including the implications of it ``deficiency`` types, should be worded
167 # in the present tense.
167 # in the present tense.
168 description = None
168 description = None
169
169
170 # message intended for humans explaining what an upgrade addressing this
170 # message intended for humans explaining what an upgrade addressing this
171 # issue will do. should be worded in the future tense.
171 # issue will do. should be worded in the future tense.
172 upgrademessage = None
172 upgrademessage = None
173
173
174 # value of current Mercurial default for new repository
174 # value of current Mercurial default for new repository
175 default = None
175 default = None
176
176
177 def __init__(self):
177 def __init__(self):
178 raise NotImplementedError()
178 raise NotImplementedError()
179
179
180 @staticmethod
180 @staticmethod
181 def fromrepo(repo):
181 def fromrepo(repo):
182 """current value of the variant in the repository"""
182 """current value of the variant in the repository"""
183 raise NotImplementedError()
183 raise NotImplementedError()
184
184
185 @staticmethod
185 @staticmethod
186 def fromconfig(repo):
186 def fromconfig(repo):
187 """current value of the variant in the configuration"""
187 """current value of the variant in the configuration"""
188 raise NotImplementedError()
188 raise NotImplementedError()
189
189
190 class requirementformatvariant(formatvariant):
190 class requirementformatvariant(formatvariant):
191 """formatvariant based on a 'requirement' name.
191 """formatvariant based on a 'requirement' name.
192
192
193 Many format variant are controlled by a 'requirement'. We define a small
193 Many format variant are controlled by a 'requirement'. We define a small
194 subclass to factor the code.
194 subclass to factor the code.
195 """
195 """
196
196
197 # the requirement that control this format variant
197 # the requirement that control this format variant
198 _requirement = None
198 _requirement = None
199
199
200 @staticmethod
200 @staticmethod
201 def _newreporequirements(ui):
201 def _newreporequirements(ui):
202 return localrepo.newreporequirements(
202 return localrepo.newreporequirements(
203 ui, localrepo.defaultcreateopts(ui))
203 ui, localrepo.defaultcreateopts(ui))
204
204
205 @classmethod
205 @classmethod
206 def fromrepo(cls, repo):
206 def fromrepo(cls, repo):
207 assert cls._requirement is not None
207 assert cls._requirement is not None
208 return cls._requirement in repo.requirements
208 return cls._requirement in repo.requirements
209
209
210 @classmethod
210 @classmethod
211 def fromconfig(cls, repo):
211 def fromconfig(cls, repo):
212 assert cls._requirement is not None
212 assert cls._requirement is not None
213 return cls._requirement in cls._newreporequirements(repo.ui)
213 return cls._requirement in cls._newreporequirements(repo.ui)
214
214
215 @registerformatvariant
215 @registerformatvariant
216 class fncache(requirementformatvariant):
216 class fncache(requirementformatvariant):
217 name = 'fncache'
217 name = 'fncache'
218
218
219 _requirement = 'fncache'
219 _requirement = 'fncache'
220
220
221 default = True
221 default = True
222
222
223 description = _('long and reserved filenames may not work correctly; '
223 description = _('long and reserved filenames may not work correctly; '
224 'repository performance is sub-optimal')
224 'repository performance is sub-optimal')
225
225
226 upgrademessage = _('repository will be more resilient to storing '
226 upgrademessage = _('repository will be more resilient to storing '
227 'certain paths and performance of certain '
227 'certain paths and performance of certain '
228 'operations should be improved')
228 'operations should be improved')
229
229
230 @registerformatvariant
230 @registerformatvariant
231 class dotencode(requirementformatvariant):
231 class dotencode(requirementformatvariant):
232 name = 'dotencode'
232 name = 'dotencode'
233
233
234 _requirement = 'dotencode'
234 _requirement = 'dotencode'
235
235
236 default = True
236 default = True
237
237
238 description = _('storage of filenames beginning with a period or '
238 description = _('storage of filenames beginning with a period or '
239 'space may not work correctly')
239 'space may not work correctly')
240
240
241 upgrademessage = _('repository will be better able to store files '
241 upgrademessage = _('repository will be better able to store files '
242 'beginning with a space or period')
242 'beginning with a space or period')
243
243
244 @registerformatvariant
244 @registerformatvariant
245 class generaldelta(requirementformatvariant):
245 class generaldelta(requirementformatvariant):
246 name = 'generaldelta'
246 name = 'generaldelta'
247
247
248 _requirement = 'generaldelta'
248 _requirement = 'generaldelta'
249
249
250 default = True
250 default = True
251
251
252 description = _('deltas within internal storage are unable to '
252 description = _('deltas within internal storage are unable to '
253 'choose optimal revisions; repository is larger and '
253 'choose optimal revisions; repository is larger and '
254 'slower than it could be; interaction with other '
254 'slower than it could be; interaction with other '
255 'repositories may require extra network and CPU '
255 'repositories may require extra network and CPU '
256 'resources, making "hg push" and "hg pull" slower')
256 'resources, making "hg push" and "hg pull" slower')
257
257
258 upgrademessage = _('repository storage will be able to create '
258 upgrademessage = _('repository storage will be able to create '
259 'optimal deltas; new repository data will be '
259 'optimal deltas; new repository data will be '
260 'smaller and read times should decrease; '
260 'smaller and read times should decrease; '
261 'interacting with other repositories using this '
261 'interacting with other repositories using this '
262 'storage model should require less network and '
262 'storage model should require less network and '
263 'CPU resources, making "hg push" and "hg pull" '
263 'CPU resources, making "hg push" and "hg pull" '
264 'faster')
264 'faster')
265
265
266 @registerformatvariant
266 @registerformatvariant
267 class sparserevlog(requirementformatvariant):
267 class sparserevlog(requirementformatvariant):
268 name = 'sparserevlog'
268 name = 'sparserevlog'
269
269
270 _requirement = localrepo.SPARSEREVLOG_REQUIREMENT
270 _requirement = localrepo.SPARSEREVLOG_REQUIREMENT
271
271
272 default = True
272 default = True
273
273
274 description = _('in order to limit disk reading and memory usage on older '
274 description = _('in order to limit disk reading and memory usage on older '
275 'version, the span of a delta chain from its root to its '
275 'version, the span of a delta chain from its root to its '
276 'end is limited, whatever the relevant data in this span. '
276 'end is limited, whatever the relevant data in this span. '
277 'This can severly limit Mercurial ability to build good '
277 'This can severly limit Mercurial ability to build good '
278 'chain of delta resulting is much more storage space being '
278 'chain of delta resulting is much more storage space being '
279 'taken and limit reusability of on disk delta during '
279 'taken and limit reusability of on disk delta during '
280 'exchange.'
280 'exchange.'
281 )
281 )
282
282
283 upgrademessage = _('Revlog supports delta chain with more unused data '
283 upgrademessage = _('Revlog supports delta chain with more unused data '
284 'between payload. These gaps will be skipped at read '
284 'between payload. These gaps will be skipped at read '
285 'time. This allows for better delta chains, making a '
285 'time. This allows for better delta chains, making a '
286 'better compression and faster exchange with server.')
286 'better compression and faster exchange with server.')
287
287
288 @registerformatvariant
288 @registerformatvariant
289 class removecldeltachain(formatvariant):
289 class removecldeltachain(formatvariant):
290 name = 'plain-cl-delta'
290 name = 'plain-cl-delta'
291
291
292 default = True
292 default = True
293
293
294 description = _('changelog storage is using deltas instead of '
294 description = _('changelog storage is using deltas instead of '
295 'raw entries; changelog reading and any '
295 'raw entries; changelog reading and any '
296 'operation relying on changelog data are slower '
296 'operation relying on changelog data are slower '
297 'than they could be')
297 'than they could be')
298
298
299 upgrademessage = _('changelog storage will be reformated to '
299 upgrademessage = _('changelog storage will be reformated to '
300 'store raw entries; changelog reading will be '
300 'store raw entries; changelog reading will be '
301 'faster; changelog size may be reduced')
301 'faster; changelog size may be reduced')
302
302
303 @staticmethod
303 @staticmethod
304 def fromrepo(repo):
304 def fromrepo(repo):
305 # Mercurial 4.0 changed changelogs to not use delta chains. Search for
305 # Mercurial 4.0 changed changelogs to not use delta chains. Search for
306 # changelogs with deltas.
306 # changelogs with deltas.
307 cl = repo.changelog
307 cl = repo.changelog
308 chainbase = cl.chainbase
308 chainbase = cl.chainbase
309 return all(rev == chainbase(rev) for rev in cl)
309 return all(rev == chainbase(rev) for rev in cl)
310
310
311 @staticmethod
311 @staticmethod
312 def fromconfig(repo):
312 def fromconfig(repo):
313 return True
313 return True
314
314
315 @registerformatvariant
315 @registerformatvariant
316 class compressionengine(formatvariant):
316 class compressionengine(formatvariant):
317 name = 'compression'
317 name = 'compression'
318 default = 'zlib'
318 default = 'zlib'
319
319
320 description = _('Compresion algorithm used to compress data. '
320 description = _('Compresion algorithm used to compress data. '
321 'Some engine are faster than other')
321 'Some engine are faster than other')
322
322
323 upgrademessage = _('revlog content will be recompressed with the new '
323 upgrademessage = _('revlog content will be recompressed with the new '
324 'algorithm.')
324 'algorithm.')
325
325
326 @classmethod
326 @classmethod
327 def fromrepo(cls, repo):
327 def fromrepo(cls, repo):
328 for req in repo.requirements:
328 for req in repo.requirements:
329 if req.startswith('exp-compression-'):
329 if req.startswith('exp-compression-'):
330 return req.split('-', 2)[2]
330 return req.split('-', 2)[2]
331 return 'zlib'
331 return 'zlib'
332
332
333 @classmethod
333 @classmethod
334 def fromconfig(cls, repo):
334 def fromconfig(cls, repo):
335 return repo.ui.config('experimental', 'format.compression')
335 return repo.ui.config('format', 'revlog-compression')
336
336
337 @registerformatvariant
337 @registerformatvariant
338 class compressionlevel(formatvariant):
338 class compressionlevel(formatvariant):
339 name = 'compression-level'
339 name = 'compression-level'
340 default = 'default'
340 default = 'default'
341
341
342 description = _('compression level')
342 description = _('compression level')
343
343
344 upgrademessage = _('revlog content will be recompressed')
344 upgrademessage = _('revlog content will be recompressed')
345
345
346 @classmethod
346 @classmethod
347 def fromrepo(cls, repo):
347 def fromrepo(cls, repo):
348 comp = compressionengine.fromrepo(repo)
348 comp = compressionengine.fromrepo(repo)
349 level = None
349 level = None
350 if comp == 'zlib':
350 if comp == 'zlib':
351 level = repo.ui.configint('storage', 'revlog.zlib.level')
351 level = repo.ui.configint('storage', 'revlog.zlib.level')
352 elif comp == 'zstd':
352 elif comp == 'zstd':
353 level = repo.ui.configint('storage', 'revlog.zstd.level')
353 level = repo.ui.configint('storage', 'revlog.zstd.level')
354 if level is None:
354 if level is None:
355 return 'default'
355 return 'default'
356 return bytes(level)
356 return bytes(level)
357
357
358 @classmethod
358 @classmethod
359 def fromconfig(cls, repo):
359 def fromconfig(cls, repo):
360 comp = compressionengine.fromconfig(repo)
360 comp = compressionengine.fromconfig(repo)
361 level = None
361 level = None
362 if comp == 'zlib':
362 if comp == 'zlib':
363 level = repo.ui.configint('storage', 'revlog.zlib.level')
363 level = repo.ui.configint('storage', 'revlog.zlib.level')
364 elif comp == 'zstd':
364 elif comp == 'zstd':
365 level = repo.ui.configint('storage', 'revlog.zstd.level')
365 level = repo.ui.configint('storage', 'revlog.zstd.level')
366 if level is None:
366 if level is None:
367 return 'default'
367 return 'default'
368 return bytes(level)
368 return bytes(level)
369
369
370 def finddeficiencies(repo):
370 def finddeficiencies(repo):
371 """returns a list of deficiencies that the repo suffer from"""
371 """returns a list of deficiencies that the repo suffer from"""
372 deficiencies = []
372 deficiencies = []
373
373
374 # We could detect lack of revlogv1 and store here, but they were added
374 # We could detect lack of revlogv1 and store here, but they were added
375 # in 0.9.2 and we don't support upgrading repos without these
375 # in 0.9.2 and we don't support upgrading repos without these
376 # requirements, so let's not bother.
376 # requirements, so let's not bother.
377
377
378 for fv in allformatvariant:
378 for fv in allformatvariant:
379 if not fv.fromrepo(repo):
379 if not fv.fromrepo(repo):
380 deficiencies.append(fv)
380 deficiencies.append(fv)
381
381
382 return deficiencies
382 return deficiencies
383
383
384 # search without '-' to support older form on newer client.
384 # search without '-' to support older form on newer client.
385 #
385 #
386 # We don't enforce backward compatibility for debug command so this
386 # We don't enforce backward compatibility for debug command so this
387 # might eventually be dropped. However, having to use two different
387 # might eventually be dropped. However, having to use two different
388 # forms in script when comparing result is anoying enough to add
388 # forms in script when comparing result is anoying enough to add
389 # backward compatibility for a while.
389 # backward compatibility for a while.
390 legacy_opts_map = {
390 legacy_opts_map = {
391 'redeltaparent': 're-delta-parent',
391 'redeltaparent': 're-delta-parent',
392 'redeltamultibase': 're-delta-multibase',
392 'redeltamultibase': 're-delta-multibase',
393 'redeltaall': 're-delta-all',
393 'redeltaall': 're-delta-all',
394 'redeltafulladd': 're-delta-fulladd',
394 'redeltafulladd': 're-delta-fulladd',
395 }
395 }
396
396
397 def findoptimizations(repo):
397 def findoptimizations(repo):
398 """Determine optimisation that could be used during upgrade"""
398 """Determine optimisation that could be used during upgrade"""
399 # These are unconditionally added. There is logic later that figures out
399 # These are unconditionally added. There is logic later that figures out
400 # which ones to apply.
400 # which ones to apply.
401 optimizations = []
401 optimizations = []
402
402
403 optimizations.append(improvement(
403 optimizations.append(improvement(
404 name='re-delta-parent',
404 name='re-delta-parent',
405 type=optimisation,
405 type=optimisation,
406 description=_('deltas within internal storage will be recalculated to '
406 description=_('deltas within internal storage will be recalculated to '
407 'choose an optimal base revision where this was not '
407 'choose an optimal base revision where this was not '
408 'already done; the size of the repository may shrink and '
408 'already done; the size of the repository may shrink and '
409 'various operations may become faster; the first time '
409 'various operations may become faster; the first time '
410 'this optimization is performed could slow down upgrade '
410 'this optimization is performed could slow down upgrade '
411 'execution considerably; subsequent invocations should '
411 'execution considerably; subsequent invocations should '
412 'not run noticeably slower'),
412 'not run noticeably slower'),
413 upgrademessage=_('deltas within internal storage will choose a new '
413 upgrademessage=_('deltas within internal storage will choose a new '
414 'base revision if needed')))
414 'base revision if needed')))
415
415
416 optimizations.append(improvement(
416 optimizations.append(improvement(
417 name='re-delta-multibase',
417 name='re-delta-multibase',
418 type=optimisation,
418 type=optimisation,
419 description=_('deltas within internal storage will be recalculated '
419 description=_('deltas within internal storage will be recalculated '
420 'against multiple base revision and the smallest '
420 'against multiple base revision and the smallest '
421 'difference will be used; the size of the repository may '
421 'difference will be used; the size of the repository may '
422 'shrink significantly when there are many merges; this '
422 'shrink significantly when there are many merges; this '
423 'optimization will slow down execution in proportion to '
423 'optimization will slow down execution in proportion to '
424 'the number of merges in the repository and the amount '
424 'the number of merges in the repository and the amount '
425 'of files in the repository; this slow down should not '
425 'of files in the repository; this slow down should not '
426 'be significant unless there are tens of thousands of '
426 'be significant unless there are tens of thousands of '
427 'files and thousands of merges'),
427 'files and thousands of merges'),
428 upgrademessage=_('deltas within internal storage will choose an '
428 upgrademessage=_('deltas within internal storage will choose an '
429 'optimal delta by computing deltas against multiple '
429 'optimal delta by computing deltas against multiple '
430 'parents; may slow down execution time '
430 'parents; may slow down execution time '
431 'significantly')))
431 'significantly')))
432
432
433 optimizations.append(improvement(
433 optimizations.append(improvement(
434 name='re-delta-all',
434 name='re-delta-all',
435 type=optimisation,
435 type=optimisation,
436 description=_('deltas within internal storage will always be '
436 description=_('deltas within internal storage will always be '
437 'recalculated without reusing prior deltas; this will '
437 'recalculated without reusing prior deltas; this will '
438 'likely make execution run several times slower; this '
438 'likely make execution run several times slower; this '
439 'optimization is typically not needed'),
439 'optimization is typically not needed'),
440 upgrademessage=_('deltas within internal storage will be fully '
440 upgrademessage=_('deltas within internal storage will be fully '
441 'recomputed; this will likely drastically slow down '
441 'recomputed; this will likely drastically slow down '
442 'execution time')))
442 'execution time')))
443
443
444 optimizations.append(improvement(
444 optimizations.append(improvement(
445 name='re-delta-fulladd',
445 name='re-delta-fulladd',
446 type=optimisation,
446 type=optimisation,
447 description=_('every revision will be re-added as if it was new '
447 description=_('every revision will be re-added as if it was new '
448 'content. It will go through the full storage '
448 'content. It will go through the full storage '
449 'mechanism giving extensions a chance to process it '
449 'mechanism giving extensions a chance to process it '
450 '(eg. lfs). This is similar to "re-delta-all" but even '
450 '(eg. lfs). This is similar to "re-delta-all" but even '
451 'slower since more logic is involved.'),
451 'slower since more logic is involved.'),
452 upgrademessage=_('each revision will be added as new content to the '
452 upgrademessage=_('each revision will be added as new content to the '
453 'internal storage; this will likely drastically slow '
453 'internal storage; this will likely drastically slow '
454 'down execution time, but some extensions might need '
454 'down execution time, but some extensions might need '
455 'it')))
455 'it')))
456
456
457 return optimizations
457 return optimizations
458
458
459 def determineactions(repo, deficiencies, sourcereqs, destreqs):
459 def determineactions(repo, deficiencies, sourcereqs, destreqs):
460 """Determine upgrade actions that will be performed.
460 """Determine upgrade actions that will be performed.
461
461
462 Given a list of improvements as returned by ``finddeficiencies`` and
462 Given a list of improvements as returned by ``finddeficiencies`` and
463 ``findoptimizations``, determine the list of upgrade actions that
463 ``findoptimizations``, determine the list of upgrade actions that
464 will be performed.
464 will be performed.
465
465
466 The role of this function is to filter improvements if needed, apply
466 The role of this function is to filter improvements if needed, apply
467 recommended optimizations from the improvements list that make sense,
467 recommended optimizations from the improvements list that make sense,
468 etc.
468 etc.
469
469
470 Returns a list of action names.
470 Returns a list of action names.
471 """
471 """
472 newactions = []
472 newactions = []
473
473
474 knownreqs = supporteddestrequirements(repo)
474 knownreqs = supporteddestrequirements(repo)
475
475
476 for d in deficiencies:
476 for d in deficiencies:
477 name = d.name
477 name = d.name
478
478
479 # If the action is a requirement that doesn't show up in the
479 # If the action is a requirement that doesn't show up in the
480 # destination requirements, prune the action.
480 # destination requirements, prune the action.
481 if name in knownreqs and name not in destreqs:
481 if name in knownreqs and name not in destreqs:
482 continue
482 continue
483
483
484 newactions.append(d)
484 newactions.append(d)
485
485
486 # FUTURE consider adding some optimizations here for certain transitions.
486 # FUTURE consider adding some optimizations here for certain transitions.
487 # e.g. adding generaldelta could schedule parent redeltas.
487 # e.g. adding generaldelta could schedule parent redeltas.
488
488
489 return newactions
489 return newactions
490
490
491 def _revlogfrompath(repo, path):
491 def _revlogfrompath(repo, path):
492 """Obtain a revlog from a repo path.
492 """Obtain a revlog from a repo path.
493
493
494 An instance of the appropriate class is returned.
494 An instance of the appropriate class is returned.
495 """
495 """
496 if path == '00changelog.i':
496 if path == '00changelog.i':
497 return changelog.changelog(repo.svfs)
497 return changelog.changelog(repo.svfs)
498 elif path.endswith('00manifest.i'):
498 elif path.endswith('00manifest.i'):
499 mandir = path[:-len('00manifest.i')]
499 mandir = path[:-len('00manifest.i')]
500 return manifest.manifestrevlog(repo.svfs, tree=mandir)
500 return manifest.manifestrevlog(repo.svfs, tree=mandir)
501 else:
501 else:
502 #reverse of "/".join(("data", path + ".i"))
502 #reverse of "/".join(("data", path + ".i"))
503 return filelog.filelog(repo.svfs, path[5:-2])
503 return filelog.filelog(repo.svfs, path[5:-2])
504
504
505 def _copyrevlogs(ui, srcrepo, dstrepo, tr, deltareuse, forcedeltabothparents):
505 def _copyrevlogs(ui, srcrepo, dstrepo, tr, deltareuse, forcedeltabothparents):
506 """Copy revlogs between 2 repos."""
506 """Copy revlogs between 2 repos."""
507 revcount = 0
507 revcount = 0
508 srcsize = 0
508 srcsize = 0
509 srcrawsize = 0
509 srcrawsize = 0
510 dstsize = 0
510 dstsize = 0
511 fcount = 0
511 fcount = 0
512 frevcount = 0
512 frevcount = 0
513 fsrcsize = 0
513 fsrcsize = 0
514 frawsize = 0
514 frawsize = 0
515 fdstsize = 0
515 fdstsize = 0
516 mcount = 0
516 mcount = 0
517 mrevcount = 0
517 mrevcount = 0
518 msrcsize = 0
518 msrcsize = 0
519 mrawsize = 0
519 mrawsize = 0
520 mdstsize = 0
520 mdstsize = 0
521 crevcount = 0
521 crevcount = 0
522 csrcsize = 0
522 csrcsize = 0
523 crawsize = 0
523 crawsize = 0
524 cdstsize = 0
524 cdstsize = 0
525
525
526 # Perform a pass to collect metadata. This validates we can open all
526 # Perform a pass to collect metadata. This validates we can open all
527 # source files and allows a unified progress bar to be displayed.
527 # source files and allows a unified progress bar to be displayed.
528 for unencoded, encoded, size in srcrepo.store.walk():
528 for unencoded, encoded, size in srcrepo.store.walk():
529 if unencoded.endswith('.d'):
529 if unencoded.endswith('.d'):
530 continue
530 continue
531
531
532 rl = _revlogfrompath(srcrepo, unencoded)
532 rl = _revlogfrompath(srcrepo, unencoded)
533
533
534 info = rl.storageinfo(exclusivefiles=True, revisionscount=True,
534 info = rl.storageinfo(exclusivefiles=True, revisionscount=True,
535 trackedsize=True, storedsize=True)
535 trackedsize=True, storedsize=True)
536
536
537 revcount += info['revisionscount'] or 0
537 revcount += info['revisionscount'] or 0
538 datasize = info['storedsize'] or 0
538 datasize = info['storedsize'] or 0
539 rawsize = info['trackedsize'] or 0
539 rawsize = info['trackedsize'] or 0
540
540
541 srcsize += datasize
541 srcsize += datasize
542 srcrawsize += rawsize
542 srcrawsize += rawsize
543
543
544 # This is for the separate progress bars.
544 # This is for the separate progress bars.
545 if isinstance(rl, changelog.changelog):
545 if isinstance(rl, changelog.changelog):
546 crevcount += len(rl)
546 crevcount += len(rl)
547 csrcsize += datasize
547 csrcsize += datasize
548 crawsize += rawsize
548 crawsize += rawsize
549 elif isinstance(rl, manifest.manifestrevlog):
549 elif isinstance(rl, manifest.manifestrevlog):
550 mcount += 1
550 mcount += 1
551 mrevcount += len(rl)
551 mrevcount += len(rl)
552 msrcsize += datasize
552 msrcsize += datasize
553 mrawsize += rawsize
553 mrawsize += rawsize
554 elif isinstance(rl, filelog.filelog):
554 elif isinstance(rl, filelog.filelog):
555 fcount += 1
555 fcount += 1
556 frevcount += len(rl)
556 frevcount += len(rl)
557 fsrcsize += datasize
557 fsrcsize += datasize
558 frawsize += rawsize
558 frawsize += rawsize
559 else:
559 else:
560 error.ProgrammingError('unknown revlog type')
560 error.ProgrammingError('unknown revlog type')
561
561
562 if not revcount:
562 if not revcount:
563 return
563 return
564
564
565 ui.write(_('migrating %d total revisions (%d in filelogs, %d in manifests, '
565 ui.write(_('migrating %d total revisions (%d in filelogs, %d in manifests, '
566 '%d in changelog)\n') %
566 '%d in changelog)\n') %
567 (revcount, frevcount, mrevcount, crevcount))
567 (revcount, frevcount, mrevcount, crevcount))
568 ui.write(_('migrating %s in store; %s tracked data\n') % (
568 ui.write(_('migrating %s in store; %s tracked data\n') % (
569 (util.bytecount(srcsize), util.bytecount(srcrawsize))))
569 (util.bytecount(srcsize), util.bytecount(srcrawsize))))
570
570
571 # Used to keep track of progress.
571 # Used to keep track of progress.
572 progress = None
572 progress = None
573 def oncopiedrevision(rl, rev, node):
573 def oncopiedrevision(rl, rev, node):
574 progress.increment()
574 progress.increment()
575
575
576 # Do the actual copying.
576 # Do the actual copying.
577 # FUTURE this operation can be farmed off to worker processes.
577 # FUTURE this operation can be farmed off to worker processes.
578 seen = set()
578 seen = set()
579 for unencoded, encoded, size in srcrepo.store.walk():
579 for unencoded, encoded, size in srcrepo.store.walk():
580 if unencoded.endswith('.d'):
580 if unencoded.endswith('.d'):
581 continue
581 continue
582
582
583 oldrl = _revlogfrompath(srcrepo, unencoded)
583 oldrl = _revlogfrompath(srcrepo, unencoded)
584 newrl = _revlogfrompath(dstrepo, unencoded)
584 newrl = _revlogfrompath(dstrepo, unencoded)
585
585
586 if isinstance(oldrl, changelog.changelog) and 'c' not in seen:
586 if isinstance(oldrl, changelog.changelog) and 'c' not in seen:
587 ui.write(_('finished migrating %d manifest revisions across %d '
587 ui.write(_('finished migrating %d manifest revisions across %d '
588 'manifests; change in size: %s\n') %
588 'manifests; change in size: %s\n') %
589 (mrevcount, mcount, util.bytecount(mdstsize - msrcsize)))
589 (mrevcount, mcount, util.bytecount(mdstsize - msrcsize)))
590
590
591 ui.write(_('migrating changelog containing %d revisions '
591 ui.write(_('migrating changelog containing %d revisions '
592 '(%s in store; %s tracked data)\n') %
592 '(%s in store; %s tracked data)\n') %
593 (crevcount, util.bytecount(csrcsize),
593 (crevcount, util.bytecount(csrcsize),
594 util.bytecount(crawsize)))
594 util.bytecount(crawsize)))
595 seen.add('c')
595 seen.add('c')
596 progress = srcrepo.ui.makeprogress(_('changelog revisions'),
596 progress = srcrepo.ui.makeprogress(_('changelog revisions'),
597 total=crevcount)
597 total=crevcount)
598 elif isinstance(oldrl, manifest.manifestrevlog) and 'm' not in seen:
598 elif isinstance(oldrl, manifest.manifestrevlog) and 'm' not in seen:
599 ui.write(_('finished migrating %d filelog revisions across %d '
599 ui.write(_('finished migrating %d filelog revisions across %d '
600 'filelogs; change in size: %s\n') %
600 'filelogs; change in size: %s\n') %
601 (frevcount, fcount, util.bytecount(fdstsize - fsrcsize)))
601 (frevcount, fcount, util.bytecount(fdstsize - fsrcsize)))
602
602
603 ui.write(_('migrating %d manifests containing %d revisions '
603 ui.write(_('migrating %d manifests containing %d revisions '
604 '(%s in store; %s tracked data)\n') %
604 '(%s in store; %s tracked data)\n') %
605 (mcount, mrevcount, util.bytecount(msrcsize),
605 (mcount, mrevcount, util.bytecount(msrcsize),
606 util.bytecount(mrawsize)))
606 util.bytecount(mrawsize)))
607 seen.add('m')
607 seen.add('m')
608 if progress:
608 if progress:
609 progress.complete()
609 progress.complete()
610 progress = srcrepo.ui.makeprogress(_('manifest revisions'),
610 progress = srcrepo.ui.makeprogress(_('manifest revisions'),
611 total=mrevcount)
611 total=mrevcount)
612 elif 'f' not in seen:
612 elif 'f' not in seen:
613 ui.write(_('migrating %d filelogs containing %d revisions '
613 ui.write(_('migrating %d filelogs containing %d revisions '
614 '(%s in store; %s tracked data)\n') %
614 '(%s in store; %s tracked data)\n') %
615 (fcount, frevcount, util.bytecount(fsrcsize),
615 (fcount, frevcount, util.bytecount(fsrcsize),
616 util.bytecount(frawsize)))
616 util.bytecount(frawsize)))
617 seen.add('f')
617 seen.add('f')
618 if progress:
618 if progress:
619 progress.complete()
619 progress.complete()
620 progress = srcrepo.ui.makeprogress(_('file revisions'),
620 progress = srcrepo.ui.makeprogress(_('file revisions'),
621 total=frevcount)
621 total=frevcount)
622
622
623
623
624 ui.note(_('cloning %d revisions from %s\n') % (len(oldrl), unencoded))
624 ui.note(_('cloning %d revisions from %s\n') % (len(oldrl), unencoded))
625 oldrl.clone(tr, newrl, addrevisioncb=oncopiedrevision,
625 oldrl.clone(tr, newrl, addrevisioncb=oncopiedrevision,
626 deltareuse=deltareuse,
626 deltareuse=deltareuse,
627 forcedeltabothparents=forcedeltabothparents)
627 forcedeltabothparents=forcedeltabothparents)
628
628
629 info = newrl.storageinfo(storedsize=True)
629 info = newrl.storageinfo(storedsize=True)
630 datasize = info['storedsize'] or 0
630 datasize = info['storedsize'] or 0
631
631
632 dstsize += datasize
632 dstsize += datasize
633
633
634 if isinstance(newrl, changelog.changelog):
634 if isinstance(newrl, changelog.changelog):
635 cdstsize += datasize
635 cdstsize += datasize
636 elif isinstance(newrl, manifest.manifestrevlog):
636 elif isinstance(newrl, manifest.manifestrevlog):
637 mdstsize += datasize
637 mdstsize += datasize
638 else:
638 else:
639 fdstsize += datasize
639 fdstsize += datasize
640
640
641 progress.complete()
641 progress.complete()
642
642
643 ui.write(_('finished migrating %d changelog revisions; change in size: '
643 ui.write(_('finished migrating %d changelog revisions; change in size: '
644 '%s\n') % (crevcount, util.bytecount(cdstsize - csrcsize)))
644 '%s\n') % (crevcount, util.bytecount(cdstsize - csrcsize)))
645
645
646 ui.write(_('finished migrating %d total revisions; total change in store '
646 ui.write(_('finished migrating %d total revisions; total change in store '
647 'size: %s\n') % (revcount, util.bytecount(dstsize - srcsize)))
647 'size: %s\n') % (revcount, util.bytecount(dstsize - srcsize)))
648
648
649 def _filterstorefile(srcrepo, dstrepo, requirements, path, mode, st):
649 def _filterstorefile(srcrepo, dstrepo, requirements, path, mode, st):
650 """Determine whether to copy a store file during upgrade.
650 """Determine whether to copy a store file during upgrade.
651
651
652 This function is called when migrating store files from ``srcrepo`` to
652 This function is called when migrating store files from ``srcrepo`` to
653 ``dstrepo`` as part of upgrading a repository.
653 ``dstrepo`` as part of upgrading a repository.
654
654
655 Args:
655 Args:
656 srcrepo: repo we are copying from
656 srcrepo: repo we are copying from
657 dstrepo: repo we are copying to
657 dstrepo: repo we are copying to
658 requirements: set of requirements for ``dstrepo``
658 requirements: set of requirements for ``dstrepo``
659 path: store file being examined
659 path: store file being examined
660 mode: the ``ST_MODE`` file type of ``path``
660 mode: the ``ST_MODE`` file type of ``path``
661 st: ``stat`` data structure for ``path``
661 st: ``stat`` data structure for ``path``
662
662
663 Function should return ``True`` if the file is to be copied.
663 Function should return ``True`` if the file is to be copied.
664 """
664 """
665 # Skip revlogs.
665 # Skip revlogs.
666 if path.endswith(('.i', '.d')):
666 if path.endswith(('.i', '.d')):
667 return False
667 return False
668 # Skip transaction related files.
668 # Skip transaction related files.
669 if path.startswith('undo'):
669 if path.startswith('undo'):
670 return False
670 return False
671 # Only copy regular files.
671 # Only copy regular files.
672 if mode != stat.S_IFREG:
672 if mode != stat.S_IFREG:
673 return False
673 return False
674 # Skip other skipped files.
674 # Skip other skipped files.
675 if path in ('lock', 'fncache'):
675 if path in ('lock', 'fncache'):
676 return False
676 return False
677
677
678 return True
678 return True
679
679
680 def _finishdatamigration(ui, srcrepo, dstrepo, requirements):
680 def _finishdatamigration(ui, srcrepo, dstrepo, requirements):
681 """Hook point for extensions to perform additional actions during upgrade.
681 """Hook point for extensions to perform additional actions during upgrade.
682
682
683 This function is called after revlogs and store files have been copied but
683 This function is called after revlogs and store files have been copied but
684 before the new store is swapped into the original location.
684 before the new store is swapped into the original location.
685 """
685 """
686
686
687 def _upgraderepo(ui, srcrepo, dstrepo, requirements, actions):
687 def _upgraderepo(ui, srcrepo, dstrepo, requirements, actions):
688 """Do the low-level work of upgrading a repository.
688 """Do the low-level work of upgrading a repository.
689
689
690 The upgrade is effectively performed as a copy between a source
690 The upgrade is effectively performed as a copy between a source
691 repository and a temporary destination repository.
691 repository and a temporary destination repository.
692
692
693 The source repository is unmodified for as long as possible so the
693 The source repository is unmodified for as long as possible so the
694 upgrade can abort at any time without causing loss of service for
694 upgrade can abort at any time without causing loss of service for
695 readers and without corrupting the source repository.
695 readers and without corrupting the source repository.
696 """
696 """
697 assert srcrepo.currentwlock()
697 assert srcrepo.currentwlock()
698 assert dstrepo.currentwlock()
698 assert dstrepo.currentwlock()
699
699
700 ui.write(_('(it is safe to interrupt this process any time before '
700 ui.write(_('(it is safe to interrupt this process any time before '
701 'data migration completes)\n'))
701 'data migration completes)\n'))
702
702
703 if 're-delta-all' in actions:
703 if 're-delta-all' in actions:
704 deltareuse = revlog.revlog.DELTAREUSENEVER
704 deltareuse = revlog.revlog.DELTAREUSENEVER
705 elif 're-delta-parent' in actions:
705 elif 're-delta-parent' in actions:
706 deltareuse = revlog.revlog.DELTAREUSESAMEREVS
706 deltareuse = revlog.revlog.DELTAREUSESAMEREVS
707 elif 're-delta-multibase' in actions:
707 elif 're-delta-multibase' in actions:
708 deltareuse = revlog.revlog.DELTAREUSESAMEREVS
708 deltareuse = revlog.revlog.DELTAREUSESAMEREVS
709 elif 're-delta-fulladd' in actions:
709 elif 're-delta-fulladd' in actions:
710 deltareuse = revlog.revlog.DELTAREUSEFULLADD
710 deltareuse = revlog.revlog.DELTAREUSEFULLADD
711 else:
711 else:
712 deltareuse = revlog.revlog.DELTAREUSEALWAYS
712 deltareuse = revlog.revlog.DELTAREUSEALWAYS
713
713
714 with dstrepo.transaction('upgrade') as tr:
714 with dstrepo.transaction('upgrade') as tr:
715 _copyrevlogs(ui, srcrepo, dstrepo, tr, deltareuse,
715 _copyrevlogs(ui, srcrepo, dstrepo, tr, deltareuse,
716 're-delta-multibase' in actions)
716 're-delta-multibase' in actions)
717
717
718 # Now copy other files in the store directory.
718 # Now copy other files in the store directory.
719 # The sorted() makes execution deterministic.
719 # The sorted() makes execution deterministic.
720 for p, kind, st in sorted(srcrepo.store.vfs.readdir('', stat=True)):
720 for p, kind, st in sorted(srcrepo.store.vfs.readdir('', stat=True)):
721 if not _filterstorefile(srcrepo, dstrepo, requirements,
721 if not _filterstorefile(srcrepo, dstrepo, requirements,
722 p, kind, st):
722 p, kind, st):
723 continue
723 continue
724
724
725 srcrepo.ui.write(_('copying %s\n') % p)
725 srcrepo.ui.write(_('copying %s\n') % p)
726 src = srcrepo.store.rawvfs.join(p)
726 src = srcrepo.store.rawvfs.join(p)
727 dst = dstrepo.store.rawvfs.join(p)
727 dst = dstrepo.store.rawvfs.join(p)
728 util.copyfile(src, dst, copystat=True)
728 util.copyfile(src, dst, copystat=True)
729
729
730 _finishdatamigration(ui, srcrepo, dstrepo, requirements)
730 _finishdatamigration(ui, srcrepo, dstrepo, requirements)
731
731
732 ui.write(_('data fully migrated to temporary repository\n'))
732 ui.write(_('data fully migrated to temporary repository\n'))
733
733
734 backuppath = pycompat.mkdtemp(prefix='upgradebackup.', dir=srcrepo.path)
734 backuppath = pycompat.mkdtemp(prefix='upgradebackup.', dir=srcrepo.path)
735 backupvfs = vfsmod.vfs(backuppath)
735 backupvfs = vfsmod.vfs(backuppath)
736
736
737 # Make a backup of requires file first, as it is the first to be modified.
737 # Make a backup of requires file first, as it is the first to be modified.
738 util.copyfile(srcrepo.vfs.join('requires'), backupvfs.join('requires'))
738 util.copyfile(srcrepo.vfs.join('requires'), backupvfs.join('requires'))
739
739
740 # We install an arbitrary requirement that clients must not support
740 # We install an arbitrary requirement that clients must not support
741 # as a mechanism to lock out new clients during the data swap. This is
741 # as a mechanism to lock out new clients during the data swap. This is
742 # better than allowing a client to continue while the repository is in
742 # better than allowing a client to continue while the repository is in
743 # an inconsistent state.
743 # an inconsistent state.
744 ui.write(_('marking source repository as being upgraded; clients will be '
744 ui.write(_('marking source repository as being upgraded; clients will be '
745 'unable to read from repository\n'))
745 'unable to read from repository\n'))
746 scmutil.writerequires(srcrepo.vfs,
746 scmutil.writerequires(srcrepo.vfs,
747 srcrepo.requirements | {'upgradeinprogress'})
747 srcrepo.requirements | {'upgradeinprogress'})
748
748
749 ui.write(_('starting in-place swap of repository data\n'))
749 ui.write(_('starting in-place swap of repository data\n'))
750 ui.write(_('replaced files will be backed up at %s\n') %
750 ui.write(_('replaced files will be backed up at %s\n') %
751 backuppath)
751 backuppath)
752
752
753 # Now swap in the new store directory. Doing it as a rename should make
753 # Now swap in the new store directory. Doing it as a rename should make
754 # the operation nearly instantaneous and atomic (at least in well-behaved
754 # the operation nearly instantaneous and atomic (at least in well-behaved
755 # environments).
755 # environments).
756 ui.write(_('replacing store...\n'))
756 ui.write(_('replacing store...\n'))
757 tstart = util.timer()
757 tstart = util.timer()
758 util.rename(srcrepo.spath, backupvfs.join('store'))
758 util.rename(srcrepo.spath, backupvfs.join('store'))
759 util.rename(dstrepo.spath, srcrepo.spath)
759 util.rename(dstrepo.spath, srcrepo.spath)
760 elapsed = util.timer() - tstart
760 elapsed = util.timer() - tstart
761 ui.write(_('store replacement complete; repository was inconsistent for '
761 ui.write(_('store replacement complete; repository was inconsistent for '
762 '%0.1fs\n') % elapsed)
762 '%0.1fs\n') % elapsed)
763
763
764 # We first write the requirements file. Any new requirements will lock
764 # We first write the requirements file. Any new requirements will lock
765 # out legacy clients.
765 # out legacy clients.
766 ui.write(_('finalizing requirements file and making repository readable '
766 ui.write(_('finalizing requirements file and making repository readable '
767 'again\n'))
767 'again\n'))
768 scmutil.writerequires(srcrepo.vfs, requirements)
768 scmutil.writerequires(srcrepo.vfs, requirements)
769
769
770 # The lock file from the old store won't be removed because nothing has a
770 # The lock file from the old store won't be removed because nothing has a
771 # reference to its new location. So clean it up manually. Alternatively, we
771 # reference to its new location. So clean it up manually. Alternatively, we
772 # could update srcrepo.svfs and other variables to point to the new
772 # could update srcrepo.svfs and other variables to point to the new
773 # location. This is simpler.
773 # location. This is simpler.
774 backupvfs.unlink('store/lock')
774 backupvfs.unlink('store/lock')
775
775
776 return backuppath
776 return backuppath
777
777
778 def upgraderepo(ui, repo, run=False, optimize=None, backup=True):
778 def upgraderepo(ui, repo, run=False, optimize=None, backup=True):
779 """Upgrade a repository in place."""
779 """Upgrade a repository in place."""
780 if optimize is None:
780 if optimize is None:
781 optimize = []
781 optimize = []
782 optimize = set(legacy_opts_map.get(o, o) for o in optimize)
782 optimize = set(legacy_opts_map.get(o, o) for o in optimize)
783 repo = repo.unfiltered()
783 repo = repo.unfiltered()
784
784
785 # Ensure the repository can be upgraded.
785 # Ensure the repository can be upgraded.
786 missingreqs = requiredsourcerequirements(repo) - repo.requirements
786 missingreqs = requiredsourcerequirements(repo) - repo.requirements
787 if missingreqs:
787 if missingreqs:
788 raise error.Abort(_('cannot upgrade repository; requirement '
788 raise error.Abort(_('cannot upgrade repository; requirement '
789 'missing: %s') % _(', ').join(sorted(missingreqs)))
789 'missing: %s') % _(', ').join(sorted(missingreqs)))
790
790
791 blockedreqs = blocksourcerequirements(repo) & repo.requirements
791 blockedreqs = blocksourcerequirements(repo) & repo.requirements
792 if blockedreqs:
792 if blockedreqs:
793 raise error.Abort(_('cannot upgrade repository; unsupported source '
793 raise error.Abort(_('cannot upgrade repository; unsupported source '
794 'requirement: %s') %
794 'requirement: %s') %
795 _(', ').join(sorted(blockedreqs)))
795 _(', ').join(sorted(blockedreqs)))
796
796
797 # FUTURE there is potentially a need to control the wanted requirements via
797 # FUTURE there is potentially a need to control the wanted requirements via
798 # command arguments or via an extension hook point.
798 # command arguments or via an extension hook point.
799 newreqs = localrepo.newreporequirements(
799 newreqs = localrepo.newreporequirements(
800 repo.ui, localrepo.defaultcreateopts(repo.ui))
800 repo.ui, localrepo.defaultcreateopts(repo.ui))
801 newreqs.update(preservedrequirements(repo))
801 newreqs.update(preservedrequirements(repo))
802
802
803 noremovereqs = (repo.requirements - newreqs -
803 noremovereqs = (repo.requirements - newreqs -
804 supportremovedrequirements(repo))
804 supportremovedrequirements(repo))
805 if noremovereqs:
805 if noremovereqs:
806 raise error.Abort(_('cannot upgrade repository; requirement would be '
806 raise error.Abort(_('cannot upgrade repository; requirement would be '
807 'removed: %s') % _(', ').join(sorted(noremovereqs)))
807 'removed: %s') % _(', ').join(sorted(noremovereqs)))
808
808
809 noaddreqs = (newreqs - repo.requirements -
809 noaddreqs = (newreqs - repo.requirements -
810 allowednewrequirements(repo))
810 allowednewrequirements(repo))
811 if noaddreqs:
811 if noaddreqs:
812 raise error.Abort(_('cannot upgrade repository; do not support adding '
812 raise error.Abort(_('cannot upgrade repository; do not support adding '
813 'requirement: %s') %
813 'requirement: %s') %
814 _(', ').join(sorted(noaddreqs)))
814 _(', ').join(sorted(noaddreqs)))
815
815
816 unsupportedreqs = newreqs - supporteddestrequirements(repo)
816 unsupportedreqs = newreqs - supporteddestrequirements(repo)
817 if unsupportedreqs:
817 if unsupportedreqs:
818 raise error.Abort(_('cannot upgrade repository; do not support '
818 raise error.Abort(_('cannot upgrade repository; do not support '
819 'destination requirement: %s') %
819 'destination requirement: %s') %
820 _(', ').join(sorted(unsupportedreqs)))
820 _(', ').join(sorted(unsupportedreqs)))
821
821
822 # Find and validate all improvements that can be made.
822 # Find and validate all improvements that can be made.
823 alloptimizations = findoptimizations(repo)
823 alloptimizations = findoptimizations(repo)
824
824
825 # Apply and Validate arguments.
825 # Apply and Validate arguments.
826 optimizations = []
826 optimizations = []
827 for o in alloptimizations:
827 for o in alloptimizations:
828 if o.name in optimize:
828 if o.name in optimize:
829 optimizations.append(o)
829 optimizations.append(o)
830 optimize.discard(o.name)
830 optimize.discard(o.name)
831
831
832 if optimize: # anything left is unknown
832 if optimize: # anything left is unknown
833 raise error.Abort(_('unknown optimization action requested: %s') %
833 raise error.Abort(_('unknown optimization action requested: %s') %
834 ', '.join(sorted(optimize)),
834 ', '.join(sorted(optimize)),
835 hint=_('run without arguments to see valid '
835 hint=_('run without arguments to see valid '
836 'optimizations'))
836 'optimizations'))
837
837
838 deficiencies = finddeficiencies(repo)
838 deficiencies = finddeficiencies(repo)
839 actions = determineactions(repo, deficiencies, repo.requirements, newreqs)
839 actions = determineactions(repo, deficiencies, repo.requirements, newreqs)
840 actions.extend(o for o in sorted(optimizations)
840 actions.extend(o for o in sorted(optimizations)
841 # determineactions could have added optimisation
841 # determineactions could have added optimisation
842 if o not in actions)
842 if o not in actions)
843
843
844 def printrequirements():
844 def printrequirements():
845 ui.write(_('requirements\n'))
845 ui.write(_('requirements\n'))
846 ui.write(_(' preserved: %s\n') %
846 ui.write(_(' preserved: %s\n') %
847 _(', ').join(sorted(newreqs & repo.requirements)))
847 _(', ').join(sorted(newreqs & repo.requirements)))
848
848
849 if repo.requirements - newreqs:
849 if repo.requirements - newreqs:
850 ui.write(_(' removed: %s\n') %
850 ui.write(_(' removed: %s\n') %
851 _(', ').join(sorted(repo.requirements - newreqs)))
851 _(', ').join(sorted(repo.requirements - newreqs)))
852
852
853 if newreqs - repo.requirements:
853 if newreqs - repo.requirements:
854 ui.write(_(' added: %s\n') %
854 ui.write(_(' added: %s\n') %
855 _(', ').join(sorted(newreqs - repo.requirements)))
855 _(', ').join(sorted(newreqs - repo.requirements)))
856
856
857 ui.write('\n')
857 ui.write('\n')
858
858
859 def printupgradeactions():
859 def printupgradeactions():
860 for a in actions:
860 for a in actions:
861 ui.write('%s\n %s\n\n' % (a.name, a.upgrademessage))
861 ui.write('%s\n %s\n\n' % (a.name, a.upgrademessage))
862
862
863 if not run:
863 if not run:
864 fromconfig = []
864 fromconfig = []
865 onlydefault = []
865 onlydefault = []
866
866
867 for d in deficiencies:
867 for d in deficiencies:
868 if d.fromconfig(repo):
868 if d.fromconfig(repo):
869 fromconfig.append(d)
869 fromconfig.append(d)
870 elif d.default:
870 elif d.default:
871 onlydefault.append(d)
871 onlydefault.append(d)
872
872
873 if fromconfig or onlydefault:
873 if fromconfig or onlydefault:
874
874
875 if fromconfig:
875 if fromconfig:
876 ui.write(_('repository lacks features recommended by '
876 ui.write(_('repository lacks features recommended by '
877 'current config options:\n\n'))
877 'current config options:\n\n'))
878 for i in fromconfig:
878 for i in fromconfig:
879 ui.write('%s\n %s\n\n' % (i.name, i.description))
879 ui.write('%s\n %s\n\n' % (i.name, i.description))
880
880
881 if onlydefault:
881 if onlydefault:
882 ui.write(_('repository lacks features used by the default '
882 ui.write(_('repository lacks features used by the default '
883 'config options:\n\n'))
883 'config options:\n\n'))
884 for i in onlydefault:
884 for i in onlydefault:
885 ui.write('%s\n %s\n\n' % (i.name, i.description))
885 ui.write('%s\n %s\n\n' % (i.name, i.description))
886
886
887 ui.write('\n')
887 ui.write('\n')
888 else:
888 else:
889 ui.write(_('(no feature deficiencies found in existing '
889 ui.write(_('(no feature deficiencies found in existing '
890 'repository)\n'))
890 'repository)\n'))
891
891
892 ui.write(_('performing an upgrade with "--run" will make the following '
892 ui.write(_('performing an upgrade with "--run" will make the following '
893 'changes:\n\n'))
893 'changes:\n\n'))
894
894
895 printrequirements()
895 printrequirements()
896 printupgradeactions()
896 printupgradeactions()
897
897
898 unusedoptimize = [i for i in alloptimizations if i not in actions]
898 unusedoptimize = [i for i in alloptimizations if i not in actions]
899
899
900 if unusedoptimize:
900 if unusedoptimize:
901 ui.write(_('additional optimizations are available by specifying '
901 ui.write(_('additional optimizations are available by specifying '
902 '"--optimize <name>":\n\n'))
902 '"--optimize <name>":\n\n'))
903 for i in unusedoptimize:
903 for i in unusedoptimize:
904 ui.write(_('%s\n %s\n\n') % (i.name, i.description))
904 ui.write(_('%s\n %s\n\n') % (i.name, i.description))
905 return
905 return
906
906
907 # Else we're in the run=true case.
907 # Else we're in the run=true case.
908 ui.write(_('upgrade will perform the following actions:\n\n'))
908 ui.write(_('upgrade will perform the following actions:\n\n'))
909 printrequirements()
909 printrequirements()
910 printupgradeactions()
910 printupgradeactions()
911
911
912 upgradeactions = [a.name for a in actions]
912 upgradeactions = [a.name for a in actions]
913
913
914 ui.write(_('beginning upgrade...\n'))
914 ui.write(_('beginning upgrade...\n'))
915 with repo.wlock(), repo.lock():
915 with repo.wlock(), repo.lock():
916 ui.write(_('repository locked and read-only\n'))
916 ui.write(_('repository locked and read-only\n'))
917 # Our strategy for upgrading the repository is to create a new,
917 # Our strategy for upgrading the repository is to create a new,
918 # temporary repository, write data to it, then do a swap of the
918 # temporary repository, write data to it, then do a swap of the
919 # data. There are less heavyweight ways to do this, but it is easier
919 # data. There are less heavyweight ways to do this, but it is easier
920 # to create a new repo object than to instantiate all the components
920 # to create a new repo object than to instantiate all the components
921 # (like the store) separately.
921 # (like the store) separately.
922 tmppath = pycompat.mkdtemp(prefix='upgrade.', dir=repo.path)
922 tmppath = pycompat.mkdtemp(prefix='upgrade.', dir=repo.path)
923 backuppath = None
923 backuppath = None
924 try:
924 try:
925 ui.write(_('creating temporary repository to stage migrated '
925 ui.write(_('creating temporary repository to stage migrated '
926 'data: %s\n') % tmppath)
926 'data: %s\n') % tmppath)
927
927
928 # clone ui without using ui.copy because repo.ui is protected
928 # clone ui without using ui.copy because repo.ui is protected
929 repoui = repo.ui.__class__(repo.ui)
929 repoui = repo.ui.__class__(repo.ui)
930 dstrepo = hg.repository(repoui, path=tmppath, create=True)
930 dstrepo = hg.repository(repoui, path=tmppath, create=True)
931
931
932 with dstrepo.wlock(), dstrepo.lock():
932 with dstrepo.wlock(), dstrepo.lock():
933 backuppath = _upgraderepo(ui, repo, dstrepo, newreqs,
933 backuppath = _upgraderepo(ui, repo, dstrepo, newreqs,
934 upgradeactions)
934 upgradeactions)
935 if not (backup or backuppath is None):
935 if not (backup or backuppath is None):
936 ui.write(_('removing old repository content%s\n') % backuppath)
936 ui.write(_('removing old repository content%s\n') % backuppath)
937 repo.vfs.rmtree(backuppath, forcibly=True)
937 repo.vfs.rmtree(backuppath, forcibly=True)
938 backuppath = None
938 backuppath = None
939
939
940 finally:
940 finally:
941 ui.write(_('removing temporary repository %s\n') % tmppath)
941 ui.write(_('removing temporary repository %s\n') % tmppath)
942 repo.vfs.rmtree(tmppath, forcibly=True)
942 repo.vfs.rmtree(tmppath, forcibly=True)
943
943
944 if backuppath:
944 if backuppath:
945 ui.warn(_('copy of old repository backed up at %s\n') %
945 ui.warn(_('copy of old repository backed up at %s\n') %
946 backuppath)
946 backuppath)
947 ui.warn(_('the old repository will not be deleted; remove '
947 ui.warn(_('the old repository will not be deleted; remove '
948 'it to free up disk space once the upgraded '
948 'it to free up disk space once the upgraded '
949 'repository is verified\n'))
949 'repository is verified\n'))
@@ -1,195 +1,195 b''
1 A new repository uses zlib storage, which doesn't need a requirement
1 A new repository uses zlib storage, which doesn't need a requirement
2
2
3 $ hg init default
3 $ hg init default
4 $ cd default
4 $ cd default
5 $ cat .hg/requires
5 $ cat .hg/requires
6 dotencode
6 dotencode
7 fncache
7 fncache
8 generaldelta
8 generaldelta
9 revlogv1
9 revlogv1
10 sparserevlog
10 sparserevlog
11 store
11 store
12 testonly-simplestore (reposimplestore !)
12 testonly-simplestore (reposimplestore !)
13
13
14 $ touch foo
14 $ touch foo
15 $ hg -q commit -A -m 'initial commit with a lot of repeated repeated repeated text to trigger compression'
15 $ hg -q commit -A -m 'initial commit with a lot of repeated repeated repeated text to trigger compression'
16 $ hg debugrevlog -c | grep 0x78
16 $ hg debugrevlog -c | grep 0x78
17 0x78 (x) : 1 (100.00%)
17 0x78 (x) : 1 (100.00%)
18 0x78 (x) : 110 (100.00%)
18 0x78 (x) : 110 (100.00%)
19
19
20 $ cd ..
20 $ cd ..
21
21
22 Unknown compression engine to format.compression aborts
22 Unknown compression engine to format.compression aborts
23
23
24 $ hg --config experimental.format.compression=unknown init unknown
24 $ hg --config format.revlog-compression=unknown init unknown
25 abort: compression engine unknown defined by experimental.format.compression not available
25 abort: compression engine unknown defined by format.revlog-compression not available
26 (run "hg debuginstall" to list available compression engines)
26 (run "hg debuginstall" to list available compression engines)
27 [255]
27 [255]
28
28
29 A requirement specifying an unknown compression engine results in bail
29 A requirement specifying an unknown compression engine results in bail
30
30
31 $ hg init unknownrequirement
31 $ hg init unknownrequirement
32 $ cd unknownrequirement
32 $ cd unknownrequirement
33 $ echo exp-compression-unknown >> .hg/requires
33 $ echo exp-compression-unknown >> .hg/requires
34 $ hg log
34 $ hg log
35 abort: repository requires features unknown to this Mercurial: exp-compression-unknown!
35 abort: repository requires features unknown to this Mercurial: exp-compression-unknown!
36 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
36 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
37 [255]
37 [255]
38
38
39 $ cd ..
39 $ cd ..
40
40
41 #if zstd
41 #if zstd
42
42
43 $ hg --config experimental.format.compression=zstd init zstd
43 $ hg --config format.revlog-compression=zstd init zstd
44 $ cd zstd
44 $ cd zstd
45 $ cat .hg/requires
45 $ cat .hg/requires
46 dotencode
46 dotencode
47 exp-compression-zstd
47 exp-compression-zstd
48 fncache
48 fncache
49 generaldelta
49 generaldelta
50 revlogv1
50 revlogv1
51 sparserevlog
51 sparserevlog
52 store
52 store
53 testonly-simplestore (reposimplestore !)
53 testonly-simplestore (reposimplestore !)
54
54
55 $ touch foo
55 $ touch foo
56 $ hg -q commit -A -m 'initial commit with a lot of repeated repeated repeated text'
56 $ hg -q commit -A -m 'initial commit with a lot of repeated repeated repeated text'
57
57
58 $ hg debugrevlog -c | grep 0x28
58 $ hg debugrevlog -c | grep 0x28
59 0x28 : 1 (100.00%)
59 0x28 : 1 (100.00%)
60 0x28 : 98 (100.00%)
60 0x28 : 98 (100.00%)
61
61
62 $ cd ..
62 $ cd ..
63
63
64 Specifying a new format.compression on an existing repo won't introduce data
64 Specifying a new format.compression on an existing repo won't introduce data
65 with that engine or a requirement
65 with that engine or a requirement
66
66
67 $ cd default
67 $ cd default
68 $ touch bar
68 $ touch bar
69 $ hg --config experimental.format.compression=zstd -q commit -A -m 'add bar with a lot of repeated repeated repeated text'
69 $ hg --config format.revlog-compression=zstd -q commit -A -m 'add bar with a lot of repeated repeated repeated text'
70
70
71 $ cat .hg/requires
71 $ cat .hg/requires
72 dotencode
72 dotencode
73 fncache
73 fncache
74 generaldelta
74 generaldelta
75 revlogv1
75 revlogv1
76 sparserevlog
76 sparserevlog
77 store
77 store
78 testonly-simplestore (reposimplestore !)
78 testonly-simplestore (reposimplestore !)
79
79
80 $ hg debugrevlog -c | grep 0x78
80 $ hg debugrevlog -c | grep 0x78
81 0x78 (x) : 2 (100.00%)
81 0x78 (x) : 2 (100.00%)
82 0x78 (x) : 199 (100.00%)
82 0x78 (x) : 199 (100.00%)
83
83
84 #endif
84 #endif
85
85
86 checking zlib options
86 checking zlib options
87 =====================
87 =====================
88
88
89 $ hg init zlib-level-default
89 $ hg init zlib-level-default
90 $ hg init zlib-level-1
90 $ hg init zlib-level-1
91 $ cat << EOF >> zlib-level-1/.hg/hgrc
91 $ cat << EOF >> zlib-level-1/.hg/hgrc
92 > [storage]
92 > [storage]
93 > revlog.zlib.level=1
93 > revlog.zlib.level=1
94 > EOF
94 > EOF
95 $ hg init zlib-level-9
95 $ hg init zlib-level-9
96 $ cat << EOF >> zlib-level-9/.hg/hgrc
96 $ cat << EOF >> zlib-level-9/.hg/hgrc
97 > [storage]
97 > [storage]
98 > revlog.zlib.level=9
98 > revlog.zlib.level=9
99 > EOF
99 > EOF
100
100
101
101
102 $ commitone() {
102 $ commitone() {
103 > repo=$1
103 > repo=$1
104 > cp $RUNTESTDIR/bundles/issue4438-r1.hg $repo/a
104 > cp $RUNTESTDIR/bundles/issue4438-r1.hg $repo/a
105 > hg -R $repo add $repo/a
105 > hg -R $repo add $repo/a
106 > hg -R $repo commit -m some-commit
106 > hg -R $repo commit -m some-commit
107 > }
107 > }
108
108
109 $ for repo in zlib-level-default zlib-level-1 zlib-level-9; do
109 $ for repo in zlib-level-default zlib-level-1 zlib-level-9; do
110 > commitone $repo
110 > commitone $repo
111 > done
111 > done
112
112
113 $ $RUNTESTDIR/f -s */.hg/store/data/*
113 $ $RUNTESTDIR/f -s */.hg/store/data/*
114 zlib-level-1/.hg/store/data/a.i: size=4146
114 zlib-level-1/.hg/store/data/a.i: size=4146
115 zlib-level-9/.hg/store/data/a.i: size=4138
115 zlib-level-9/.hg/store/data/a.i: size=4138
116 zlib-level-default/.hg/store/data/a.i: size=4138
116 zlib-level-default/.hg/store/data/a.i: size=4138
117
117
118 Test error cases
118 Test error cases
119
119
120 $ hg init zlib-level-invalid
120 $ hg init zlib-level-invalid
121 $ cat << EOF >> zlib-level-invalid/.hg/hgrc
121 $ cat << EOF >> zlib-level-invalid/.hg/hgrc
122 > [storage]
122 > [storage]
123 > revlog.zlib.level=foobar
123 > revlog.zlib.level=foobar
124 > EOF
124 > EOF
125 $ commitone zlib-level-invalid
125 $ commitone zlib-level-invalid
126 abort: storage.revlog.zlib.level is not a valid integer ('foobar')
126 abort: storage.revlog.zlib.level is not a valid integer ('foobar')
127 abort: storage.revlog.zlib.level is not a valid integer ('foobar')
127 abort: storage.revlog.zlib.level is not a valid integer ('foobar')
128 [255]
128 [255]
129
129
130 $ hg init zlib-level-out-of-range
130 $ hg init zlib-level-out-of-range
131 $ cat << EOF >> zlib-level-out-of-range/.hg/hgrc
131 $ cat << EOF >> zlib-level-out-of-range/.hg/hgrc
132 > [storage]
132 > [storage]
133 > revlog.zlib.level=42
133 > revlog.zlib.level=42
134 > EOF
134 > EOF
135
135
136 $ commitone zlib-level-out-of-range
136 $ commitone zlib-level-out-of-range
137 abort: invalid value for `storage.revlog.zlib.level` config: 42
137 abort: invalid value for `storage.revlog.zlib.level` config: 42
138 abort: invalid value for `storage.revlog.zlib.level` config: 42
138 abort: invalid value for `storage.revlog.zlib.level` config: 42
139 [255]
139 [255]
140
140
141 checking zstd options
141 checking zstd options
142 =====================
142 =====================
143
143
144 $ hg init zstd-level-default --config experimental.format.compression=zstd
144 $ hg init zstd-level-default --config format.revlog-compression=zstd
145 $ hg init zstd-level-1 --config experimental.format.compression=zstd
145 $ hg init zstd-level-1 --config format.revlog-compression=zstd
146 $ cat << EOF >> zstd-level-1/.hg/hgrc
146 $ cat << EOF >> zstd-level-1/.hg/hgrc
147 > [storage]
147 > [storage]
148 > revlog.zstd.level=1
148 > revlog.zstd.level=1
149 > EOF
149 > EOF
150 $ hg init zstd-level-22 --config experimental.format.compression=zstd
150 $ hg init zstd-level-22 --config format.revlog-compression=zstd
151 $ cat << EOF >> zstd-level-22/.hg/hgrc
151 $ cat << EOF >> zstd-level-22/.hg/hgrc
152 > [storage]
152 > [storage]
153 > revlog.zstd.level=22
153 > revlog.zstd.level=22
154 > EOF
154 > EOF
155
155
156
156
157 $ commitone() {
157 $ commitone() {
158 > repo=$1
158 > repo=$1
159 > cp $RUNTESTDIR/bundles/issue4438-r1.hg $repo/a
159 > cp $RUNTESTDIR/bundles/issue4438-r1.hg $repo/a
160 > hg -R $repo add $repo/a
160 > hg -R $repo add $repo/a
161 > hg -R $repo commit -m some-commit
161 > hg -R $repo commit -m some-commit
162 > }
162 > }
163
163
164 $ for repo in zstd-level-default zstd-level-1 zstd-level-22; do
164 $ for repo in zstd-level-default zstd-level-1 zstd-level-22; do
165 > commitone $repo
165 > commitone $repo
166 > done
166 > done
167
167
168 $ $RUNTESTDIR/f -s zstd-*/.hg/store/data/*
168 $ $RUNTESTDIR/f -s zstd-*/.hg/store/data/*
169 zstd-level-1/.hg/store/data/a.i: size=4097
169 zstd-level-1/.hg/store/data/a.i: size=4097
170 zstd-level-22/.hg/store/data/a.i: size=4091
170 zstd-level-22/.hg/store/data/a.i: size=4091
171 zstd-level-default/.hg/store/data/a.i: size=4094
171 zstd-level-default/.hg/store/data/a.i: size=4094
172
172
173 Test error cases
173 Test error cases
174
174
175 $ hg init zstd-level-invalid --config experimental.format.compression=zstd
175 $ hg init zstd-level-invalid --config format.revlog-compression=zstd
176 $ cat << EOF >> zstd-level-invalid/.hg/hgrc
176 $ cat << EOF >> zstd-level-invalid/.hg/hgrc
177 > [storage]
177 > [storage]
178 > revlog.zstd.level=foobar
178 > revlog.zstd.level=foobar
179 > EOF
179 > EOF
180 $ commitone zstd-level-invalid
180 $ commitone zstd-level-invalid
181 abort: storage.revlog.zstd.level is not a valid integer ('foobar')
181 abort: storage.revlog.zstd.level is not a valid integer ('foobar')
182 abort: storage.revlog.zstd.level is not a valid integer ('foobar')
182 abort: storage.revlog.zstd.level is not a valid integer ('foobar')
183 [255]
183 [255]
184
184
185 $ hg init zstd-level-out-of-range --config experimental.format.compression=zstd
185 $ hg init zstd-level-out-of-range --config format.revlog-compression=zstd
186 $ cat << EOF >> zstd-level-out-of-range/.hg/hgrc
186 $ cat << EOF >> zstd-level-out-of-range/.hg/hgrc
187 > [storage]
187 > [storage]
188 > revlog.zstd.level=42
188 > revlog.zstd.level=42
189 > EOF
189 > EOF
190
190
191 $ commitone zstd-level-out-of-range
191 $ commitone zstd-level-out-of-range
192 abort: invalid value for `storage.revlog.zstd.level` config: 42
192 abort: invalid value for `storage.revlog.zstd.level` config: 42
193 abort: invalid value for `storage.revlog.zstd.level` config: 42
193 abort: invalid value for `storage.revlog.zstd.level` config: 42
194 [255]
194 [255]
195
195
General Comments 0
You need to be logged in to leave comments. Login now