##// END OF EJS Templates
admin-command: add verify command...
Raphaël Gomès -
r51882:752c5a5b default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,341 b''
1 # admin/verify.py - better repository integrity checking for Mercurial
2 #
3 # Copyright 2023 Octobus <contact@octobus.net>
4 #
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.
7
8 import collections
9 import copy
10 import functools
11
12 from ..i18n import _
13 from .. import error, pycompat, registrar, requirements
14 from ..utils import stringutil
15
16
17 verify_table = {}
18 verify_alias_table = {}
19 check = registrar.verify_check(verify_table, verify_alias_table)
20
21
22 # Use this to declare options/aliases in the middle of the hierarchy.
23 # Checks like these are not run themselves and cannot have a body.
24 # For an example, see the `revlogs` check.
25 def noop_func(*args, **kwargs):
26 return
27
28
29 @check(b"working-copy.dirstate", alias=b"dirstate")
30 def check_dirstate(ui, repo, **options):
31 ui.status(_(b"checking dirstate\n"))
32
33 parent1, parent2 = repo.dirstate.parents()
34 m1 = repo[parent1].manifest()
35 m2 = repo[parent2].manifest()
36 errors = 0
37
38 is_narrow = requirements.NARROW_REQUIREMENT in repo.requirements
39 narrow_matcher = repo.narrowmatch() if is_narrow else None
40
41 for err in repo.dirstate.verify(m1, m2, narrow_matcher):
42 ui.warn(err[0] % err[1:])
43 errors += 1
44
45 return errors
46
47
48 # Tree of all checks and their associated function
49 pyramid = {}
50
51
52 def build_pyramid(table, full_pyramid):
53 """Create a pyramid of checks of the registered checks.
54 It is a name-based hierarchy that can be arbitrarily nested."""
55 for entry, func in sorted(table.items(), key=lambda x: x[0], reverse=True):
56 cursor = full_pyramid
57 levels = entry.split(b".")
58 for level in levels[:-1]:
59 current_node = cursor.setdefault(level, {})
60 cursor = current_node
61 if cursor.get(levels[-1]) is None:
62 cursor[levels[-1]] = (entry, func)
63 elif func is not noop_func:
64 m = b"intermediate checks need to use `verify.noop_func`"
65 raise error.ProgrammingError(m)
66
67
68 def find_checks(name, table=None, alias_table=None, full_pyramid=None):
69 """Find all checks for a given name and returns a dict of
70 (qualified_check_name, check_function)
71
72 # Examples
73
74 Using a full qualified name:
75 "working-copy.dirstate" -> {
76 "working-copy.dirstate": CF,
77 }
78
79 Using a *prefix* of a qualified name:
80 "store.revlogs" -> {
81 "store.revlogs.changelog": CF,
82 "store.revlogs.manifestlog": CF,
83 "store.revlogs.filelog": CF,
84 }
85
86 Using a defined alias:
87 "revlogs" -> {
88 "store.revlogs.changelog": CF,
89 "store.revlogs.manifestlog": CF,
90 "store.revlogs.filelog": CF,
91 }
92
93 Using something that is none of the above will be an error.
94 """
95 if table is None:
96 table = verify_table
97 if alias_table is None:
98 alias_table = verify_alias_table
99
100 if name == b"full":
101 return table
102 checks = {}
103
104 # is it a full name?
105 check = table.get(name)
106
107 if check is None:
108 # is it an alias?
109 qualified_name = alias_table.get(name)
110 if qualified_name is not None:
111 name = qualified_name
112 check = table.get(name)
113 else:
114 split = name.split(b".", 1)
115 if len(split) == 2:
116 # split[0] can be an alias
117 qualified_name = alias_table.get(split[0])
118 if qualified_name is not None:
119 name = b"%s.%s" % (qualified_name, split[1])
120 check = table.get(name)
121 else:
122 qualified_name = name
123
124 # Maybe it's a subtree in the check hierarchy that does not
125 # have an explicit alias.
126 levels = name.split(b".")
127 if full_pyramid is not None:
128 if not full_pyramid:
129 build_pyramid(table, full_pyramid)
130
131 pyramid.clear()
132 pyramid.update(full_pyramid.items())
133 else:
134 build_pyramid(table, pyramid)
135
136 subtree = pyramid
137 # Find subtree
138 for level in levels:
139 subtree = subtree.get(level)
140 if subtree is None:
141 hint = error.getsimilar(list(alias_table) + list(table), name)
142 hint = error.similarity_hint(hint)
143
144 raise error.InputError(_(b"unknown check %s" % name), hint=hint)
145
146 # Get all checks in that subtree
147 if isinstance(subtree, dict):
148 stack = list(subtree.items())
149 while stack:
150 current_name, entry = stack.pop()
151 if isinstance(entry, dict):
152 stack.extend(entry.items())
153 else:
154 # (qualified_name, func)
155 checks[entry[0]] = entry[1]
156 else:
157 checks[name] = check
158
159 return checks
160
161
162 def pass_options(
163 ui,
164 checks,
165 options,
166 table=None,
167 alias_table=None,
168 full_pyramid=None,
169 ):
170 """Given a dict of checks (fully qualified name to function), and a list
171 of options as given by the user, pass each option down to the right check
172 function."""
173 ui.debug(b"passing options to check functions\n")
174 to_modify = collections.defaultdict(dict)
175
176 if not checks:
177 raise error.Error(_(b"`checks` required"))
178
179 for option in sorted(options):
180 split = option.split(b":")
181 hint = _(
182 b"syntax is 'check:option=value', "
183 b"eg. revlogs.changelog:copies=yes"
184 )
185 option_error = error.InputError(
186 _(b"invalid option '%s'") % option, hint=hint
187 )
188 if len(split) != 2:
189 raise option_error
190
191 check_name, option_value = split
192 if not option_value:
193 raise option_error
194
195 split = option_value.split(b"=")
196 if len(split) != 2:
197 raise option_error
198
199 option_name, value = split
200 if not value:
201 raise option_error
202
203 path = b"%s:%s" % (check_name, option_name)
204
205 matching_checks = find_checks(
206 check_name,
207 table=table,
208 alias_table=alias_table,
209 full_pyramid=full_pyramid,
210 )
211 for name in matching_checks:
212 check = checks.get(name)
213 if check is None:
214 msg = _(b"specified option '%s' for unselected check '%s'\n")
215 raise error.InputError(msg % (name, option_name))
216
217 assert hasattr(check, "func") # help Pytype
218
219 if not hasattr(check.func, "options"):
220 raise error.InputError(
221 _(b"check '%s' has no option '%s'") % (name, option_name)
222 )
223
224 try:
225 matching_option = next(
226 (o for o in check.func.options if o[0] == option_name)
227 )
228 except StopIteration:
229 raise error.InputError(
230 _(b"check '%s' has no option '%s'") % (name, option_name)
231 )
232
233 # transform the argument from cli string to the expected Python type
234 _name, typ, _docstring = matching_option
235
236 as_typed = None
237 if isinstance(typ, bool):
238 as_bool = stringutil.parsebool(value)
239 if as_bool is None:
240 raise error.InputError(
241 _(b"'%s' is not a boolean ('%s')") % (path, value)
242 )
243 as_typed = as_bool
244 elif isinstance(typ, list):
245 as_list = stringutil.parselist(value)
246 if as_list is None:
247 raise error.InputError(
248 _(b"'%s' is not a list ('%s')") % (path, value)
249 )
250 as_typed = as_list
251 else:
252 raise error.ProgrammingError(b"unsupported type %s", type(typ))
253
254 if option_name in to_modify[name]:
255 raise error.InputError(
256 _(b"duplicated option '%s' for '%s'") % (option_name, name)
257 )
258 else:
259 assert as_typed is not None
260 to_modify[name][option_name] = as_typed
261
262 # Manage case where a check is set but without command line options
263 # it will later be set with default check options values
264 for name, f in checks.items():
265 if name not in to_modify:
266 to_modify[name] = {}
267
268 # Merge default options with command line options
269 for check_name, cmd_options in to_modify.items():
270 check = checks.get(check_name)
271 func = checks[check_name]
272 merged_options = {}
273 # help Pytype
274 assert check is not None
275 assert check.func is not None
276 assert hasattr(check.func, "options")
277
278 if check.func.options:
279 # copy the default value in case it's mutable (list, etc.)
280 merged_options = {
281 o[0]: copy.deepcopy(o[1]) for o in check.func.options
282 }
283 if cmd_options:
284 for k, v in cmd_options.items():
285 merged_options[k] = v
286 options = pycompat.strkwargs(merged_options)
287 checks[check_name] = functools.partial(func, **options)
288 ui.debug(b"merged options for '%s': '%r'\n" % (check_name, options))
289
290 return checks
291
292
293 def get_checks(
294 repo,
295 ui,
296 names=None,
297 options=None,
298 table=None,
299 alias_table=None,
300 full_pyramid=None,
301 ):
302 """Given a list of function names and optionally a list of
303 options, return matched checks with merged options (command line options
304 values take precedence on default ones)
305
306 It runs find checks, then resolve options and returns a dict of matched
307 functions with resolved options.
308 """
309 funcs = {}
310
311 if names is None:
312 names = []
313
314 if options is None:
315 options = []
316
317 # find checks
318 for name in names:
319 matched = find_checks(
320 name,
321 table=table,
322 alias_table=alias_table,
323 full_pyramid=full_pyramid,
324 )
325 matched_names = b", ".join(matched)
326 ui.debug(b"found checks '%s' for name '%s'\n" % (matched_names, name))
327 funcs.update(matched)
328
329 funcs = {n: functools.partial(f, ui, repo) for n, f in funcs.items()}
330
331 # resolve options
332 checks = pass_options(
333 ui,
334 funcs,
335 options,
336 table=table,
337 alias_table=alias_table,
338 full_pyramid=full_pyramid,
339 )
340
341 return checks
@@ -0,0 +1,399 b''
1 # Test admin commands
2
3 import functools
4 import unittest
5 from mercurial.i18n import _
6 from mercurial import error, ui as uimod
7 from mercurial import registrar
8 from mercurial.admin import verify
9
10
11 class TestAdminVerifyFindChecks(unittest.TestCase):
12 def __init__(self, *args, **kwargs):
13 super().__init__(*args, **kwargs)
14 self.ui = uimod.ui.load()
15 self.repo = b"fake-repo"
16
17 def cleanup_table(self):
18 self.table = {}
19 self.alias_table = {}
20 self.pyramid = {}
21
22 self.addCleanup(cleanup_table, self)
23
24 def setUp(self):
25 self.table = {}
26 self.alias_table = {}
27 self.pyramid = {}
28 check = registrar.verify_check(self.table, self.alias_table)
29
30 # mock some fake check method for tests purpose
31 @check(
32 b"test.dummy",
33 alias=b"dummy",
34 options=[],
35 )
36 def check_dummy(ui, repo, **options):
37 return options
38
39 @check(
40 b"test.fake",
41 alias=b"fake",
42 options=[
43 (b'a', False, _(b'a boolean value (default: False)')),
44 (b'b', True, _(b'a boolean value (default: True)')),
45 (b'c', [], _(b'a list')),
46 ],
47 )
48 def check_fake(ui, repo, **options):
49 return options
50
51 # alias in the middle of a hierarchy
52 check(
53 b"test.noop",
54 alias=b"noop",
55 options=[],
56 )(verify.noop_func)
57
58 @check(
59 b"test.noop.deeper",
60 alias=b"deeper",
61 options=[
62 (b'y', True, _(b'a boolean value (default: True)')),
63 (b'z', [], _(b'a list')),
64 ],
65 )
66 def check_noop_deeper(ui, repo, **options):
67 return options
68
69 # args wrapper utilities
70 def find_checks(self, name):
71 return verify.find_checks(
72 name=name,
73 table=self.table,
74 alias_table=self.alias_table,
75 full_pyramid=self.pyramid,
76 )
77
78 def pass_options(self, checks, options):
79 return verify.pass_options(
80 self.ui,
81 checks,
82 options,
83 table=self.table,
84 alias_table=self.alias_table,
85 full_pyramid=self.pyramid,
86 )
87
88 def get_checks(self, names, options):
89 return verify.get_checks(
90 self.repo,
91 self.ui,
92 names=names,
93 options=options,
94 table=self.table,
95 alias_table=self.alias_table,
96 full_pyramid=self.pyramid,
97 )
98
99 # tests find_checks
100 def test_find_checks_empty_name(self):
101 with self.assertRaises(error.InputError):
102 self.find_checks(name=b"")
103
104 def test_find_checks_wrong_name(self):
105 with self.assertRaises(error.InputError):
106 self.find_checks(name=b"unknown")
107
108 def test_find_checks_dummy(self):
109 name = b"test.dummy"
110 found = self.find_checks(name=name)
111 self.assertEqual(len(found), 1)
112 self.assertIn(name, found)
113 meth = found[name]
114 self.assertTrue(callable(meth))
115 self.assertEqual(len(meth.options), 0)
116
117 def test_find_checks_fake(self):
118 name = b"test.fake"
119 found = self.find_checks(name=name)
120 self.assertEqual(len(found), 1)
121 self.assertIn(name, found)
122 meth = found[name]
123 self.assertTrue(callable(meth))
124 self.assertEqual(len(meth.options), 3)
125
126 def test_find_checks_noop(self):
127 name = b"test.noop.deeper"
128 found = self.find_checks(name=name)
129 self.assertEqual(len(found), 1)
130 self.assertIn(name, found)
131 meth = found[name]
132 self.assertTrue(callable(meth))
133 self.assertEqual(len(meth.options), 2)
134
135 def test_find_checks_from_aliases(self):
136 found = self.find_checks(name=b"dummy")
137 self.assertEqual(len(found), 1)
138 self.assertIn(b"test.dummy", found)
139
140 found = self.find_checks(name=b"fake")
141 self.assertEqual(len(found), 1)
142 self.assertIn(b"test.fake", found)
143
144 found = self.find_checks(name=b"deeper")
145 self.assertEqual(len(found), 1)
146 self.assertIn(b"test.noop.deeper", found)
147
148 def test_find_checks_from_root(self):
149 found = self.find_checks(name=b"test")
150 self.assertEqual(len(found), 3)
151 self.assertIn(b"test.dummy", found)
152 self.assertIn(b"test.fake", found)
153 self.assertIn(b"test.noop.deeper", found)
154
155 def test_find_checks_from_intermediate(self):
156 found = self.find_checks(name=b"test.noop")
157 self.assertEqual(len(found), 1)
158 self.assertIn(b"test.noop.deeper", found)
159
160 def test_find_checks_from_parent_dot_name(self):
161 found = self.find_checks(name=b"noop.deeper")
162 self.assertEqual(len(found), 1)
163 self.assertIn(b"test.noop.deeper", found)
164
165 # tests pass_options
166 def test_pass_options_no_checks_no_options(self):
167 checks = {}
168 options = []
169
170 with self.assertRaises(error.Error):
171 self.pass_options(checks=checks, options=options)
172
173 def test_pass_options_fake_empty_options(self):
174 checks = self.find_checks(name=b"test.fake")
175 funcs = {
176 n: functools.partial(f, self.ui, self.repo)
177 for n, f in checks.items()
178 }
179 options = []
180 # should end with default options
181 expected_options = {"a": False, "b": True, "c": []}
182 func = self.pass_options(checks=funcs, options=options)
183
184 self.assertDictEqual(func[b"test.fake"].keywords, expected_options)
185
186 def test_pass_options_fake_non_existing_options(self):
187 checks = self.find_checks(name=b"test.fake")
188 funcs = {
189 n: functools.partial(f, self.ui, self.repo)
190 for n, f in checks.items()
191 }
192
193 with self.assertRaises(error.InputError):
194 options = [b"test.fake:boom=yes"]
195 self.pass_options(checks=funcs, options=options)
196
197 def test_pass_options_fake_unrelated_options(self):
198 checks = self.find_checks(name=b"test.fake")
199 funcs = {
200 n: functools.partial(f, self.ui, self.repo)
201 for n, f in checks.items()
202 }
203 options = [b"test.noop.deeper:y=yes"]
204
205 with self.assertRaises(error.InputError):
206 self.pass_options(checks=funcs, options=options)
207
208 def test_pass_options_fake_set_option(self):
209 checks = self.find_checks(name=b"test.fake")
210 funcs = {
211 n: functools.partial(f, self.ui, self.repo)
212 for n, f in checks.items()
213 }
214 options = [b"test.fake:a=yes"]
215 expected_options = {"a": True, "b": True, "c": []}
216 func = self.pass_options(checks=funcs, options=options)
217
218 self.assertDictEqual(func[b"test.fake"].keywords, expected_options)
219
220 def test_pass_options_fake_set_option_with_alias(self):
221 checks = self.find_checks(name=b"test.fake")
222 funcs = {
223 n: functools.partial(f, self.ui, self.repo)
224 for n, f in checks.items()
225 }
226 options = [b"fake:a=yes"]
227 expected_options = {"a": True, "b": True, "c": []}
228 func = self.pass_options(checks=funcs, options=options)
229
230 self.assertDictEqual(func[b"test.fake"].keywords, expected_options)
231
232 def test_pass_options_fake_set_all_option(self):
233 checks = self.find_checks(name=b"test.fake")
234 funcs = {
235 n: functools.partial(f, self.ui, self.repo)
236 for n, f in checks.items()
237 }
238 options = [b"test.fake:a=yes", b"test.fake:b=no", b"test.fake:c=0,1,2"]
239 expected_options = {"a": True, "b": False, "c": [b"0", b"1", b"2"]}
240 func = self.pass_options(checks=funcs, options=options)
241
242 self.assertDictEqual(func[b"test.fake"].keywords, expected_options)
243
244 def test_pass_options_fake_set_all_option_plus_unexisting(self):
245 checks = self.find_checks(name=b"test.fake")
246 funcs = {
247 n: functools.partial(f, self.ui, self.repo)
248 for n, f in checks.items()
249 }
250 options = [
251 b"test.fake:a=yes",
252 b"test.fake:b=no",
253 b"test.fake:c=0,1,2",
254 b"test.fake:d=0",
255 ]
256
257 with self.assertRaises(error.InputError):
258 self.pass_options(checks=funcs, options=options)
259
260 def test_pass_options_fake_duplicate_option(self):
261 checks = self.find_checks(name=b"test.fake")
262 funcs = {
263 n: functools.partial(f, self.ui, self.repo)
264 for n, f in checks.items()
265 }
266 options = [
267 b"test.fake:a=yes",
268 b"test.fake:a=no",
269 ]
270
271 with self.assertRaises(error.InputError):
272 self.pass_options(checks=funcs, options=options)
273
274 def test_pass_options_fake_set_malformed_option(self):
275 checks = self.find_checks(name=b"test.fake")
276 funcs = {
277 n: functools.partial(f, self.ui, self.repo)
278 for n, f in checks.items()
279 }
280 options = [
281 b"test.fake:ayes",
282 b"test.fake:b==no",
283 b"test.fake=",
284 b"test.fake:",
285 b"test.fa=ke:d=0",
286 b"test.fa=ke:d=0",
287 ]
288
289 for opt in options:
290 with self.assertRaises(error.InputError):
291 self.pass_options(checks=funcs, options=[opt])
292
293 def test_pass_options_types(self):
294 checks = self.find_checks(name=b"test.fake")
295 funcs = {
296 n: functools.partial(f, self.ui, self.repo)
297 for n, f in checks.items()
298 }
299 # boolean, yes/no
300 options = [b"test.fake:a=yes", b"test.fake:b=no"]
301 expected_options = {"a": True, "b": False, "c": []}
302 func = self.pass_options(checks=funcs, options=options)
303
304 self.assertDictEqual(func[b"test.fake"].keywords, expected_options)
305
306 # boolean, 0/1
307 options = [b"test.fake:a=1", b"test.fake:b=0"]
308 expected_options = {"a": True, "b": False, "c": []}
309 func = self.pass_options(checks=funcs, options=options)
310
311 self.assertDictEqual(func[b"test.fake"].keywords, expected_options)
312
313 # boolean, true/false
314 options = [b"test.fake:a=true", b"test.fake:b=false"]
315 expected_options = {"a": True, "b": False, "c": []}
316 func = self.pass_options(checks=funcs, options=options)
317
318 self.assertDictEqual(func[b"test.fake"].keywords, expected_options)
319
320 # boolean, wrong type
321 options = [b"test.fake:a=si"]
322 with self.assertRaises(error.InputError):
323 self.pass_options(checks=funcs, options=options)
324
325 # lists
326 options = [b"test.fake:c=0,1,2"]
327 expected_options = {"a": False, "b": True, "c": [b"0", b"1", b"2"]}
328 func = self.pass_options(checks=funcs, options=options)
329
330 self.assertDictEqual(func[b"test.fake"].keywords, expected_options)
331
332 options = [b"test.fake:c=x,y,z"]
333 expected_options = {"a": False, "b": True, "c": [b"x", b"y", b"z"]}
334 func = self.pass_options(checks=funcs, options=options)
335
336 self.assertDictEqual(func[b"test.fake"].keywords, expected_options)
337
338 # tests get_checks
339 def test_get_checks_fake(self):
340 funcs = self.get_checks(
341 names=[b"test.fake"], options=[b"test.fake:a=yes"]
342 )
343 options = funcs.get(b"test.fake").keywords
344 expected_options = {"a": True, "b": True, "c": []}
345 self.assertDictEqual(options, expected_options)
346
347 def test_get_checks_multiple_mixed_with_defaults(self):
348 funcs = self.get_checks(
349 names=[b"test.fake", b"test.noop.deeper", b"test.dummy"],
350 options=[
351 b"test.noop.deeper:y=no",
352 b"test.noop.deeper:z=-1,0,1",
353 ],
354 )
355 options = funcs.get(b"test.fake").keywords
356 expected_options = {"a": False, "b": True, "c": []}
357 self.assertDictEqual(options, expected_options)
358
359 options = funcs.get(b"test.noop.deeper").keywords
360 expected_options = {"y": False, "z": [b"-1", b"0", b"1"]}
361 self.assertDictEqual(options, expected_options)
362
363 options = funcs.get(b"test.dummy").keywords
364 expected_options = {}
365 self.assertDictEqual(options, expected_options)
366
367 def test_broken_pyramid(self):
368 """Check that we detect pyramids that can't resolve"""
369 table = {}
370 alias_table = {}
371 pyramid = {}
372 check = registrar.verify_check(table, alias_table)
373
374 # Create two checks that clash
375 @check(b"test.wrong.intermediate")
376 def check_dummy(ui, repo, **options):
377 return options
378
379 @check(b"test.wrong.intermediate.thing")
380 def check_fake(ui, repo, **options):
381 return options
382
383 with self.assertRaises(error.ProgrammingError) as e:
384 verify.get_checks(
385 self.repo,
386 self.ui,
387 names=[b"test.wrong.intermediate"],
388 options=[],
389 table=table,
390 alias_table=alias_table,
391 full_pyramid=pyramid,
392 )
393 assert "`verify.noop_func`" in str(e.exception), str(e.exception)
394
395
396 if __name__ == '__main__':
397 import silenttestrunner
398
399 silenttestrunner.main(__name__)
@@ -0,0 +1,49 b''
1 Test admin::verify
2
3 $ hg init admin-verify
4 $ cd admin-verify
5
6 Test normal output
7
8 $ hg admin::verify -c dirstate
9 running 1 checks
10 running working-copy.dirstate
11 checking dirstate
12
13 Quiet works
14
15 $ hg admin::verify -c dirstate --quiet
16
17 Test no check no options
18
19 $ hg admin::verify
20 abort: `checks` required
21 [255]
22
23 Test single check without options
24
25 $ hg admin::verify -c working-copy.dirstate
26 running 1 checks
27 running working-copy.dirstate
28 checking dirstate
29
30 Test single check (alias) without options
31
32 $ hg admin::verify -c dirstate
33 running 1 checks
34 running working-copy.dirstate
35 checking dirstate
36
37 Test wrong check name without options
38
39 $ hg admin::verify -c working-copy.dir
40 abort: unknown check working-copy.dir
41 (did you mean working-copy.dirstate?)
42 [10]
43
44 Test wrong alias without options
45
46 $ hg admin::verify -c dir
47 abort: unknown check dir
48 [10]
49
@@ -1,11 +1,49 b''
1 # admin_commands.py - command processing for admin* commands
1 # admin_commands.py - command processing for admin* commands
2 #
2 #
3 # Copyright 2022 Mercurial Developers
3 # Copyright 2022 Mercurial Developers
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 . import registrar
8 from .i18n import _
9 from .admin import verify
10 from . import error, registrar, transaction
11
9
12
10 table = {}
13 table = {}
11 command = registrar.command(table)
14 command = registrar.command(table)
15
16
17 @command(
18 b'admin::verify',
19 [
20 (b'c', b'check', [], _(b'add a check'), _(b'CHECK')),
21 (b'o', b'option', [], _(b'pass an option to a check'), _(b'OPTION')),
22 ],
23 helpcategory=command.CATEGORY_MAINTENANCE,
24 )
25 def admin_verify(ui, repo, **opts):
26 """verify the integrity of the repository
27
28 Alternative UI to `hg verify` with a lot more control over the
29 verification process and better error reporting.
30 """
31
32 if not repo.url().startswith(b'file:'):
33 raise error.Abort(_(b"cannot verify bundle or remote repos"))
34
35 if transaction.has_abandoned_transaction(repo):
36 ui.warn(_(b"abandoned transaction found - run hg recover\n"))
37
38 checks = opts.get("check", [])
39 options = opts.get("option", [])
40
41 funcs = verify.get_checks(repo, ui, names=checks, options=options)
42
43 ui.status(_(b"running %d checks\n") % len(funcs))
44 # Done in two times so the execution is separated from the resolving step
45 for name, func in sorted(funcs.items(), key=lambda x: x[0]):
46 ui.status(_(b"running %s\n") % name)
47 errors = func()
48 if errors:
49 ui.warn(_(b"found %d errors\n") % len(errors))
@@ -1,8049 +1,8052 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
3 # Copyright 2005-2007 Olivia Mackall <olivia@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
8
9 import os
9 import os
10 import re
10 import re
11 import sys
11 import sys
12
12
13 from .i18n import _
13 from .i18n import _
14 from .node import (
14 from .node import (
15 hex,
15 hex,
16 nullid,
16 nullid,
17 nullrev,
17 nullrev,
18 short,
18 short,
19 wdirrev,
19 wdirrev,
20 )
20 )
21 from . import (
21 from . import (
22 admin_commands as admin_commands_mod,
22 admin_commands as admin_commands_mod,
23 archival,
23 archival,
24 bookmarks,
24 bookmarks,
25 bundle2,
25 bundle2,
26 bundlecaches,
26 bundlecaches,
27 changegroup,
27 changegroup,
28 cmdutil,
28 cmdutil,
29 copies,
29 copies,
30 debugcommands as debugcommandsmod,
30 debugcommands as debugcommandsmod,
31 destutil,
31 destutil,
32 discovery,
32 discovery,
33 encoding,
33 encoding,
34 error,
34 error,
35 exchange,
35 exchange,
36 extensions,
36 extensions,
37 filemerge,
37 filemerge,
38 formatter,
38 formatter,
39 graphmod,
39 graphmod,
40 grep as grepmod,
40 grep as grepmod,
41 hbisect,
41 hbisect,
42 help,
42 help,
43 hg,
43 hg,
44 logcmdutil,
44 logcmdutil,
45 merge as mergemod,
45 merge as mergemod,
46 mergestate as mergestatemod,
46 mergestate as mergestatemod,
47 narrowspec,
47 narrowspec,
48 obsolete,
48 obsolete,
49 obsutil,
49 obsutil,
50 patch,
50 patch,
51 phases,
51 phases,
52 pycompat,
52 pycompat,
53 rcutil,
53 rcutil,
54 registrar,
54 registrar,
55 requirements,
55 requirements,
56 revsetlang,
56 revsetlang,
57 rewriteutil,
57 rewriteutil,
58 scmutil,
58 scmutil,
59 server,
59 server,
60 shelve as shelvemod,
60 shelve as shelvemod,
61 state as statemod,
61 state as statemod,
62 streamclone,
62 streamclone,
63 tags as tagsmod,
63 tags as tagsmod,
64 ui as uimod,
64 ui as uimod,
65 util,
65 util,
66 verify as verifymod,
66 verify as verifymod,
67 vfs as vfsmod,
67 vfs as vfsmod,
68 wireprotoserver,
68 wireprotoserver,
69 )
69 )
70 from .utils import (
70 from .utils import (
71 dateutil,
71 dateutil,
72 procutil,
72 procutil,
73 stringutil,
73 stringutil,
74 urlutil,
74 urlutil,
75 )
75 )
76
76
77 table = {}
77 table = {}
78 table.update(debugcommandsmod.command._table)
78 table.update(debugcommandsmod.command._table)
79 table.update(admin_commands_mod.command._table)
79 table.update(admin_commands_mod.command._table)
80
80
81 command = registrar.command(table)
81 command = registrar.command(table)
82 INTENT_READONLY = registrar.INTENT_READONLY
82 INTENT_READONLY = registrar.INTENT_READONLY
83
83
84 # common command options
84 # common command options
85
85
86 globalopts = [
86 globalopts = [
87 (
87 (
88 b'R',
88 b'R',
89 b'repository',
89 b'repository',
90 b'',
90 b'',
91 _(b'repository root directory or name of overlay bundle file'),
91 _(b'repository root directory or name of overlay bundle file'),
92 _(b'REPO'),
92 _(b'REPO'),
93 ),
93 ),
94 (b'', b'cwd', b'', _(b'change working directory'), _(b'DIR')),
94 (b'', b'cwd', b'', _(b'change working directory'), _(b'DIR')),
95 (
95 (
96 b'y',
96 b'y',
97 b'noninteractive',
97 b'noninteractive',
98 None,
98 None,
99 _(
99 _(
100 b'do not prompt, automatically pick the first choice for all prompts'
100 b'do not prompt, automatically pick the first choice for all prompts'
101 ),
101 ),
102 ),
102 ),
103 (b'q', b'quiet', None, _(b'suppress output')),
103 (b'q', b'quiet', None, _(b'suppress output')),
104 (b'v', b'verbose', None, _(b'enable additional output')),
104 (b'v', b'verbose', None, _(b'enable additional output')),
105 (
105 (
106 b'',
106 b'',
107 b'color',
107 b'color',
108 b'',
108 b'',
109 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
109 # i18n: 'always', 'auto', 'never', and 'debug' are keywords
110 # and should not be translated
110 # and should not be translated
111 _(b"when to colorize (boolean, always, auto, never, or debug)"),
111 _(b"when to colorize (boolean, always, auto, never, or debug)"),
112 _(b'TYPE'),
112 _(b'TYPE'),
113 ),
113 ),
114 (
114 (
115 b'',
115 b'',
116 b'config',
116 b'config',
117 [],
117 [],
118 _(b'set/override config option (use \'section.name=value\')'),
118 _(b'set/override config option (use \'section.name=value\')'),
119 _(b'CONFIG'),
119 _(b'CONFIG'),
120 ),
120 ),
121 (b'', b'debug', None, _(b'enable debugging output')),
121 (b'', b'debug', None, _(b'enable debugging output')),
122 (b'', b'debugger', None, _(b'start debugger')),
122 (b'', b'debugger', None, _(b'start debugger')),
123 (
123 (
124 b'',
124 b'',
125 b'encoding',
125 b'encoding',
126 encoding.encoding,
126 encoding.encoding,
127 _(b'set the charset encoding'),
127 _(b'set the charset encoding'),
128 _(b'ENCODE'),
128 _(b'ENCODE'),
129 ),
129 ),
130 (
130 (
131 b'',
131 b'',
132 b'encodingmode',
132 b'encodingmode',
133 encoding.encodingmode,
133 encoding.encodingmode,
134 _(b'set the charset encoding mode'),
134 _(b'set the charset encoding mode'),
135 _(b'MODE'),
135 _(b'MODE'),
136 ),
136 ),
137 (b'', b'traceback', None, _(b'always print a traceback on exception')),
137 (b'', b'traceback', None, _(b'always print a traceback on exception')),
138 (b'', b'time', None, _(b'time how long the command takes')),
138 (b'', b'time', None, _(b'time how long the command takes')),
139 (b'', b'profile', None, _(b'print command execution profile')),
139 (b'', b'profile', None, _(b'print command execution profile')),
140 (b'', b'version', None, _(b'output version information and exit')),
140 (b'', b'version', None, _(b'output version information and exit')),
141 (b'h', b'help', None, _(b'display help and exit')),
141 (b'h', b'help', None, _(b'display help and exit')),
142 (b'', b'hidden', False, _(b'consider hidden changesets')),
142 (b'', b'hidden', False, _(b'consider hidden changesets')),
143 (
143 (
144 b'',
144 b'',
145 b'pager',
145 b'pager',
146 b'auto',
146 b'auto',
147 _(b"when to paginate (boolean, always, auto, or never)"),
147 _(b"when to paginate (boolean, always, auto, or never)"),
148 _(b'TYPE'),
148 _(b'TYPE'),
149 ),
149 ),
150 ]
150 ]
151
151
152 dryrunopts = cmdutil.dryrunopts
152 dryrunopts = cmdutil.dryrunopts
153 remoteopts = cmdutil.remoteopts
153 remoteopts = cmdutil.remoteopts
154 walkopts = cmdutil.walkopts
154 walkopts = cmdutil.walkopts
155 commitopts = cmdutil.commitopts
155 commitopts = cmdutil.commitopts
156 commitopts2 = cmdutil.commitopts2
156 commitopts2 = cmdutil.commitopts2
157 commitopts3 = cmdutil.commitopts3
157 commitopts3 = cmdutil.commitopts3
158 formatteropts = cmdutil.formatteropts
158 formatteropts = cmdutil.formatteropts
159 templateopts = cmdutil.templateopts
159 templateopts = cmdutil.templateopts
160 logopts = cmdutil.logopts
160 logopts = cmdutil.logopts
161 diffopts = cmdutil.diffopts
161 diffopts = cmdutil.diffopts
162 diffwsopts = cmdutil.diffwsopts
162 diffwsopts = cmdutil.diffwsopts
163 diffopts2 = cmdutil.diffopts2
163 diffopts2 = cmdutil.diffopts2
164 mergetoolopts = cmdutil.mergetoolopts
164 mergetoolopts = cmdutil.mergetoolopts
165 similarityopts = cmdutil.similarityopts
165 similarityopts = cmdutil.similarityopts
166 subrepoopts = cmdutil.subrepoopts
166 subrepoopts = cmdutil.subrepoopts
167 debugrevlogopts = cmdutil.debugrevlogopts
167 debugrevlogopts = cmdutil.debugrevlogopts
168
168
169 # Commands start here, listed alphabetically
169 # Commands start here, listed alphabetically
170
170
171
171
172 @command(
172 @command(
173 b'abort',
173 b'abort',
174 dryrunopts,
174 dryrunopts,
175 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
175 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
176 helpbasic=True,
176 helpbasic=True,
177 )
177 )
178 def abort(ui, repo, **opts):
178 def abort(ui, repo, **opts):
179 """abort an unfinished operation (EXPERIMENTAL)
179 """abort an unfinished operation (EXPERIMENTAL)
180
180
181 Aborts a multistep operation like graft, histedit, rebase, merge,
181 Aborts a multistep operation like graft, histedit, rebase, merge,
182 and unshelve if they are in an unfinished state.
182 and unshelve if they are in an unfinished state.
183
183
184 use --dry-run/-n to dry run the command.
184 use --dry-run/-n to dry run the command.
185 """
185 """
186 dryrun = opts.get('dry_run')
186 dryrun = opts.get('dry_run')
187 abortstate = cmdutil.getunfinishedstate(repo)
187 abortstate = cmdutil.getunfinishedstate(repo)
188 if not abortstate:
188 if not abortstate:
189 raise error.StateError(_(b'no operation in progress'))
189 raise error.StateError(_(b'no operation in progress'))
190 if not abortstate.abortfunc:
190 if not abortstate.abortfunc:
191 raise error.InputError(
191 raise error.InputError(
192 (
192 (
193 _(b"%s in progress but does not support 'hg abort'")
193 _(b"%s in progress but does not support 'hg abort'")
194 % (abortstate._opname)
194 % (abortstate._opname)
195 ),
195 ),
196 hint=abortstate.hint(),
196 hint=abortstate.hint(),
197 )
197 )
198 if dryrun:
198 if dryrun:
199 ui.status(
199 ui.status(
200 _(b'%s in progress, will be aborted\n') % (abortstate._opname)
200 _(b'%s in progress, will be aborted\n') % (abortstate._opname)
201 )
201 )
202 return
202 return
203 return abortstate.abortfunc(ui, repo)
203 return abortstate.abortfunc(ui, repo)
204
204
205
205
206 @command(
206 @command(
207 b'add',
207 b'add',
208 walkopts + subrepoopts + dryrunopts,
208 walkopts + subrepoopts + dryrunopts,
209 _(b'[OPTION]... [FILE]...'),
209 _(b'[OPTION]... [FILE]...'),
210 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
210 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
211 helpbasic=True,
211 helpbasic=True,
212 inferrepo=True,
212 inferrepo=True,
213 )
213 )
214 def add(ui, repo, *pats, **opts):
214 def add(ui, repo, *pats, **opts):
215 """add the specified files on the next commit
215 """add the specified files on the next commit
216
216
217 Schedule files to be version controlled and added to the
217 Schedule files to be version controlled and added to the
218 repository.
218 repository.
219
219
220 The files will be added to the repository at the next commit. To
220 The files will be added to the repository at the next commit. To
221 undo an add before that, see :hg:`forget`.
221 undo an add before that, see :hg:`forget`.
222
222
223 If no names are given, add all files to the repository (except
223 If no names are given, add all files to the repository (except
224 files matching ``.hgignore``).
224 files matching ``.hgignore``).
225
225
226 .. container:: verbose
226 .. container:: verbose
227
227
228 Examples:
228 Examples:
229
229
230 - New (unknown) files are added
230 - New (unknown) files are added
231 automatically by :hg:`add`::
231 automatically by :hg:`add`::
232
232
233 $ ls
233 $ ls
234 foo.c
234 foo.c
235 $ hg status
235 $ hg status
236 ? foo.c
236 ? foo.c
237 $ hg add
237 $ hg add
238 adding foo.c
238 adding foo.c
239 $ hg status
239 $ hg status
240 A foo.c
240 A foo.c
241
241
242 - Specific files to be added can be specified::
242 - Specific files to be added can be specified::
243
243
244 $ ls
244 $ ls
245 bar.c foo.c
245 bar.c foo.c
246 $ hg status
246 $ hg status
247 ? bar.c
247 ? bar.c
248 ? foo.c
248 ? foo.c
249 $ hg add bar.c
249 $ hg add bar.c
250 $ hg status
250 $ hg status
251 A bar.c
251 A bar.c
252 ? foo.c
252 ? foo.c
253
253
254 Returns 0 if all files are successfully added.
254 Returns 0 if all files are successfully added.
255 """
255 """
256
256
257 with repo.wlock(), repo.dirstate.changing_files(repo):
257 with repo.wlock(), repo.dirstate.changing_files(repo):
258 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
258 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
259 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
259 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
260 rejected = cmdutil.add(ui, repo, m, b"", uipathfn, False, **opts)
260 rejected = cmdutil.add(ui, repo, m, b"", uipathfn, False, **opts)
261 return rejected and 1 or 0
261 return rejected and 1 or 0
262
262
263
263
264 @command(
264 @command(
265 b'addremove',
265 b'addremove',
266 similarityopts + subrepoopts + walkopts + dryrunopts,
266 similarityopts + subrepoopts + walkopts + dryrunopts,
267 _(b'[OPTION]... [FILE]...'),
267 _(b'[OPTION]... [FILE]...'),
268 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
268 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
269 inferrepo=True,
269 inferrepo=True,
270 )
270 )
271 def addremove(ui, repo, *pats, **opts):
271 def addremove(ui, repo, *pats, **opts):
272 """add all new files, delete all missing files
272 """add all new files, delete all missing files
273
273
274 Add all new files and remove all missing files from the
274 Add all new files and remove all missing files from the
275 repository.
275 repository.
276
276
277 Unless names are given, new files are ignored if they match any of
277 Unless names are given, new files are ignored if they match any of
278 the patterns in ``.hgignore``. As with add, these changes take
278 the patterns in ``.hgignore``. As with add, these changes take
279 effect at the next commit.
279 effect at the next commit.
280
280
281 Use the -s/--similarity option to detect renamed files. This
281 Use the -s/--similarity option to detect renamed files. This
282 option takes a percentage between 0 (disabled) and 100 (files must
282 option takes a percentage between 0 (disabled) and 100 (files must
283 be identical) as its parameter. With a parameter greater than 0,
283 be identical) as its parameter. With a parameter greater than 0,
284 this compares every removed file with every added file and records
284 this compares every removed file with every added file and records
285 those similar enough as renames. Detecting renamed files this way
285 those similar enough as renames. Detecting renamed files this way
286 can be expensive. After using this option, :hg:`status -C` can be
286 can be expensive. After using this option, :hg:`status -C` can be
287 used to check which files were identified as moved or renamed. If
287 used to check which files were identified as moved or renamed. If
288 not specified, -s/--similarity defaults to 100 and only renames of
288 not specified, -s/--similarity defaults to 100 and only renames of
289 identical files are detected.
289 identical files are detected.
290
290
291 .. container:: verbose
291 .. container:: verbose
292
292
293 Examples:
293 Examples:
294
294
295 - A number of files (bar.c and foo.c) are new,
295 - A number of files (bar.c and foo.c) are new,
296 while foobar.c has been removed (without using :hg:`remove`)
296 while foobar.c has been removed (without using :hg:`remove`)
297 from the repository::
297 from the repository::
298
298
299 $ ls
299 $ ls
300 bar.c foo.c
300 bar.c foo.c
301 $ hg status
301 $ hg status
302 ! foobar.c
302 ! foobar.c
303 ? bar.c
303 ? bar.c
304 ? foo.c
304 ? foo.c
305 $ hg addremove
305 $ hg addremove
306 adding bar.c
306 adding bar.c
307 adding foo.c
307 adding foo.c
308 removing foobar.c
308 removing foobar.c
309 $ hg status
309 $ hg status
310 A bar.c
310 A bar.c
311 A foo.c
311 A foo.c
312 R foobar.c
312 R foobar.c
313
313
314 - A file foobar.c was moved to foo.c without using :hg:`rename`.
314 - A file foobar.c was moved to foo.c without using :hg:`rename`.
315 Afterwards, it was edited slightly::
315 Afterwards, it was edited slightly::
316
316
317 $ ls
317 $ ls
318 foo.c
318 foo.c
319 $ hg status
319 $ hg status
320 ! foobar.c
320 ! foobar.c
321 ? foo.c
321 ? foo.c
322 $ hg addremove --similarity 90
322 $ hg addremove --similarity 90
323 removing foobar.c
323 removing foobar.c
324 adding foo.c
324 adding foo.c
325 recording removal of foobar.c as rename to foo.c (94% similar)
325 recording removal of foobar.c as rename to foo.c (94% similar)
326 $ hg status -C
326 $ hg status -C
327 A foo.c
327 A foo.c
328 foobar.c
328 foobar.c
329 R foobar.c
329 R foobar.c
330
330
331 Returns 0 if all files are successfully added.
331 Returns 0 if all files are successfully added.
332 """
332 """
333 opts = pycompat.byteskwargs(opts)
333 opts = pycompat.byteskwargs(opts)
334 if not opts.get(b'similarity'):
334 if not opts.get(b'similarity'):
335 opts[b'similarity'] = b'100'
335 opts[b'similarity'] = b'100'
336 with repo.wlock(), repo.dirstate.changing_files(repo):
336 with repo.wlock(), repo.dirstate.changing_files(repo):
337 matcher = scmutil.match(repo[None], pats, opts)
337 matcher = scmutil.match(repo[None], pats, opts)
338 relative = scmutil.anypats(pats, opts)
338 relative = scmutil.anypats(pats, opts)
339 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
339 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
340 return scmutil.addremove(repo, matcher, b"", uipathfn, opts)
340 return scmutil.addremove(repo, matcher, b"", uipathfn, opts)
341
341
342
342
343 @command(
343 @command(
344 b'annotate|blame',
344 b'annotate|blame',
345 [
345 [
346 (b'r', b'rev', b'', _(b'annotate the specified revision'), _(b'REV')),
346 (b'r', b'rev', b'', _(b'annotate the specified revision'), _(b'REV')),
347 (
347 (
348 b'',
348 b'',
349 b'follow',
349 b'follow',
350 None,
350 None,
351 _(b'follow copies/renames and list the filename (DEPRECATED)'),
351 _(b'follow copies/renames and list the filename (DEPRECATED)'),
352 ),
352 ),
353 (b'', b'no-follow', None, _(b"don't follow copies and renames")),
353 (b'', b'no-follow', None, _(b"don't follow copies and renames")),
354 (b'a', b'text', None, _(b'treat all files as text')),
354 (b'a', b'text', None, _(b'treat all files as text')),
355 (b'u', b'user', None, _(b'list the author (long with -v)')),
355 (b'u', b'user', None, _(b'list the author (long with -v)')),
356 (b'f', b'file', None, _(b'list the filename')),
356 (b'f', b'file', None, _(b'list the filename')),
357 (b'd', b'date', None, _(b'list the date (short with -q)')),
357 (b'd', b'date', None, _(b'list the date (short with -q)')),
358 (b'n', b'number', None, _(b'list the revision number (default)')),
358 (b'n', b'number', None, _(b'list the revision number (default)')),
359 (b'c', b'changeset', None, _(b'list the changeset')),
359 (b'c', b'changeset', None, _(b'list the changeset')),
360 (
360 (
361 b'l',
361 b'l',
362 b'line-number',
362 b'line-number',
363 None,
363 None,
364 _(b'show line number at the first appearance'),
364 _(b'show line number at the first appearance'),
365 ),
365 ),
366 (
366 (
367 b'',
367 b'',
368 b'skip',
368 b'skip',
369 [],
369 [],
370 _(b'revset to not display (EXPERIMENTAL)'),
370 _(b'revset to not display (EXPERIMENTAL)'),
371 _(b'REV'),
371 _(b'REV'),
372 ),
372 ),
373 ]
373 ]
374 + diffwsopts
374 + diffwsopts
375 + walkopts
375 + walkopts
376 + formatteropts,
376 + formatteropts,
377 _(b'[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
377 _(b'[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
378 helpcategory=command.CATEGORY_FILE_CONTENTS,
378 helpcategory=command.CATEGORY_FILE_CONTENTS,
379 helpbasic=True,
379 helpbasic=True,
380 inferrepo=True,
380 inferrepo=True,
381 )
381 )
382 def annotate(ui, repo, *pats, **opts):
382 def annotate(ui, repo, *pats, **opts):
383 """show changeset information by line for each file
383 """show changeset information by line for each file
384
384
385 List changes in files, showing the revision id responsible for
385 List changes in files, showing the revision id responsible for
386 each line.
386 each line.
387
387
388 This command is useful for discovering when a change was made and
388 This command is useful for discovering when a change was made and
389 by whom.
389 by whom.
390
390
391 If you include --file, --user, or --date, the revision number is
391 If you include --file, --user, or --date, the revision number is
392 suppressed unless you also include --number.
392 suppressed unless you also include --number.
393
393
394 Without the -a/--text option, annotate will avoid processing files
394 Without the -a/--text option, annotate will avoid processing files
395 it detects as binary. With -a, annotate will annotate the file
395 it detects as binary. With -a, annotate will annotate the file
396 anyway, although the results will probably be neither useful
396 anyway, although the results will probably be neither useful
397 nor desirable.
397 nor desirable.
398
398
399 .. container:: verbose
399 .. container:: verbose
400
400
401 Template:
401 Template:
402
402
403 The following keywords are supported in addition to the common template
403 The following keywords are supported in addition to the common template
404 keywords and functions. See also :hg:`help templates`.
404 keywords and functions. See also :hg:`help templates`.
405
405
406 :lines: List of lines with annotation data.
406 :lines: List of lines with annotation data.
407 :path: String. Repository-absolute path of the specified file.
407 :path: String. Repository-absolute path of the specified file.
408
408
409 And each entry of ``{lines}`` provides the following sub-keywords in
409 And each entry of ``{lines}`` provides the following sub-keywords in
410 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
410 addition to ``{date}``, ``{node}``, ``{rev}``, ``{user}``, etc.
411
411
412 :line: String. Line content.
412 :line: String. Line content.
413 :lineno: Integer. Line number at that revision.
413 :lineno: Integer. Line number at that revision.
414 :path: String. Repository-absolute path of the file at that revision.
414 :path: String. Repository-absolute path of the file at that revision.
415
415
416 See :hg:`help templates.operators` for the list expansion syntax.
416 See :hg:`help templates.operators` for the list expansion syntax.
417
417
418 Returns 0 on success.
418 Returns 0 on success.
419 """
419 """
420 opts = pycompat.byteskwargs(opts)
420 opts = pycompat.byteskwargs(opts)
421 if not pats:
421 if not pats:
422 raise error.InputError(
422 raise error.InputError(
423 _(b'at least one filename or pattern is required')
423 _(b'at least one filename or pattern is required')
424 )
424 )
425
425
426 if opts.get(b'follow'):
426 if opts.get(b'follow'):
427 # --follow is deprecated and now just an alias for -f/--file
427 # --follow is deprecated and now just an alias for -f/--file
428 # to mimic the behavior of Mercurial before version 1.5
428 # to mimic the behavior of Mercurial before version 1.5
429 opts[b'file'] = True
429 opts[b'file'] = True
430
430
431 if (
431 if (
432 not opts.get(b'user')
432 not opts.get(b'user')
433 and not opts.get(b'changeset')
433 and not opts.get(b'changeset')
434 and not opts.get(b'date')
434 and not opts.get(b'date')
435 and not opts.get(b'file')
435 and not opts.get(b'file')
436 ):
436 ):
437 opts[b'number'] = True
437 opts[b'number'] = True
438
438
439 linenumber = opts.get(b'line_number') is not None
439 linenumber = opts.get(b'line_number') is not None
440 if (
440 if (
441 linenumber
441 linenumber
442 and (not opts.get(b'changeset'))
442 and (not opts.get(b'changeset'))
443 and (not opts.get(b'number'))
443 and (not opts.get(b'number'))
444 ):
444 ):
445 raise error.InputError(_(b'at least one of -n/-c is required for -l'))
445 raise error.InputError(_(b'at least one of -n/-c is required for -l'))
446
446
447 rev = opts.get(b'rev')
447 rev = opts.get(b'rev')
448 if rev:
448 if rev:
449 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
449 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
450 ctx = logcmdutil.revsingle(repo, rev)
450 ctx = logcmdutil.revsingle(repo, rev)
451
451
452 ui.pager(b'annotate')
452 ui.pager(b'annotate')
453 rootfm = ui.formatter(b'annotate', opts)
453 rootfm = ui.formatter(b'annotate', opts)
454 if ui.debugflag:
454 if ui.debugflag:
455 shorthex = pycompat.identity
455 shorthex = pycompat.identity
456 else:
456 else:
457
457
458 def shorthex(h):
458 def shorthex(h):
459 return h[:12]
459 return h[:12]
460
460
461 if ui.quiet:
461 if ui.quiet:
462 datefunc = dateutil.shortdate
462 datefunc = dateutil.shortdate
463 else:
463 else:
464 datefunc = dateutil.datestr
464 datefunc = dateutil.datestr
465 if ctx.rev() is None:
465 if ctx.rev() is None:
466 if opts.get(b'changeset'):
466 if opts.get(b'changeset'):
467 # omit "+" suffix which is appended to node hex
467 # omit "+" suffix which is appended to node hex
468 def formatrev(rev):
468 def formatrev(rev):
469 if rev == wdirrev:
469 if rev == wdirrev:
470 return b'%d' % ctx.p1().rev()
470 return b'%d' % ctx.p1().rev()
471 else:
471 else:
472 return b'%d' % rev
472 return b'%d' % rev
473
473
474 else:
474 else:
475
475
476 def formatrev(rev):
476 def formatrev(rev):
477 if rev == wdirrev:
477 if rev == wdirrev:
478 return b'%d+' % ctx.p1().rev()
478 return b'%d+' % ctx.p1().rev()
479 else:
479 else:
480 return b'%d ' % rev
480 return b'%d ' % rev
481
481
482 def formathex(h):
482 def formathex(h):
483 if h == repo.nodeconstants.wdirhex:
483 if h == repo.nodeconstants.wdirhex:
484 return b'%s+' % shorthex(hex(ctx.p1().node()))
484 return b'%s+' % shorthex(hex(ctx.p1().node()))
485 else:
485 else:
486 return b'%s ' % shorthex(h)
486 return b'%s ' % shorthex(h)
487
487
488 else:
488 else:
489 formatrev = b'%d'.__mod__
489 formatrev = b'%d'.__mod__
490 formathex = shorthex
490 formathex = shorthex
491
491
492 opmap = [
492 opmap = [
493 (b'user', b' ', lambda x: x.fctx.user(), ui.shortuser),
493 (b'user', b' ', lambda x: x.fctx.user(), ui.shortuser),
494 (b'rev', b' ', lambda x: scmutil.intrev(x.fctx), formatrev),
494 (b'rev', b' ', lambda x: scmutil.intrev(x.fctx), formatrev),
495 (b'node', b' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
495 (b'node', b' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
496 (b'date', b' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
496 (b'date', b' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
497 (b'path', b' ', lambda x: x.fctx.path(), pycompat.bytestr),
497 (b'path', b' ', lambda x: x.fctx.path(), pycompat.bytestr),
498 (b'lineno', b':', lambda x: x.lineno, pycompat.bytestr),
498 (b'lineno', b':', lambda x: x.lineno, pycompat.bytestr),
499 ]
499 ]
500 opnamemap = {
500 opnamemap = {
501 b'rev': b'number',
501 b'rev': b'number',
502 b'node': b'changeset',
502 b'node': b'changeset',
503 b'path': b'file',
503 b'path': b'file',
504 b'lineno': b'line_number',
504 b'lineno': b'line_number',
505 }
505 }
506
506
507 if rootfm.isplain():
507 if rootfm.isplain():
508
508
509 def makefunc(get, fmt):
509 def makefunc(get, fmt):
510 return lambda x: fmt(get(x))
510 return lambda x: fmt(get(x))
511
511
512 else:
512 else:
513
513
514 def makefunc(get, fmt):
514 def makefunc(get, fmt):
515 return get
515 return get
516
516
517 datahint = rootfm.datahint()
517 datahint = rootfm.datahint()
518 funcmap = [
518 funcmap = [
519 (makefunc(get, fmt), sep)
519 (makefunc(get, fmt), sep)
520 for fn, sep, get, fmt in opmap
520 for fn, sep, get, fmt in opmap
521 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
521 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
522 ]
522 ]
523 funcmap[0] = (funcmap[0][0], b'') # no separator in front of first column
523 funcmap[0] = (funcmap[0][0], b'') # no separator in front of first column
524 fields = b' '.join(
524 fields = b' '.join(
525 fn
525 fn
526 for fn, sep, get, fmt in opmap
526 for fn, sep, get, fmt in opmap
527 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
527 if opts.get(opnamemap.get(fn, fn)) or fn in datahint
528 )
528 )
529
529
530 def bad(x, y):
530 def bad(x, y):
531 raise error.InputError(b"%s: %s" % (x, y))
531 raise error.InputError(b"%s: %s" % (x, y))
532
532
533 m = scmutil.match(ctx, pats, opts, badfn=bad)
533 m = scmutil.match(ctx, pats, opts, badfn=bad)
534
534
535 follow = not opts.get(b'no_follow')
535 follow = not opts.get(b'no_follow')
536 diffopts = patch.difffeatureopts(
536 diffopts = patch.difffeatureopts(
537 ui, opts, section=b'annotate', whitespace=True
537 ui, opts, section=b'annotate', whitespace=True
538 )
538 )
539 skiprevs = opts.get(b'skip')
539 skiprevs = opts.get(b'skip')
540 if skiprevs:
540 if skiprevs:
541 skiprevs = logcmdutil.revrange(repo, skiprevs)
541 skiprevs = logcmdutil.revrange(repo, skiprevs)
542
542
543 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
543 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
544 for abs in ctx.walk(m):
544 for abs in ctx.walk(m):
545 fctx = ctx[abs]
545 fctx = ctx[abs]
546 rootfm.startitem()
546 rootfm.startitem()
547 rootfm.data(path=abs)
547 rootfm.data(path=abs)
548 if not opts.get(b'text') and fctx.isbinary():
548 if not opts.get(b'text') and fctx.isbinary():
549 rootfm.plain(_(b"%s: binary file\n") % uipathfn(abs))
549 rootfm.plain(_(b"%s: binary file\n") % uipathfn(abs))
550 continue
550 continue
551
551
552 fm = rootfm.nested(b'lines', tmpl=b'{rev}: {line}')
552 fm = rootfm.nested(b'lines', tmpl=b'{rev}: {line}')
553 lines = fctx.annotate(
553 lines = fctx.annotate(
554 follow=follow, skiprevs=skiprevs, diffopts=diffopts
554 follow=follow, skiprevs=skiprevs, diffopts=diffopts
555 )
555 )
556 if not lines:
556 if not lines:
557 fm.end()
557 fm.end()
558 continue
558 continue
559 formats = []
559 formats = []
560 pieces = []
560 pieces = []
561
561
562 for f, sep in funcmap:
562 for f, sep in funcmap:
563 l = [f(n) for n in lines]
563 l = [f(n) for n in lines]
564 if fm.isplain():
564 if fm.isplain():
565 sizes = [encoding.colwidth(x) for x in l]
565 sizes = [encoding.colwidth(x) for x in l]
566 ml = max(sizes)
566 ml = max(sizes)
567 formats.append([sep + b' ' * (ml - w) + b'%s' for w in sizes])
567 formats.append([sep + b' ' * (ml - w) + b'%s' for w in sizes])
568 else:
568 else:
569 formats.append([b'%s'] * len(l))
569 formats.append([b'%s'] * len(l))
570 pieces.append(l)
570 pieces.append(l)
571
571
572 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
572 for f, p, n in zip(zip(*formats), zip(*pieces), lines):
573 fm.startitem()
573 fm.startitem()
574 fm.context(fctx=n.fctx)
574 fm.context(fctx=n.fctx)
575 fm.write(fields, b"".join(f), *p)
575 fm.write(fields, b"".join(f), *p)
576 if n.skip:
576 if n.skip:
577 fmt = b"* %s"
577 fmt = b"* %s"
578 else:
578 else:
579 fmt = b": %s"
579 fmt = b": %s"
580 fm.write(b'line', fmt, n.text)
580 fm.write(b'line', fmt, n.text)
581
581
582 if not lines[-1].text.endswith(b'\n'):
582 if not lines[-1].text.endswith(b'\n'):
583 fm.plain(b'\n')
583 fm.plain(b'\n')
584 fm.end()
584 fm.end()
585
585
586 rootfm.end()
586 rootfm.end()
587
587
588
588
589 @command(
589 @command(
590 b'archive',
590 b'archive',
591 [
591 [
592 (b'', b'no-decode', None, _(b'do not pass files through decoders')),
592 (b'', b'no-decode', None, _(b'do not pass files through decoders')),
593 (
593 (
594 b'p',
594 b'p',
595 b'prefix',
595 b'prefix',
596 b'',
596 b'',
597 _(b'directory prefix for files in archive'),
597 _(b'directory prefix for files in archive'),
598 _(b'PREFIX'),
598 _(b'PREFIX'),
599 ),
599 ),
600 (b'r', b'rev', b'', _(b'revision to distribute'), _(b'REV')),
600 (b'r', b'rev', b'', _(b'revision to distribute'), _(b'REV')),
601 (b't', b'type', b'', _(b'type of distribution to create'), _(b'TYPE')),
601 (b't', b'type', b'', _(b'type of distribution to create'), _(b'TYPE')),
602 ]
602 ]
603 + subrepoopts
603 + subrepoopts
604 + walkopts,
604 + walkopts,
605 _(b'[OPTION]... DEST'),
605 _(b'[OPTION]... DEST'),
606 helpcategory=command.CATEGORY_IMPORT_EXPORT,
606 helpcategory=command.CATEGORY_IMPORT_EXPORT,
607 )
607 )
608 def archive(ui, repo, dest, **opts):
608 def archive(ui, repo, dest, **opts):
609 """create an unversioned archive of a repository revision
609 """create an unversioned archive of a repository revision
610
610
611 By default, the revision used is the parent of the working
611 By default, the revision used is the parent of the working
612 directory; use -r/--rev to specify a different revision.
612 directory; use -r/--rev to specify a different revision.
613
613
614 The archive type is automatically detected based on file
614 The archive type is automatically detected based on file
615 extension (to override, use -t/--type).
615 extension (to override, use -t/--type).
616
616
617 .. container:: verbose
617 .. container:: verbose
618
618
619 Examples:
619 Examples:
620
620
621 - create a zip file containing the 1.0 release::
621 - create a zip file containing the 1.0 release::
622
622
623 hg archive -r 1.0 project-1.0.zip
623 hg archive -r 1.0 project-1.0.zip
624
624
625 - create a tarball excluding .hg files::
625 - create a tarball excluding .hg files::
626
626
627 hg archive project.tar.gz -X ".hg*"
627 hg archive project.tar.gz -X ".hg*"
628
628
629 Valid types are:
629 Valid types are:
630
630
631 :``files``: a directory full of files (default)
631 :``files``: a directory full of files (default)
632 :``tar``: tar archive, uncompressed
632 :``tar``: tar archive, uncompressed
633 :``tbz2``: tar archive, compressed using bzip2
633 :``tbz2``: tar archive, compressed using bzip2
634 :``tgz``: tar archive, compressed using gzip
634 :``tgz``: tar archive, compressed using gzip
635 :``txz``: tar archive, compressed using lzma (only in Python 3)
635 :``txz``: tar archive, compressed using lzma (only in Python 3)
636 :``uzip``: zip archive, uncompressed
636 :``uzip``: zip archive, uncompressed
637 :``zip``: zip archive, compressed using deflate
637 :``zip``: zip archive, compressed using deflate
638
638
639 The exact name of the destination archive or directory is given
639 The exact name of the destination archive or directory is given
640 using a format string; see :hg:`help export` for details.
640 using a format string; see :hg:`help export` for details.
641
641
642 Each member added to an archive file has a directory prefix
642 Each member added to an archive file has a directory prefix
643 prepended. Use -p/--prefix to specify a format string for the
643 prepended. Use -p/--prefix to specify a format string for the
644 prefix. The default is the basename of the archive, with suffixes
644 prefix. The default is the basename of the archive, with suffixes
645 removed.
645 removed.
646
646
647 Returns 0 on success.
647 Returns 0 on success.
648 """
648 """
649
649
650 rev = opts.get('rev')
650 rev = opts.get('rev')
651 if rev:
651 if rev:
652 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
652 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
653 ctx = logcmdutil.revsingle(repo, rev)
653 ctx = logcmdutil.revsingle(repo, rev)
654 if not ctx:
654 if not ctx:
655 raise error.InputError(
655 raise error.InputError(
656 _(b'no working directory: please specify a revision')
656 _(b'no working directory: please specify a revision')
657 )
657 )
658 node = ctx.node()
658 node = ctx.node()
659 dest = cmdutil.makefilename(ctx, dest)
659 dest = cmdutil.makefilename(ctx, dest)
660 if os.path.realpath(dest) == repo.root:
660 if os.path.realpath(dest) == repo.root:
661 raise error.InputError(_(b'repository root cannot be destination'))
661 raise error.InputError(_(b'repository root cannot be destination'))
662
662
663 kind = opts.get('type') or archival.guesskind(dest) or b'files'
663 kind = opts.get('type') or archival.guesskind(dest) or b'files'
664 prefix = opts.get('prefix')
664 prefix = opts.get('prefix')
665
665
666 if dest == b'-':
666 if dest == b'-':
667 if kind == b'files':
667 if kind == b'files':
668 raise error.InputError(_(b'cannot archive plain files to stdout'))
668 raise error.InputError(_(b'cannot archive plain files to stdout'))
669 dest = cmdutil.makefileobj(ctx, dest)
669 dest = cmdutil.makefileobj(ctx, dest)
670 if not prefix:
670 if not prefix:
671 prefix = os.path.basename(repo.root) + b'-%h'
671 prefix = os.path.basename(repo.root) + b'-%h'
672
672
673 prefix = cmdutil.makefilename(ctx, prefix)
673 prefix = cmdutil.makefilename(ctx, prefix)
674 match = scmutil.match(ctx, [], pycompat.byteskwargs(opts))
674 match = scmutil.match(ctx, [], pycompat.byteskwargs(opts))
675 archival.archive(
675 archival.archive(
676 repo,
676 repo,
677 dest,
677 dest,
678 node,
678 node,
679 kind,
679 kind,
680 not opts.get('no_decode'),
680 not opts.get('no_decode'),
681 match,
681 match,
682 prefix,
682 prefix,
683 subrepos=opts.get('subrepos'),
683 subrepos=opts.get('subrepos'),
684 )
684 )
685
685
686
686
687 @command(
687 @command(
688 b'backout',
688 b'backout',
689 [
689 [
690 (
690 (
691 b'',
691 b'',
692 b'merge',
692 b'merge',
693 None,
693 None,
694 _(b'merge with old dirstate parent after backout'),
694 _(b'merge with old dirstate parent after backout'),
695 ),
695 ),
696 (
696 (
697 b'',
697 b'',
698 b'commit',
698 b'commit',
699 None,
699 None,
700 _(b'commit if no conflicts were encountered (DEPRECATED)'),
700 _(b'commit if no conflicts were encountered (DEPRECATED)'),
701 ),
701 ),
702 (b'', b'no-commit', None, _(b'do not commit')),
702 (b'', b'no-commit', None, _(b'do not commit')),
703 (
703 (
704 b'',
704 b'',
705 b'parent',
705 b'parent',
706 b'',
706 b'',
707 _(b'parent to choose when backing out merge (DEPRECATED)'),
707 _(b'parent to choose when backing out merge (DEPRECATED)'),
708 _(b'REV'),
708 _(b'REV'),
709 ),
709 ),
710 (b'r', b'rev', b'', _(b'revision to backout'), _(b'REV')),
710 (b'r', b'rev', b'', _(b'revision to backout'), _(b'REV')),
711 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
711 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
712 ]
712 ]
713 + mergetoolopts
713 + mergetoolopts
714 + walkopts
714 + walkopts
715 + commitopts
715 + commitopts
716 + commitopts2,
716 + commitopts2,
717 _(b'[OPTION]... [-r] REV'),
717 _(b'[OPTION]... [-r] REV'),
718 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
718 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
719 )
719 )
720 def backout(ui, repo, node=None, rev=None, **opts):
720 def backout(ui, repo, node=None, rev=None, **opts):
721 """reverse effect of earlier changeset
721 """reverse effect of earlier changeset
722
722
723 Prepare a new changeset with the effect of REV undone in the
723 Prepare a new changeset with the effect of REV undone in the
724 current working directory. If no conflicts were encountered,
724 current working directory. If no conflicts were encountered,
725 it will be committed immediately.
725 it will be committed immediately.
726
726
727 If REV is the parent of the working directory, then this new changeset
727 If REV is the parent of the working directory, then this new changeset
728 is committed automatically (unless --no-commit is specified).
728 is committed automatically (unless --no-commit is specified).
729
729
730 .. note::
730 .. note::
731
731
732 :hg:`backout` cannot be used to fix either an unwanted or
732 :hg:`backout` cannot be used to fix either an unwanted or
733 incorrect merge.
733 incorrect merge.
734
734
735 .. container:: verbose
735 .. container:: verbose
736
736
737 Examples:
737 Examples:
738
738
739 - Reverse the effect of the parent of the working directory.
739 - Reverse the effect of the parent of the working directory.
740 This backout will be committed immediately::
740 This backout will be committed immediately::
741
741
742 hg backout -r .
742 hg backout -r .
743
743
744 - Reverse the effect of previous bad revision 23::
744 - Reverse the effect of previous bad revision 23::
745
745
746 hg backout -r 23
746 hg backout -r 23
747
747
748 - Reverse the effect of previous bad revision 23 and
748 - Reverse the effect of previous bad revision 23 and
749 leave changes uncommitted::
749 leave changes uncommitted::
750
750
751 hg backout -r 23 --no-commit
751 hg backout -r 23 --no-commit
752 hg commit -m "Backout revision 23"
752 hg commit -m "Backout revision 23"
753
753
754 By default, the pending changeset will have one parent,
754 By default, the pending changeset will have one parent,
755 maintaining a linear history. With --merge, the pending
755 maintaining a linear history. With --merge, the pending
756 changeset will instead have two parents: the old parent of the
756 changeset will instead have two parents: the old parent of the
757 working directory and a new child of REV that simply undoes REV.
757 working directory and a new child of REV that simply undoes REV.
758
758
759 Before version 1.7, the behavior without --merge was equivalent
759 Before version 1.7, the behavior without --merge was equivalent
760 to specifying --merge followed by :hg:`update --clean .` to
760 to specifying --merge followed by :hg:`update --clean .` to
761 cancel the merge and leave the child of REV as a head to be
761 cancel the merge and leave the child of REV as a head to be
762 merged separately.
762 merged separately.
763
763
764 See :hg:`help dates` for a list of formats valid for -d/--date.
764 See :hg:`help dates` for a list of formats valid for -d/--date.
765
765
766 See :hg:`help revert` for a way to restore files to the state
766 See :hg:`help revert` for a way to restore files to the state
767 of another revision.
767 of another revision.
768
768
769 Returns 0 on success, 1 if nothing to backout or there are unresolved
769 Returns 0 on success, 1 if nothing to backout or there are unresolved
770 files.
770 files.
771 """
771 """
772 with repo.wlock(), repo.lock():
772 with repo.wlock(), repo.lock():
773 return _dobackout(ui, repo, node, rev, **opts)
773 return _dobackout(ui, repo, node, rev, **opts)
774
774
775
775
776 def _dobackout(ui, repo, node=None, rev=None, **opts):
776 def _dobackout(ui, repo, node=None, rev=None, **opts):
777 cmdutil.check_incompatible_arguments(opts, 'no_commit', ['commit', 'merge'])
777 cmdutil.check_incompatible_arguments(opts, 'no_commit', ['commit', 'merge'])
778
778
779 if rev and node:
779 if rev and node:
780 raise error.InputError(_(b"please specify just one revision"))
780 raise error.InputError(_(b"please specify just one revision"))
781
781
782 if not rev:
782 if not rev:
783 rev = node
783 rev = node
784
784
785 if not rev:
785 if not rev:
786 raise error.InputError(_(b"please specify a revision to backout"))
786 raise error.InputError(_(b"please specify a revision to backout"))
787
787
788 date = opts.get('date')
788 date = opts.get('date')
789 if date:
789 if date:
790 opts['date'] = dateutil.parsedate(date)
790 opts['date'] = dateutil.parsedate(date)
791
791
792 cmdutil.checkunfinished(repo)
792 cmdutil.checkunfinished(repo)
793 cmdutil.bailifchanged(repo)
793 cmdutil.bailifchanged(repo)
794 ctx = logcmdutil.revsingle(repo, rev)
794 ctx = logcmdutil.revsingle(repo, rev)
795 node = ctx.node()
795 node = ctx.node()
796
796
797 op1, op2 = repo.dirstate.parents()
797 op1, op2 = repo.dirstate.parents()
798 if not repo.changelog.isancestor(node, op1):
798 if not repo.changelog.isancestor(node, op1):
799 raise error.InputError(
799 raise error.InputError(
800 _(b'cannot backout change that is not an ancestor')
800 _(b'cannot backout change that is not an ancestor')
801 )
801 )
802
802
803 p1, p2 = repo.changelog.parents(node)
803 p1, p2 = repo.changelog.parents(node)
804 if p1 == repo.nullid:
804 if p1 == repo.nullid:
805 raise error.InputError(_(b'cannot backout a change with no parents'))
805 raise error.InputError(_(b'cannot backout a change with no parents'))
806 if p2 != repo.nullid:
806 if p2 != repo.nullid:
807 if not opts.get('parent'):
807 if not opts.get('parent'):
808 raise error.InputError(_(b'cannot backout a merge changeset'))
808 raise error.InputError(_(b'cannot backout a merge changeset'))
809 p = repo.lookup(opts['parent'])
809 p = repo.lookup(opts['parent'])
810 if p not in (p1, p2):
810 if p not in (p1, p2):
811 raise error.InputError(
811 raise error.InputError(
812 _(b'%s is not a parent of %s') % (short(p), short(node))
812 _(b'%s is not a parent of %s') % (short(p), short(node))
813 )
813 )
814 parent = p
814 parent = p
815 else:
815 else:
816 if opts.get('parent'):
816 if opts.get('parent'):
817 raise error.InputError(
817 raise error.InputError(
818 _(b'cannot use --parent on non-merge changeset')
818 _(b'cannot use --parent on non-merge changeset')
819 )
819 )
820 parent = p1
820 parent = p1
821
821
822 # the backout should appear on the same branch
822 # the backout should appear on the same branch
823 branch = repo.dirstate.branch()
823 branch = repo.dirstate.branch()
824 bheads = repo.branchheads(branch)
824 bheads = repo.branchheads(branch)
825 rctx = scmutil.revsingle(repo, hex(parent))
825 rctx = scmutil.revsingle(repo, hex(parent))
826 if not opts.get('merge') and op1 != node:
826 if not opts.get('merge') and op1 != node:
827 with repo.transaction(b"backout"):
827 with repo.transaction(b"backout"):
828 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
828 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
829 with ui.configoverride(overrides, b'backout'):
829 with ui.configoverride(overrides, b'backout'):
830 stats = mergemod.back_out(ctx, parent=repo[parent])
830 stats = mergemod.back_out(ctx, parent=repo[parent])
831 repo.setparents(op1, op2)
831 repo.setparents(op1, op2)
832 hg._showstats(repo, stats)
832 hg._showstats(repo, stats)
833 if stats.unresolvedcount:
833 if stats.unresolvedcount:
834 repo.ui.status(
834 repo.ui.status(
835 _(b"use 'hg resolve' to retry unresolved file merges\n")
835 _(b"use 'hg resolve' to retry unresolved file merges\n")
836 )
836 )
837 return 1
837 return 1
838 else:
838 else:
839 hg.clean(repo, node, show_stats=False)
839 hg.clean(repo, node, show_stats=False)
840 repo.dirstate.setbranch(branch, repo.currenttransaction())
840 repo.dirstate.setbranch(branch, repo.currenttransaction())
841 cmdutil.revert(ui, repo, rctx)
841 cmdutil.revert(ui, repo, rctx)
842
842
843 if opts.get('no_commit'):
843 if opts.get('no_commit'):
844 msg = _(b"changeset %s backed out, don't forget to commit.\n")
844 msg = _(b"changeset %s backed out, don't forget to commit.\n")
845 ui.status(msg % short(node))
845 ui.status(msg % short(node))
846 return 0
846 return 0
847
847
848 def commitfunc(ui, repo, message, match, opts):
848 def commitfunc(ui, repo, message, match, opts):
849 editform = b'backout'
849 editform = b'backout'
850 e = cmdutil.getcommiteditor(
850 e = cmdutil.getcommiteditor(
851 editform=editform, **pycompat.strkwargs(opts)
851 editform=editform, **pycompat.strkwargs(opts)
852 )
852 )
853 if not message:
853 if not message:
854 # we don't translate commit messages
854 # we don't translate commit messages
855 message = b"Backed out changeset %s" % short(node)
855 message = b"Backed out changeset %s" % short(node)
856 e = cmdutil.getcommiteditor(edit=True, editform=editform)
856 e = cmdutil.getcommiteditor(edit=True, editform=editform)
857 return repo.commit(
857 return repo.commit(
858 message, opts.get(b'user'), opts.get(b'date'), match, editor=e
858 message, opts.get(b'user'), opts.get(b'date'), match, editor=e
859 )
859 )
860
860
861 # save to detect changes
861 # save to detect changes
862 tip = repo.changelog.tip()
862 tip = repo.changelog.tip()
863
863
864 newnode = cmdutil.commit(
864 newnode = cmdutil.commit(
865 ui, repo, commitfunc, [], pycompat.byteskwargs(opts)
865 ui, repo, commitfunc, [], pycompat.byteskwargs(opts)
866 )
866 )
867 if not newnode:
867 if not newnode:
868 ui.status(_(b"nothing changed\n"))
868 ui.status(_(b"nothing changed\n"))
869 return 1
869 return 1
870 cmdutil.commitstatus(repo, newnode, branch, bheads, tip)
870 cmdutil.commitstatus(repo, newnode, branch, bheads, tip)
871
871
872 def nice(node):
872 def nice(node):
873 return b'%d:%s' % (repo.changelog.rev(node), short(node))
873 return b'%d:%s' % (repo.changelog.rev(node), short(node))
874
874
875 ui.status(
875 ui.status(
876 _(b'changeset %s backs out changeset %s\n')
876 _(b'changeset %s backs out changeset %s\n')
877 % (nice(newnode), nice(node))
877 % (nice(newnode), nice(node))
878 )
878 )
879 if opts.get('merge') and op1 != node:
879 if opts.get('merge') and op1 != node:
880 hg.clean(repo, op1, show_stats=False)
880 hg.clean(repo, op1, show_stats=False)
881 ui.status(_(b'merging with changeset %s\n') % nice(newnode))
881 ui.status(_(b'merging with changeset %s\n') % nice(newnode))
882 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
882 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
883 with ui.configoverride(overrides, b'backout'):
883 with ui.configoverride(overrides, b'backout'):
884 return hg.merge(repo[b'tip'])
884 return hg.merge(repo[b'tip'])
885 return 0
885 return 0
886
886
887
887
888 @command(
888 @command(
889 b'bisect',
889 b'bisect',
890 [
890 [
891 (b'r', b'reset', False, _(b'reset bisect state')),
891 (b'r', b'reset', False, _(b'reset bisect state')),
892 (b'g', b'good', False, _(b'mark changeset good')),
892 (b'g', b'good', False, _(b'mark changeset good')),
893 (b'b', b'bad', False, _(b'mark changeset bad')),
893 (b'b', b'bad', False, _(b'mark changeset bad')),
894 (b's', b'skip', False, _(b'skip testing changeset')),
894 (b's', b'skip', False, _(b'skip testing changeset')),
895 (b'e', b'extend', False, _(b'extend the bisect range')),
895 (b'e', b'extend', False, _(b'extend the bisect range')),
896 (
896 (
897 b'c',
897 b'c',
898 b'command',
898 b'command',
899 b'',
899 b'',
900 _(b'use command to check changeset state'),
900 _(b'use command to check changeset state'),
901 _(b'CMD'),
901 _(b'CMD'),
902 ),
902 ),
903 (b'U', b'noupdate', False, _(b'do not update to target')),
903 (b'U', b'noupdate', False, _(b'do not update to target')),
904 ],
904 ],
905 _(b"[-gbsr] [-U] [-c CMD] [REV]"),
905 _(b"[-gbsr] [-U] [-c CMD] [REV]"),
906 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
906 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
907 )
907 )
908 def bisect(
908 def bisect(
909 ui,
909 ui,
910 repo,
910 repo,
911 positional_1=None,
911 positional_1=None,
912 positional_2=None,
912 positional_2=None,
913 command=None,
913 command=None,
914 reset=None,
914 reset=None,
915 good=None,
915 good=None,
916 bad=None,
916 bad=None,
917 skip=None,
917 skip=None,
918 extend=None,
918 extend=None,
919 noupdate=None,
919 noupdate=None,
920 ):
920 ):
921 """subdivision search of changesets
921 """subdivision search of changesets
922
922
923 This command helps to find changesets which introduce problems. To
923 This command helps to find changesets which introduce problems. To
924 use, mark the earliest changeset you know exhibits the problem as
924 use, mark the earliest changeset you know exhibits the problem as
925 bad, then mark the latest changeset which is free from the problem
925 bad, then mark the latest changeset which is free from the problem
926 as good. Bisect will update your working directory to a revision
926 as good. Bisect will update your working directory to a revision
927 for testing (unless the -U/--noupdate option is specified). Once
927 for testing (unless the -U/--noupdate option is specified). Once
928 you have performed tests, mark the working directory as good or
928 you have performed tests, mark the working directory as good or
929 bad, and bisect will either update to another candidate changeset
929 bad, and bisect will either update to another candidate changeset
930 or announce that it has found the bad revision.
930 or announce that it has found the bad revision.
931
931
932 As a shortcut, you can also use the revision argument to mark a
932 As a shortcut, you can also use the revision argument to mark a
933 revision as good or bad without checking it out first.
933 revision as good or bad without checking it out first.
934
934
935 If you supply a command, it will be used for automatic bisection.
935 If you supply a command, it will be used for automatic bisection.
936 The environment variable HG_NODE will contain the ID of the
936 The environment variable HG_NODE will contain the ID of the
937 changeset being tested. The exit status of the command will be
937 changeset being tested. The exit status of the command will be
938 used to mark revisions as good or bad: status 0 means good, 125
938 used to mark revisions as good or bad: status 0 means good, 125
939 means to skip the revision, 127 (command not found) will abort the
939 means to skip the revision, 127 (command not found) will abort the
940 bisection, and any other non-zero exit status means the revision
940 bisection, and any other non-zero exit status means the revision
941 is bad.
941 is bad.
942
942
943 .. container:: verbose
943 .. container:: verbose
944
944
945 Some examples:
945 Some examples:
946
946
947 - start a bisection with known bad revision 34, and good revision 12::
947 - start a bisection with known bad revision 34, and good revision 12::
948
948
949 hg bisect --bad 34
949 hg bisect --bad 34
950 hg bisect --good 12
950 hg bisect --good 12
951
951
952 - advance the current bisection by marking current revision as good or
952 - advance the current bisection by marking current revision as good or
953 bad::
953 bad::
954
954
955 hg bisect --good
955 hg bisect --good
956 hg bisect --bad
956 hg bisect --bad
957
957
958 - mark the current revision, or a known revision, to be skipped (e.g. if
958 - mark the current revision, or a known revision, to be skipped (e.g. if
959 that revision is not usable because of another issue)::
959 that revision is not usable because of another issue)::
960
960
961 hg bisect --skip
961 hg bisect --skip
962 hg bisect --skip 23
962 hg bisect --skip 23
963
963
964 - skip all revisions that do not touch directories ``foo`` or ``bar``::
964 - skip all revisions that do not touch directories ``foo`` or ``bar``::
965
965
966 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
966 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
967
967
968 - forget the current bisection::
968 - forget the current bisection::
969
969
970 hg bisect --reset
970 hg bisect --reset
971
971
972 - use 'make && make tests' to automatically find the first broken
972 - use 'make && make tests' to automatically find the first broken
973 revision::
973 revision::
974
974
975 hg bisect --reset
975 hg bisect --reset
976 hg bisect --bad 34
976 hg bisect --bad 34
977 hg bisect --good 12
977 hg bisect --good 12
978 hg bisect --command "make && make tests"
978 hg bisect --command "make && make tests"
979
979
980 - see all changesets whose states are already known in the current
980 - see all changesets whose states are already known in the current
981 bisection::
981 bisection::
982
982
983 hg log -r "bisect(pruned)"
983 hg log -r "bisect(pruned)"
984
984
985 - see the changeset currently being bisected (especially useful
985 - see the changeset currently being bisected (especially useful
986 if running with -U/--noupdate)::
986 if running with -U/--noupdate)::
987
987
988 hg log -r "bisect(current)"
988 hg log -r "bisect(current)"
989
989
990 - see all changesets that took part in the current bisection::
990 - see all changesets that took part in the current bisection::
991
991
992 hg log -r "bisect(range)"
992 hg log -r "bisect(range)"
993
993
994 - you can even get a nice graph::
994 - you can even get a nice graph::
995
995
996 hg log --graph -r "bisect(range)"
996 hg log --graph -r "bisect(range)"
997
997
998 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
998 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
999
999
1000 Returns 0 on success.
1000 Returns 0 on success.
1001 """
1001 """
1002 rev = []
1002 rev = []
1003 # backward compatibility
1003 # backward compatibility
1004 if positional_1 in (b"good", b"bad", b"reset", b"init"):
1004 if positional_1 in (b"good", b"bad", b"reset", b"init"):
1005 ui.warn(_(b"(use of 'hg bisect <cmd>' is deprecated)\n"))
1005 ui.warn(_(b"(use of 'hg bisect <cmd>' is deprecated)\n"))
1006 cmd = positional_1
1006 cmd = positional_1
1007 rev.append(positional_2)
1007 rev.append(positional_2)
1008 if cmd == b"good":
1008 if cmd == b"good":
1009 good = True
1009 good = True
1010 elif cmd == b"bad":
1010 elif cmd == b"bad":
1011 bad = True
1011 bad = True
1012 else:
1012 else:
1013 reset = True
1013 reset = True
1014 elif positional_2:
1014 elif positional_2:
1015 raise error.InputError(_(b'incompatible arguments'))
1015 raise error.InputError(_(b'incompatible arguments'))
1016 elif positional_1 is not None:
1016 elif positional_1 is not None:
1017 rev.append(positional_1)
1017 rev.append(positional_1)
1018
1018
1019 incompatibles = {
1019 incompatibles = {
1020 b'--bad': bad,
1020 b'--bad': bad,
1021 b'--command': bool(command),
1021 b'--command': bool(command),
1022 b'--extend': extend,
1022 b'--extend': extend,
1023 b'--good': good,
1023 b'--good': good,
1024 b'--reset': reset,
1024 b'--reset': reset,
1025 b'--skip': skip,
1025 b'--skip': skip,
1026 }
1026 }
1027
1027
1028 enabled = [x for x in incompatibles if incompatibles[x]]
1028 enabled = [x for x in incompatibles if incompatibles[x]]
1029
1029
1030 if len(enabled) > 1:
1030 if len(enabled) > 1:
1031 raise error.InputError(
1031 raise error.InputError(
1032 _(b'%s and %s are incompatible') % tuple(sorted(enabled)[0:2])
1032 _(b'%s and %s are incompatible') % tuple(sorted(enabled)[0:2])
1033 )
1033 )
1034
1034
1035 if reset:
1035 if reset:
1036 hbisect.resetstate(repo)
1036 hbisect.resetstate(repo)
1037 return
1037 return
1038
1038
1039 state = hbisect.load_state(repo)
1039 state = hbisect.load_state(repo)
1040
1040
1041 if rev:
1041 if rev:
1042 revs = logcmdutil.revrange(repo, rev)
1042 revs = logcmdutil.revrange(repo, rev)
1043 goodnodes = state[b'good']
1043 goodnodes = state[b'good']
1044 badnodes = state[b'bad']
1044 badnodes = state[b'bad']
1045 if goodnodes and badnodes:
1045 if goodnodes and badnodes:
1046 candidates = repo.revs(b'(%ln)::(%ln)', goodnodes, badnodes)
1046 candidates = repo.revs(b'(%ln)::(%ln)', goodnodes, badnodes)
1047 candidates += repo.revs(b'(%ln)::(%ln)', badnodes, goodnodes)
1047 candidates += repo.revs(b'(%ln)::(%ln)', badnodes, goodnodes)
1048 revs = candidates & revs
1048 revs = candidates & revs
1049 nodes = [repo.changelog.node(i) for i in revs]
1049 nodes = [repo.changelog.node(i) for i in revs]
1050 else:
1050 else:
1051 nodes = [repo.lookup(b'.')]
1051 nodes = [repo.lookup(b'.')]
1052
1052
1053 # update state
1053 # update state
1054 if good or bad or skip:
1054 if good or bad or skip:
1055 if good:
1055 if good:
1056 state[b'good'] += nodes
1056 state[b'good'] += nodes
1057 elif bad:
1057 elif bad:
1058 state[b'bad'] += nodes
1058 state[b'bad'] += nodes
1059 elif skip:
1059 elif skip:
1060 state[b'skip'] += nodes
1060 state[b'skip'] += nodes
1061 hbisect.save_state(repo, state)
1061 hbisect.save_state(repo, state)
1062 if not (state[b'good'] and state[b'bad']):
1062 if not (state[b'good'] and state[b'bad']):
1063 return
1063 return
1064
1064
1065 def mayupdate(repo, node, show_stats=True):
1065 def mayupdate(repo, node, show_stats=True):
1066 """common used update sequence"""
1066 """common used update sequence"""
1067 if noupdate:
1067 if noupdate:
1068 return
1068 return
1069 cmdutil.checkunfinished(repo)
1069 cmdutil.checkunfinished(repo)
1070 cmdutil.bailifchanged(repo)
1070 cmdutil.bailifchanged(repo)
1071 return hg.clean(repo, node, show_stats=show_stats)
1071 return hg.clean(repo, node, show_stats=show_stats)
1072
1072
1073 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
1073 displayer = logcmdutil.changesetdisplayer(ui, repo, {})
1074
1074
1075 if command:
1075 if command:
1076 changesets = 1
1076 changesets = 1
1077 if noupdate:
1077 if noupdate:
1078 try:
1078 try:
1079 node = state[b'current'][0]
1079 node = state[b'current'][0]
1080 except LookupError:
1080 except LookupError:
1081 raise error.StateError(
1081 raise error.StateError(
1082 _(
1082 _(
1083 b'current bisect revision is unknown - '
1083 b'current bisect revision is unknown - '
1084 b'start a new bisect to fix'
1084 b'start a new bisect to fix'
1085 )
1085 )
1086 )
1086 )
1087 else:
1087 else:
1088 node, p2 = repo.dirstate.parents()
1088 node, p2 = repo.dirstate.parents()
1089 if p2 != repo.nullid:
1089 if p2 != repo.nullid:
1090 raise error.StateError(_(b'current bisect revision is a merge'))
1090 raise error.StateError(_(b'current bisect revision is a merge'))
1091 if rev:
1091 if rev:
1092 if not nodes:
1092 if not nodes:
1093 raise error.InputError(_(b'empty revision set'))
1093 raise error.InputError(_(b'empty revision set'))
1094 node = repo[nodes[-1]].node()
1094 node = repo[nodes[-1]].node()
1095 with hbisect.restore_state(repo, state, node):
1095 with hbisect.restore_state(repo, state, node):
1096 while changesets:
1096 while changesets:
1097 # update state
1097 # update state
1098 state[b'current'] = [node]
1098 state[b'current'] = [node]
1099 hbisect.save_state(repo, state)
1099 hbisect.save_state(repo, state)
1100 status = ui.system(
1100 status = ui.system(
1101 command,
1101 command,
1102 environ={b'HG_NODE': hex(node)},
1102 environ={b'HG_NODE': hex(node)},
1103 blockedtag=b'bisect_check',
1103 blockedtag=b'bisect_check',
1104 )
1104 )
1105 if status == 125:
1105 if status == 125:
1106 transition = b"skip"
1106 transition = b"skip"
1107 elif status == 0:
1107 elif status == 0:
1108 transition = b"good"
1108 transition = b"good"
1109 # status < 0 means process was killed
1109 # status < 0 means process was killed
1110 elif status == 127:
1110 elif status == 127:
1111 raise error.Abort(_(b"failed to execute %s") % command)
1111 raise error.Abort(_(b"failed to execute %s") % command)
1112 elif status < 0:
1112 elif status < 0:
1113 raise error.Abort(_(b"%s killed") % command)
1113 raise error.Abort(_(b"%s killed") % command)
1114 else:
1114 else:
1115 transition = b"bad"
1115 transition = b"bad"
1116 state[transition].append(node)
1116 state[transition].append(node)
1117 ctx = repo[node]
1117 ctx = repo[node]
1118 summary = cmdutil.format_changeset_summary(ui, ctx, b'bisect')
1118 summary = cmdutil.format_changeset_summary(ui, ctx, b'bisect')
1119 ui.status(_(b'changeset %s: %s\n') % (summary, transition))
1119 ui.status(_(b'changeset %s: %s\n') % (summary, transition))
1120 hbisect.checkstate(state)
1120 hbisect.checkstate(state)
1121 # bisect
1121 # bisect
1122 nodes, changesets, bgood = hbisect.bisect(repo, state)
1122 nodes, changesets, bgood = hbisect.bisect(repo, state)
1123 # update to next check
1123 # update to next check
1124 node = nodes[0]
1124 node = nodes[0]
1125 mayupdate(repo, node, show_stats=False)
1125 mayupdate(repo, node, show_stats=False)
1126 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
1126 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
1127 return
1127 return
1128
1128
1129 hbisect.checkstate(state)
1129 hbisect.checkstate(state)
1130
1130
1131 # actually bisect
1131 # actually bisect
1132 nodes, changesets, good = hbisect.bisect(repo, state)
1132 nodes, changesets, good = hbisect.bisect(repo, state)
1133 if extend:
1133 if extend:
1134 if not changesets:
1134 if not changesets:
1135 extendctx = hbisect.extendrange(repo, state, nodes, good)
1135 extendctx = hbisect.extendrange(repo, state, nodes, good)
1136 if extendctx is not None:
1136 if extendctx is not None:
1137 ui.write(
1137 ui.write(
1138 _(b"Extending search to changeset %s\n")
1138 _(b"Extending search to changeset %s\n")
1139 % cmdutil.format_changeset_summary(ui, extendctx, b'bisect')
1139 % cmdutil.format_changeset_summary(ui, extendctx, b'bisect')
1140 )
1140 )
1141 state[b'current'] = [extendctx.node()]
1141 state[b'current'] = [extendctx.node()]
1142 hbisect.save_state(repo, state)
1142 hbisect.save_state(repo, state)
1143 return mayupdate(repo, extendctx.node())
1143 return mayupdate(repo, extendctx.node())
1144 raise error.StateError(_(b"nothing to extend"))
1144 raise error.StateError(_(b"nothing to extend"))
1145
1145
1146 if changesets == 0:
1146 if changesets == 0:
1147 hbisect.printresult(ui, repo, state, displayer, nodes, good)
1147 hbisect.printresult(ui, repo, state, displayer, nodes, good)
1148 else:
1148 else:
1149 assert len(nodes) == 1 # only a single node can be tested next
1149 assert len(nodes) == 1 # only a single node can be tested next
1150 node = nodes[0]
1150 node = nodes[0]
1151 # compute the approximate number of remaining tests
1151 # compute the approximate number of remaining tests
1152 tests, size = 0, 2
1152 tests, size = 0, 2
1153 while size <= changesets:
1153 while size <= changesets:
1154 tests, size = tests + 1, size * 2
1154 tests, size = tests + 1, size * 2
1155 rev = repo.changelog.rev(node)
1155 rev = repo.changelog.rev(node)
1156 summary = cmdutil.format_changeset_summary(ui, repo[rev], b'bisect')
1156 summary = cmdutil.format_changeset_summary(ui, repo[rev], b'bisect')
1157 ui.write(
1157 ui.write(
1158 _(
1158 _(
1159 b"Testing changeset %s "
1159 b"Testing changeset %s "
1160 b"(%d changesets remaining, ~%d tests)\n"
1160 b"(%d changesets remaining, ~%d tests)\n"
1161 )
1161 )
1162 % (summary, changesets, tests)
1162 % (summary, changesets, tests)
1163 )
1163 )
1164 state[b'current'] = [node]
1164 state[b'current'] = [node]
1165 hbisect.save_state(repo, state)
1165 hbisect.save_state(repo, state)
1166 return mayupdate(repo, node)
1166 return mayupdate(repo, node)
1167
1167
1168
1168
1169 @command(
1169 @command(
1170 b'bookmarks|bookmark',
1170 b'bookmarks|bookmark',
1171 [
1171 [
1172 (b'f', b'force', False, _(b'force')),
1172 (b'f', b'force', False, _(b'force')),
1173 (b'r', b'rev', b'', _(b'revision for bookmark action'), _(b'REV')),
1173 (b'r', b'rev', b'', _(b'revision for bookmark action'), _(b'REV')),
1174 (b'd', b'delete', False, _(b'delete a given bookmark')),
1174 (b'd', b'delete', False, _(b'delete a given bookmark')),
1175 (b'm', b'rename', b'', _(b'rename a given bookmark'), _(b'OLD')),
1175 (b'm', b'rename', b'', _(b'rename a given bookmark'), _(b'OLD')),
1176 (b'i', b'inactive', False, _(b'mark a bookmark inactive')),
1176 (b'i', b'inactive', False, _(b'mark a bookmark inactive')),
1177 (b'l', b'list', False, _(b'list existing bookmarks')),
1177 (b'l', b'list', False, _(b'list existing bookmarks')),
1178 ]
1178 ]
1179 + formatteropts,
1179 + formatteropts,
1180 _(b'hg bookmarks [OPTIONS]... [NAME]...'),
1180 _(b'hg bookmarks [OPTIONS]... [NAME]...'),
1181 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1181 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1182 )
1182 )
1183 def bookmark(ui, repo, *names, **opts):
1183 def bookmark(ui, repo, *names, **opts):
1184 """create a new bookmark or list existing bookmarks
1184 """create a new bookmark or list existing bookmarks
1185
1185
1186 Bookmarks are labels on changesets to help track lines of development.
1186 Bookmarks are labels on changesets to help track lines of development.
1187 Bookmarks are unversioned and can be moved, renamed and deleted.
1187 Bookmarks are unversioned and can be moved, renamed and deleted.
1188 Deleting or moving a bookmark has no effect on the associated changesets.
1188 Deleting or moving a bookmark has no effect on the associated changesets.
1189
1189
1190 Creating or updating to a bookmark causes it to be marked as 'active'.
1190 Creating or updating to a bookmark causes it to be marked as 'active'.
1191 The active bookmark is indicated with a '*'.
1191 The active bookmark is indicated with a '*'.
1192 When a commit is made, the active bookmark will advance to the new commit.
1192 When a commit is made, the active bookmark will advance to the new commit.
1193 A plain :hg:`update` will also advance an active bookmark, if possible.
1193 A plain :hg:`update` will also advance an active bookmark, if possible.
1194 Updating away from a bookmark will cause it to be deactivated.
1194 Updating away from a bookmark will cause it to be deactivated.
1195
1195
1196 Bookmarks can be pushed and pulled between repositories (see
1196 Bookmarks can be pushed and pulled between repositories (see
1197 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
1197 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
1198 diverged, a new 'divergent bookmark' of the form 'name@path' will
1198 diverged, a new 'divergent bookmark' of the form 'name@path' will
1199 be created. Using :hg:`merge` will resolve the divergence.
1199 be created. Using :hg:`merge` will resolve the divergence.
1200
1200
1201 Specifying bookmark as '.' to -m/-d/-l options is equivalent to specifying
1201 Specifying bookmark as '.' to -m/-d/-l options is equivalent to specifying
1202 the active bookmark's name.
1202 the active bookmark's name.
1203
1203
1204 A bookmark named '@' has the special property that :hg:`clone` will
1204 A bookmark named '@' has the special property that :hg:`clone` will
1205 check it out by default if it exists.
1205 check it out by default if it exists.
1206
1206
1207 .. container:: verbose
1207 .. container:: verbose
1208
1208
1209 Template:
1209 Template:
1210
1210
1211 The following keywords are supported in addition to the common template
1211 The following keywords are supported in addition to the common template
1212 keywords and functions such as ``{bookmark}``. See also
1212 keywords and functions such as ``{bookmark}``. See also
1213 :hg:`help templates`.
1213 :hg:`help templates`.
1214
1214
1215 :active: Boolean. True if the bookmark is active.
1215 :active: Boolean. True if the bookmark is active.
1216
1216
1217 Examples:
1217 Examples:
1218
1218
1219 - create an active bookmark for a new line of development::
1219 - create an active bookmark for a new line of development::
1220
1220
1221 hg book new-feature
1221 hg book new-feature
1222
1222
1223 - create an inactive bookmark as a place marker::
1223 - create an inactive bookmark as a place marker::
1224
1224
1225 hg book -i reviewed
1225 hg book -i reviewed
1226
1226
1227 - create an inactive bookmark on another changeset::
1227 - create an inactive bookmark on another changeset::
1228
1228
1229 hg book -r .^ tested
1229 hg book -r .^ tested
1230
1230
1231 - rename bookmark turkey to dinner::
1231 - rename bookmark turkey to dinner::
1232
1232
1233 hg book -m turkey dinner
1233 hg book -m turkey dinner
1234
1234
1235 - move the '@' bookmark from another branch::
1235 - move the '@' bookmark from another branch::
1236
1236
1237 hg book -f @
1237 hg book -f @
1238
1238
1239 - print only the active bookmark name::
1239 - print only the active bookmark name::
1240
1240
1241 hg book -ql .
1241 hg book -ql .
1242 """
1242 """
1243 force = opts.get('force')
1243 force = opts.get('force')
1244 rev = opts.get('rev')
1244 rev = opts.get('rev')
1245 inactive = opts.get('inactive') # meaning add/rename to inactive bookmark
1245 inactive = opts.get('inactive') # meaning add/rename to inactive bookmark
1246
1246
1247 action = cmdutil.check_at_most_one_arg(opts, 'delete', 'rename', 'list')
1247 action = cmdutil.check_at_most_one_arg(opts, 'delete', 'rename', 'list')
1248 if action:
1248 if action:
1249 cmdutil.check_incompatible_arguments(opts, action, ['rev'])
1249 cmdutil.check_incompatible_arguments(opts, action, ['rev'])
1250 elif names or rev:
1250 elif names or rev:
1251 action = 'add'
1251 action = 'add'
1252 elif inactive:
1252 elif inactive:
1253 action = 'inactive' # meaning deactivate
1253 action = 'inactive' # meaning deactivate
1254 else:
1254 else:
1255 action = 'list'
1255 action = 'list'
1256
1256
1257 cmdutil.check_incompatible_arguments(opts, 'inactive', ['delete', 'list'])
1257 cmdutil.check_incompatible_arguments(opts, 'inactive', ['delete', 'list'])
1258 if not names and action in {'add', 'delete'}:
1258 if not names and action in {'add', 'delete'}:
1259 raise error.InputError(_(b"bookmark name required"))
1259 raise error.InputError(_(b"bookmark name required"))
1260
1260
1261 if action in {'add', 'delete', 'rename', 'inactive'}:
1261 if action in {'add', 'delete', 'rename', 'inactive'}:
1262 with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr:
1262 with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr:
1263 if action == 'delete':
1263 if action == 'delete':
1264 names = pycompat.maplist(repo._bookmarks.expandname, names)
1264 names = pycompat.maplist(repo._bookmarks.expandname, names)
1265 bookmarks.delete(repo, tr, names)
1265 bookmarks.delete(repo, tr, names)
1266 elif action == 'rename':
1266 elif action == 'rename':
1267 if not names:
1267 if not names:
1268 raise error.InputError(_(b"new bookmark name required"))
1268 raise error.InputError(_(b"new bookmark name required"))
1269 elif len(names) > 1:
1269 elif len(names) > 1:
1270 raise error.InputError(
1270 raise error.InputError(
1271 _(b"only one new bookmark name allowed")
1271 _(b"only one new bookmark name allowed")
1272 )
1272 )
1273 oldname = repo._bookmarks.expandname(opts['rename'])
1273 oldname = repo._bookmarks.expandname(opts['rename'])
1274 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1274 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
1275 elif action == 'add':
1275 elif action == 'add':
1276 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1276 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
1277 elif action == 'inactive':
1277 elif action == 'inactive':
1278 if len(repo._bookmarks) == 0:
1278 if len(repo._bookmarks) == 0:
1279 ui.status(_(b"no bookmarks set\n"))
1279 ui.status(_(b"no bookmarks set\n"))
1280 elif not repo._activebookmark:
1280 elif not repo._activebookmark:
1281 ui.status(_(b"no active bookmark\n"))
1281 ui.status(_(b"no active bookmark\n"))
1282 else:
1282 else:
1283 bookmarks.deactivate(repo)
1283 bookmarks.deactivate(repo)
1284 elif action == 'list':
1284 elif action == 'list':
1285 names = pycompat.maplist(repo._bookmarks.expandname, names)
1285 names = pycompat.maplist(repo._bookmarks.expandname, names)
1286 with ui.formatter(b'bookmarks', pycompat.byteskwargs(opts)) as fm:
1286 with ui.formatter(b'bookmarks', pycompat.byteskwargs(opts)) as fm:
1287 bookmarks.printbookmarks(ui, repo, fm, names)
1287 bookmarks.printbookmarks(ui, repo, fm, names)
1288 else:
1288 else:
1289 raise error.ProgrammingError(
1289 raise error.ProgrammingError(
1290 b'invalid action: %s' % pycompat.sysbytes(action)
1290 b'invalid action: %s' % pycompat.sysbytes(action)
1291 )
1291 )
1292
1292
1293
1293
1294 @command(
1294 @command(
1295 b'branch',
1295 b'branch',
1296 [
1296 [
1297 (
1297 (
1298 b'f',
1298 b'f',
1299 b'force',
1299 b'force',
1300 None,
1300 None,
1301 _(b'set branch name even if it shadows an existing branch'),
1301 _(b'set branch name even if it shadows an existing branch'),
1302 ),
1302 ),
1303 (b'C', b'clean', None, _(b'reset branch name to parent branch name')),
1303 (b'C', b'clean', None, _(b'reset branch name to parent branch name')),
1304 (
1304 (
1305 b'r',
1305 b'r',
1306 b'rev',
1306 b'rev',
1307 [],
1307 [],
1308 _(b'change branches of the given revs (EXPERIMENTAL)'),
1308 _(b'change branches of the given revs (EXPERIMENTAL)'),
1309 ),
1309 ),
1310 ],
1310 ],
1311 _(b'[-fC] [NAME]'),
1311 _(b'[-fC] [NAME]'),
1312 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1312 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1313 )
1313 )
1314 def branch(ui, repo, label=None, **opts):
1314 def branch(ui, repo, label=None, **opts):
1315 """set or show the current branch name
1315 """set or show the current branch name
1316
1316
1317 .. note::
1317 .. note::
1318
1318
1319 Branch names are permanent and global. Use :hg:`bookmark` to create a
1319 Branch names are permanent and global. Use :hg:`bookmark` to create a
1320 light-weight bookmark instead. See :hg:`help glossary` for more
1320 light-weight bookmark instead. See :hg:`help glossary` for more
1321 information about named branches and bookmarks.
1321 information about named branches and bookmarks.
1322
1322
1323 With no argument, show the current branch name. With one argument,
1323 With no argument, show the current branch name. With one argument,
1324 set the working directory branch name (the branch will not exist
1324 set the working directory branch name (the branch will not exist
1325 in the repository until the next commit). Standard practice
1325 in the repository until the next commit). Standard practice
1326 recommends that primary development take place on the 'default'
1326 recommends that primary development take place on the 'default'
1327 branch.
1327 branch.
1328
1328
1329 Unless -f/--force is specified, branch will not let you set a
1329 Unless -f/--force is specified, branch will not let you set a
1330 branch name that already exists.
1330 branch name that already exists.
1331
1331
1332 Use -C/--clean to reset the working directory branch to that of
1332 Use -C/--clean to reset the working directory branch to that of
1333 the parent of the working directory, negating a previous branch
1333 the parent of the working directory, negating a previous branch
1334 change.
1334 change.
1335
1335
1336 Use the command :hg:`update` to switch to an existing branch. Use
1336 Use the command :hg:`update` to switch to an existing branch. Use
1337 :hg:`commit --close-branch` to mark this branch head as closed.
1337 :hg:`commit --close-branch` to mark this branch head as closed.
1338 When all heads of a branch are closed, the branch will be
1338 When all heads of a branch are closed, the branch will be
1339 considered closed.
1339 considered closed.
1340
1340
1341 Returns 0 on success.
1341 Returns 0 on success.
1342 """
1342 """
1343 revs = opts.get('rev')
1343 revs = opts.get('rev')
1344 if label:
1344 if label:
1345 label = label.strip()
1345 label = label.strip()
1346
1346
1347 if not opts.get('clean') and not label:
1347 if not opts.get('clean') and not label:
1348 if revs:
1348 if revs:
1349 raise error.InputError(
1349 raise error.InputError(
1350 _(b"no branch name specified for the revisions")
1350 _(b"no branch name specified for the revisions")
1351 )
1351 )
1352 ui.write(b"%s\n" % repo.dirstate.branch())
1352 ui.write(b"%s\n" % repo.dirstate.branch())
1353 return
1353 return
1354
1354
1355 with repo.wlock():
1355 with repo.wlock():
1356 if opts.get('clean'):
1356 if opts.get('clean'):
1357 label = repo[b'.'].branch()
1357 label = repo[b'.'].branch()
1358 repo.dirstate.setbranch(label, repo.currenttransaction())
1358 repo.dirstate.setbranch(label, repo.currenttransaction())
1359 ui.status(_(b'reset working directory to branch %s\n') % label)
1359 ui.status(_(b'reset working directory to branch %s\n') % label)
1360 elif label:
1360 elif label:
1361
1361
1362 scmutil.checknewlabel(repo, label, b'branch')
1362 scmutil.checknewlabel(repo, label, b'branch')
1363 if revs:
1363 if revs:
1364 return cmdutil.changebranch(ui, repo, revs, label, **opts)
1364 return cmdutil.changebranch(ui, repo, revs, label, **opts)
1365
1365
1366 if not opts.get('force') and label in repo.branchmap():
1366 if not opts.get('force') and label in repo.branchmap():
1367 if label not in [p.branch() for p in repo[None].parents()]:
1367 if label not in [p.branch() for p in repo[None].parents()]:
1368 raise error.InputError(
1368 raise error.InputError(
1369 _(b'a branch of the same name already exists'),
1369 _(b'a branch of the same name already exists'),
1370 # i18n: "it" refers to an existing branch
1370 # i18n: "it" refers to an existing branch
1371 hint=_(b"use 'hg update' to switch to it"),
1371 hint=_(b"use 'hg update' to switch to it"),
1372 )
1372 )
1373
1373
1374 repo.dirstate.setbranch(label, repo.currenttransaction())
1374 repo.dirstate.setbranch(label, repo.currenttransaction())
1375 ui.status(_(b'marked working directory as branch %s\n') % label)
1375 ui.status(_(b'marked working directory as branch %s\n') % label)
1376
1376
1377 # find any open named branches aside from default
1377 # find any open named branches aside from default
1378 for n, h, t, c in repo.branchmap().iterbranches():
1378 for n, h, t, c in repo.branchmap().iterbranches():
1379 if n != b"default" and not c:
1379 if n != b"default" and not c:
1380 return 0
1380 return 0
1381 ui.status(
1381 ui.status(
1382 _(
1382 _(
1383 b'(branches are permanent and global, '
1383 b'(branches are permanent and global, '
1384 b'did you want a bookmark?)\n'
1384 b'did you want a bookmark?)\n'
1385 )
1385 )
1386 )
1386 )
1387
1387
1388
1388
1389 @command(
1389 @command(
1390 b'branches',
1390 b'branches',
1391 [
1391 [
1392 (
1392 (
1393 b'a',
1393 b'a',
1394 b'active',
1394 b'active',
1395 False,
1395 False,
1396 _(b'show only branches that have unmerged heads (DEPRECATED)'),
1396 _(b'show only branches that have unmerged heads (DEPRECATED)'),
1397 ),
1397 ),
1398 (b'c', b'closed', False, _(b'show normal and closed branches')),
1398 (b'c', b'closed', False, _(b'show normal and closed branches')),
1399 (b'r', b'rev', [], _(b'show branch name(s) of the given rev')),
1399 (b'r', b'rev', [], _(b'show branch name(s) of the given rev')),
1400 ]
1400 ]
1401 + formatteropts,
1401 + formatteropts,
1402 _(b'[-c]'),
1402 _(b'[-c]'),
1403 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1403 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
1404 intents={INTENT_READONLY},
1404 intents={INTENT_READONLY},
1405 )
1405 )
1406 def branches(ui, repo, active=False, closed=False, **opts):
1406 def branches(ui, repo, active=False, closed=False, **opts):
1407 """list repository named branches
1407 """list repository named branches
1408
1408
1409 List the repository's named branches, indicating which ones are
1409 List the repository's named branches, indicating which ones are
1410 inactive. If -c/--closed is specified, also list branches which have
1410 inactive. If -c/--closed is specified, also list branches which have
1411 been marked closed (see :hg:`commit --close-branch`).
1411 been marked closed (see :hg:`commit --close-branch`).
1412
1412
1413 Use the command :hg:`update` to switch to an existing branch.
1413 Use the command :hg:`update` to switch to an existing branch.
1414
1414
1415 .. container:: verbose
1415 .. container:: verbose
1416
1416
1417 Template:
1417 Template:
1418
1418
1419 The following keywords are supported in addition to the common template
1419 The following keywords are supported in addition to the common template
1420 keywords and functions such as ``{branch}``. See also
1420 keywords and functions such as ``{branch}``. See also
1421 :hg:`help templates`.
1421 :hg:`help templates`.
1422
1422
1423 :active: Boolean. True if the branch is active.
1423 :active: Boolean. True if the branch is active.
1424 :closed: Boolean. True if the branch is closed.
1424 :closed: Boolean. True if the branch is closed.
1425 :current: Boolean. True if it is the current branch.
1425 :current: Boolean. True if it is the current branch.
1426
1426
1427 Returns 0.
1427 Returns 0.
1428 """
1428 """
1429
1429
1430 revs = opts.get('rev')
1430 revs = opts.get('rev')
1431 selectedbranches = None
1431 selectedbranches = None
1432 if revs:
1432 if revs:
1433 revs = logcmdutil.revrange(repo, revs)
1433 revs = logcmdutil.revrange(repo, revs)
1434 getbi = repo.revbranchcache().branchinfo
1434 getbi = repo.revbranchcache().branchinfo
1435 selectedbranches = {getbi(r)[0] for r in revs}
1435 selectedbranches = {getbi(r)[0] for r in revs}
1436
1436
1437 ui.pager(b'branches')
1437 ui.pager(b'branches')
1438 fm = ui.formatter(b'branches', pycompat.byteskwargs(opts))
1438 fm = ui.formatter(b'branches', pycompat.byteskwargs(opts))
1439 hexfunc = fm.hexfunc
1439 hexfunc = fm.hexfunc
1440
1440
1441 allheads = set(repo.heads())
1441 allheads = set(repo.heads())
1442 branches = []
1442 branches = []
1443 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1443 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1444 if selectedbranches is not None and tag not in selectedbranches:
1444 if selectedbranches is not None and tag not in selectedbranches:
1445 continue
1445 continue
1446 isactive = False
1446 isactive = False
1447 if not isclosed:
1447 if not isclosed:
1448 openheads = set(repo.branchmap().iteropen(heads))
1448 openheads = set(repo.branchmap().iteropen(heads))
1449 isactive = bool(openheads & allheads)
1449 isactive = bool(openheads & allheads)
1450 branches.append((tag, repo[tip], isactive, not isclosed))
1450 branches.append((tag, repo[tip], isactive, not isclosed))
1451 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]), reverse=True)
1451 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]), reverse=True)
1452
1452
1453 for tag, ctx, isactive, isopen in branches:
1453 for tag, ctx, isactive, isopen in branches:
1454 if active and not isactive:
1454 if active and not isactive:
1455 continue
1455 continue
1456 if isactive:
1456 if isactive:
1457 label = b'branches.active'
1457 label = b'branches.active'
1458 notice = b''
1458 notice = b''
1459 elif not isopen:
1459 elif not isopen:
1460 if not closed:
1460 if not closed:
1461 continue
1461 continue
1462 label = b'branches.closed'
1462 label = b'branches.closed'
1463 notice = _(b' (closed)')
1463 notice = _(b' (closed)')
1464 else:
1464 else:
1465 label = b'branches.inactive'
1465 label = b'branches.inactive'
1466 notice = _(b' (inactive)')
1466 notice = _(b' (inactive)')
1467 current = tag == repo.dirstate.branch()
1467 current = tag == repo.dirstate.branch()
1468 if current:
1468 if current:
1469 label = b'branches.current'
1469 label = b'branches.current'
1470
1470
1471 fm.startitem()
1471 fm.startitem()
1472 fm.write(b'branch', b'%s', tag, label=label)
1472 fm.write(b'branch', b'%s', tag, label=label)
1473 rev = ctx.rev()
1473 rev = ctx.rev()
1474 padsize = max(31 - len(b"%d" % rev) - encoding.colwidth(tag), 0)
1474 padsize = max(31 - len(b"%d" % rev) - encoding.colwidth(tag), 0)
1475 fmt = b' ' * padsize + b' %d:%s'
1475 fmt = b' ' * padsize + b' %d:%s'
1476 fm.condwrite(
1476 fm.condwrite(
1477 not ui.quiet,
1477 not ui.quiet,
1478 b'rev node',
1478 b'rev node',
1479 fmt,
1479 fmt,
1480 rev,
1480 rev,
1481 hexfunc(ctx.node()),
1481 hexfunc(ctx.node()),
1482 label=b'log.changeset changeset.%s' % ctx.phasestr(),
1482 label=b'log.changeset changeset.%s' % ctx.phasestr(),
1483 )
1483 )
1484 fm.context(ctx=ctx)
1484 fm.context(ctx=ctx)
1485 fm.data(active=isactive, closed=not isopen, current=current)
1485 fm.data(active=isactive, closed=not isopen, current=current)
1486 if not ui.quiet:
1486 if not ui.quiet:
1487 fm.plain(notice)
1487 fm.plain(notice)
1488 fm.plain(b'\n')
1488 fm.plain(b'\n')
1489 fm.end()
1489 fm.end()
1490
1490
1491
1491
1492 @command(
1492 @command(
1493 b'bundle',
1493 b'bundle',
1494 [
1494 [
1495 (
1495 (
1496 b'',
1496 b'',
1497 b'exact',
1497 b'exact',
1498 None,
1498 None,
1499 _(b'compute the base from the revision specified'),
1499 _(b'compute the base from the revision specified'),
1500 ),
1500 ),
1501 (
1501 (
1502 b'f',
1502 b'f',
1503 b'force',
1503 b'force',
1504 None,
1504 None,
1505 _(b'run even when the destination is unrelated'),
1505 _(b'run even when the destination is unrelated'),
1506 ),
1506 ),
1507 (
1507 (
1508 b'r',
1508 b'r',
1509 b'rev',
1509 b'rev',
1510 [],
1510 [],
1511 _(b'a changeset intended to be added to the destination'),
1511 _(b'a changeset intended to be added to the destination'),
1512 _(b'REV'),
1512 _(b'REV'),
1513 ),
1513 ),
1514 (
1514 (
1515 b'b',
1515 b'b',
1516 b'branch',
1516 b'branch',
1517 [],
1517 [],
1518 _(b'a specific branch you would like to bundle'),
1518 _(b'a specific branch you would like to bundle'),
1519 _(b'BRANCH'),
1519 _(b'BRANCH'),
1520 ),
1520 ),
1521 (
1521 (
1522 b'',
1522 b'',
1523 b'base',
1523 b'base',
1524 [],
1524 [],
1525 _(b'a base changeset assumed to be available at the destination'),
1525 _(b'a base changeset assumed to be available at the destination'),
1526 _(b'REV'),
1526 _(b'REV'),
1527 ),
1527 ),
1528 (b'a', b'all', None, _(b'bundle all changesets in the repository')),
1528 (b'a', b'all', None, _(b'bundle all changesets in the repository')),
1529 (
1529 (
1530 b't',
1530 b't',
1531 b'type',
1531 b'type',
1532 b'bzip2',
1532 b'bzip2',
1533 _(b'bundle compression type to use'),
1533 _(b'bundle compression type to use'),
1534 _(b'TYPE'),
1534 _(b'TYPE'),
1535 ),
1535 ),
1536 ]
1536 ]
1537 + remoteopts,
1537 + remoteopts,
1538 _(b'[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]...'),
1538 _(b'[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]...'),
1539 helpcategory=command.CATEGORY_IMPORT_EXPORT,
1539 helpcategory=command.CATEGORY_IMPORT_EXPORT,
1540 )
1540 )
1541 def bundle(ui, repo, fname, *dests, **opts):
1541 def bundle(ui, repo, fname, *dests, **opts):
1542 """create a bundle file
1542 """create a bundle file
1543
1543
1544 Generate a bundle file containing data to be transferred to another
1544 Generate a bundle file containing data to be transferred to another
1545 repository.
1545 repository.
1546
1546
1547 To create a bundle containing all changesets, use -a/--all
1547 To create a bundle containing all changesets, use -a/--all
1548 (or --base null). Otherwise, hg assumes the destination will have
1548 (or --base null). Otherwise, hg assumes the destination will have
1549 all the nodes you specify with --base parameters. Otherwise, hg
1549 all the nodes you specify with --base parameters. Otherwise, hg
1550 will assume the repository has all the nodes in destination, or
1550 will assume the repository has all the nodes in destination, or
1551 default-push/default if no destination is specified, where destination
1551 default-push/default if no destination is specified, where destination
1552 is the repositories you provide through DEST option.
1552 is the repositories you provide through DEST option.
1553
1553
1554 You can change bundle format with the -t/--type option. See
1554 You can change bundle format with the -t/--type option. See
1555 :hg:`help bundlespec` for documentation on this format. By default,
1555 :hg:`help bundlespec` for documentation on this format. By default,
1556 the most appropriate format is used and compression defaults to
1556 the most appropriate format is used and compression defaults to
1557 bzip2.
1557 bzip2.
1558
1558
1559 The bundle file can then be transferred using conventional means
1559 The bundle file can then be transferred using conventional means
1560 and applied to another repository with the unbundle or pull
1560 and applied to another repository with the unbundle or pull
1561 command. This is useful when direct push and pull are not
1561 command. This is useful when direct push and pull are not
1562 available or when exporting an entire repository is undesirable.
1562 available or when exporting an entire repository is undesirable.
1563
1563
1564 Applying bundles preserves all changeset contents including
1564 Applying bundles preserves all changeset contents including
1565 permissions, copy/rename information, and revision history.
1565 permissions, copy/rename information, and revision history.
1566
1566
1567 Returns 0 on success, 1 if no changes found.
1567 Returns 0 on success, 1 if no changes found.
1568 """
1568 """
1569
1569
1570 revs = None
1570 revs = None
1571 if 'rev' in opts:
1571 if 'rev' in opts:
1572 revstrings = opts['rev']
1572 revstrings = opts['rev']
1573 revs = logcmdutil.revrange(repo, revstrings)
1573 revs = logcmdutil.revrange(repo, revstrings)
1574 if revstrings and not revs:
1574 if revstrings and not revs:
1575 raise error.InputError(_(b'no commits to bundle'))
1575 raise error.InputError(_(b'no commits to bundle'))
1576
1576
1577 bundletype = opts.get('type', b'bzip2').lower()
1577 bundletype = opts.get('type', b'bzip2').lower()
1578 try:
1578 try:
1579 bundlespec = bundlecaches.parsebundlespec(
1579 bundlespec = bundlecaches.parsebundlespec(
1580 repo, bundletype, strict=False
1580 repo, bundletype, strict=False
1581 )
1581 )
1582 except error.UnsupportedBundleSpecification as e:
1582 except error.UnsupportedBundleSpecification as e:
1583 raise error.InputError(
1583 raise error.InputError(
1584 pycompat.bytestr(e),
1584 pycompat.bytestr(e),
1585 hint=_(b"see 'hg help bundlespec' for supported values for --type"),
1585 hint=_(b"see 'hg help bundlespec' for supported values for --type"),
1586 )
1586 )
1587 cgversion = bundlespec.params[b"cg.version"]
1587 cgversion = bundlespec.params[b"cg.version"]
1588
1588
1589 # Packed bundles are a pseudo bundle format for now.
1589 # Packed bundles are a pseudo bundle format for now.
1590 if cgversion == b's1':
1590 if cgversion == b's1':
1591 raise error.InputError(
1591 raise error.InputError(
1592 _(b'packed bundles cannot be produced by "hg bundle"'),
1592 _(b'packed bundles cannot be produced by "hg bundle"'),
1593 hint=_(b"use 'hg debugcreatestreamclonebundle'"),
1593 hint=_(b"use 'hg debugcreatestreamclonebundle'"),
1594 )
1594 )
1595
1595
1596 if opts.get('all'):
1596 if opts.get('all'):
1597 if dests:
1597 if dests:
1598 raise error.InputError(
1598 raise error.InputError(
1599 _(b"--all is incompatible with specifying destinations")
1599 _(b"--all is incompatible with specifying destinations")
1600 )
1600 )
1601 if opts.get('base'):
1601 if opts.get('base'):
1602 ui.warn(_(b"ignoring --base because --all was specified\n"))
1602 ui.warn(_(b"ignoring --base because --all was specified\n"))
1603 if opts.get('exact'):
1603 if opts.get('exact'):
1604 ui.warn(_(b"ignoring --exact because --all was specified\n"))
1604 ui.warn(_(b"ignoring --exact because --all was specified\n"))
1605 base = [nullrev]
1605 base = [nullrev]
1606 elif opts.get('exact'):
1606 elif opts.get('exact'):
1607 if dests:
1607 if dests:
1608 raise error.InputError(
1608 raise error.InputError(
1609 _(b"--exact is incompatible with specifying destinations")
1609 _(b"--exact is incompatible with specifying destinations")
1610 )
1610 )
1611 if opts.get('base'):
1611 if opts.get('base'):
1612 ui.warn(_(b"ignoring --base because --exact was specified\n"))
1612 ui.warn(_(b"ignoring --base because --exact was specified\n"))
1613 base = repo.revs(b'parents(%ld) - %ld', revs, revs)
1613 base = repo.revs(b'parents(%ld) - %ld', revs, revs)
1614 if not base:
1614 if not base:
1615 base = [nullrev]
1615 base = [nullrev]
1616 else:
1616 else:
1617 base = logcmdutil.revrange(repo, opts.get('base'))
1617 base = logcmdutil.revrange(repo, opts.get('base'))
1618 if cgversion not in changegroup.supportedoutgoingversions(repo):
1618 if cgversion not in changegroup.supportedoutgoingversions(repo):
1619 raise error.Abort(
1619 raise error.Abort(
1620 _(b"repository does not support bundle version %s") % cgversion
1620 _(b"repository does not support bundle version %s") % cgversion
1621 )
1621 )
1622
1622
1623 if base:
1623 if base:
1624 if dests:
1624 if dests:
1625 raise error.InputError(
1625 raise error.InputError(
1626 _(b"--base is incompatible with specifying destinations")
1626 _(b"--base is incompatible with specifying destinations")
1627 )
1627 )
1628 cl = repo.changelog
1628 cl = repo.changelog
1629 common = [cl.node(rev) for rev in base]
1629 common = [cl.node(rev) for rev in base]
1630 heads = [cl.node(r) for r in revs] if revs else None
1630 heads = [cl.node(r) for r in revs] if revs else None
1631 outgoing = discovery.outgoing(repo, common, heads)
1631 outgoing = discovery.outgoing(repo, common, heads)
1632 missing = outgoing.missing
1632 missing = outgoing.missing
1633 excluded = outgoing.excluded
1633 excluded = outgoing.excluded
1634 else:
1634 else:
1635 missing = set()
1635 missing = set()
1636 excluded = set()
1636 excluded = set()
1637 for path in urlutil.get_push_paths(repo, ui, dests):
1637 for path in urlutil.get_push_paths(repo, ui, dests):
1638 other = hg.peer(repo, pycompat.byteskwargs(opts), path)
1638 other = hg.peer(repo, pycompat.byteskwargs(opts), path)
1639 if revs is not None:
1639 if revs is not None:
1640 hex_revs = [repo[r].hex() for r in revs]
1640 hex_revs = [repo[r].hex() for r in revs]
1641 else:
1641 else:
1642 hex_revs = None
1642 hex_revs = None
1643 branches = (path.branch, [])
1643 branches = (path.branch, [])
1644 head_revs, checkout = hg.addbranchrevs(
1644 head_revs, checkout = hg.addbranchrevs(
1645 repo, repo, branches, hex_revs
1645 repo, repo, branches, hex_revs
1646 )
1646 )
1647 heads = (
1647 heads = (
1648 head_revs
1648 head_revs
1649 and pycompat.maplist(repo.lookup, head_revs)
1649 and pycompat.maplist(repo.lookup, head_revs)
1650 or head_revs
1650 or head_revs
1651 )
1651 )
1652 outgoing = discovery.findcommonoutgoing(
1652 outgoing = discovery.findcommonoutgoing(
1653 repo,
1653 repo,
1654 other,
1654 other,
1655 onlyheads=heads,
1655 onlyheads=heads,
1656 force=opts.get('force'),
1656 force=opts.get('force'),
1657 portable=True,
1657 portable=True,
1658 )
1658 )
1659 missing.update(outgoing.missing)
1659 missing.update(outgoing.missing)
1660 excluded.update(outgoing.excluded)
1660 excluded.update(outgoing.excluded)
1661
1661
1662 if not missing:
1662 if not missing:
1663 scmutil.nochangesfound(ui, repo, not base and excluded)
1663 scmutil.nochangesfound(ui, repo, not base and excluded)
1664 return 1
1664 return 1
1665
1665
1666 # internal changeset are internal implementation details that should not
1666 # internal changeset are internal implementation details that should not
1667 # leave the repository. Bundling with `hg bundle` create such risk.
1667 # leave the repository. Bundling with `hg bundle` create such risk.
1668 bundled_internal = repo.revs(b"%ln and _internal()", missing)
1668 bundled_internal = repo.revs(b"%ln and _internal()", missing)
1669 if bundled_internal:
1669 if bundled_internal:
1670 msg = _(b"cannot bundle internal changesets")
1670 msg = _(b"cannot bundle internal changesets")
1671 hint = _(b"%d internal changesets selected") % len(bundled_internal)
1671 hint = _(b"%d internal changesets selected") % len(bundled_internal)
1672 raise error.Abort(msg, hint=hint)
1672 raise error.Abort(msg, hint=hint)
1673
1673
1674 if heads:
1674 if heads:
1675 outgoing = discovery.outgoing(
1675 outgoing = discovery.outgoing(
1676 repo, missingroots=missing, ancestorsof=heads
1676 repo, missingroots=missing, ancestorsof=heads
1677 )
1677 )
1678 else:
1678 else:
1679 outgoing = discovery.outgoing(repo, missingroots=missing)
1679 outgoing = discovery.outgoing(repo, missingroots=missing)
1680 outgoing.excluded = sorted(excluded)
1680 outgoing.excluded = sorted(excluded)
1681
1681
1682 if cgversion == b'01': # bundle1
1682 if cgversion == b'01': # bundle1
1683 bversion = b'HG10' + bundlespec.wirecompression
1683 bversion = b'HG10' + bundlespec.wirecompression
1684 bcompression = None
1684 bcompression = None
1685 elif cgversion in (b'02', b'03'):
1685 elif cgversion in (b'02', b'03'):
1686 bversion = b'HG20'
1686 bversion = b'HG20'
1687 bcompression = bundlespec.wirecompression
1687 bcompression = bundlespec.wirecompression
1688 else:
1688 else:
1689 raise error.ProgrammingError(
1689 raise error.ProgrammingError(
1690 b'bundle: unexpected changegroup version %s' % cgversion
1690 b'bundle: unexpected changegroup version %s' % cgversion
1691 )
1691 )
1692
1692
1693 # TODO compression options should be derived from bundlespec parsing.
1693 # TODO compression options should be derived from bundlespec parsing.
1694 # This is a temporary hack to allow adjusting bundle compression
1694 # This is a temporary hack to allow adjusting bundle compression
1695 # level without a) formalizing the bundlespec changes to declare it
1695 # level without a) formalizing the bundlespec changes to declare it
1696 # b) introducing a command flag.
1696 # b) introducing a command flag.
1697 compopts = {}
1697 compopts = {}
1698 complevel = ui.configint(
1698 complevel = ui.configint(
1699 b'experimental', b'bundlecomplevel.' + bundlespec.compression
1699 b'experimental', b'bundlecomplevel.' + bundlespec.compression
1700 )
1700 )
1701 if complevel is None:
1701 if complevel is None:
1702 complevel = ui.configint(b'experimental', b'bundlecomplevel')
1702 complevel = ui.configint(b'experimental', b'bundlecomplevel')
1703 if complevel is not None:
1703 if complevel is not None:
1704 compopts[b'level'] = complevel
1704 compopts[b'level'] = complevel
1705
1705
1706 compthreads = ui.configint(
1706 compthreads = ui.configint(
1707 b'experimental', b'bundlecompthreads.' + bundlespec.compression
1707 b'experimental', b'bundlecompthreads.' + bundlespec.compression
1708 )
1708 )
1709 if compthreads is None:
1709 if compthreads is None:
1710 compthreads = ui.configint(b'experimental', b'bundlecompthreads')
1710 compthreads = ui.configint(b'experimental', b'bundlecompthreads')
1711 if compthreads is not None:
1711 if compthreads is not None:
1712 compopts[b'threads'] = compthreads
1712 compopts[b'threads'] = compthreads
1713
1713
1714 # Bundling of obsmarker and phases is optional as not all clients
1714 # Bundling of obsmarker and phases is optional as not all clients
1715 # support the necessary features.
1715 # support the necessary features.
1716 cfg = ui.configbool
1716 cfg = ui.configbool
1717 obsolescence_cfg = cfg(b'experimental', b'evolution.bundle-obsmarker')
1717 obsolescence_cfg = cfg(b'experimental', b'evolution.bundle-obsmarker')
1718 bundlespec.set_param(b'obsolescence', obsolescence_cfg, overwrite=False)
1718 bundlespec.set_param(b'obsolescence', obsolescence_cfg, overwrite=False)
1719 obs_mand_cfg = cfg(b'experimental', b'evolution.bundle-obsmarker:mandatory')
1719 obs_mand_cfg = cfg(b'experimental', b'evolution.bundle-obsmarker:mandatory')
1720 bundlespec.set_param(
1720 bundlespec.set_param(
1721 b'obsolescence-mandatory', obs_mand_cfg, overwrite=False
1721 b'obsolescence-mandatory', obs_mand_cfg, overwrite=False
1722 )
1722 )
1723 if not bundlespec.params.get(b'phases', False):
1723 if not bundlespec.params.get(b'phases', False):
1724 phases_cfg = cfg(b'experimental', b'bundle-phases')
1724 phases_cfg = cfg(b'experimental', b'bundle-phases')
1725 bundlespec.set_param(b'phases', phases_cfg, overwrite=False)
1725 bundlespec.set_param(b'phases', phases_cfg, overwrite=False)
1726
1726
1727 bundle2.writenewbundle(
1727 bundle2.writenewbundle(
1728 ui,
1728 ui,
1729 repo,
1729 repo,
1730 b'bundle',
1730 b'bundle',
1731 fname,
1731 fname,
1732 bversion,
1732 bversion,
1733 outgoing,
1733 outgoing,
1734 bundlespec.params,
1734 bundlespec.params,
1735 compression=bcompression,
1735 compression=bcompression,
1736 compopts=compopts,
1736 compopts=compopts,
1737 )
1737 )
1738
1738
1739
1739
1740 @command(
1740 @command(
1741 b'cat',
1741 b'cat',
1742 [
1742 [
1743 (
1743 (
1744 b'o',
1744 b'o',
1745 b'output',
1745 b'output',
1746 b'',
1746 b'',
1747 _(b'print output to file with formatted name'),
1747 _(b'print output to file with formatted name'),
1748 _(b'FORMAT'),
1748 _(b'FORMAT'),
1749 ),
1749 ),
1750 (b'r', b'rev', b'', _(b'print the given revision'), _(b'REV')),
1750 (b'r', b'rev', b'', _(b'print the given revision'), _(b'REV')),
1751 (b'', b'decode', None, _(b'apply any matching decode filter')),
1751 (b'', b'decode', None, _(b'apply any matching decode filter')),
1752 ]
1752 ]
1753 + walkopts
1753 + walkopts
1754 + formatteropts,
1754 + formatteropts,
1755 _(b'[OPTION]... FILE...'),
1755 _(b'[OPTION]... FILE...'),
1756 helpcategory=command.CATEGORY_FILE_CONTENTS,
1756 helpcategory=command.CATEGORY_FILE_CONTENTS,
1757 inferrepo=True,
1757 inferrepo=True,
1758 intents={INTENT_READONLY},
1758 intents={INTENT_READONLY},
1759 )
1759 )
1760 def cat(ui, repo, file1, *pats, **opts):
1760 def cat(ui, repo, file1, *pats, **opts):
1761 """output the current or given revision of files
1761 """output the current or given revision of files
1762
1762
1763 Print the specified files as they were at the given revision. If
1763 Print the specified files as they were at the given revision. If
1764 no revision is given, the parent of the working directory is used.
1764 no revision is given, the parent of the working directory is used.
1765
1765
1766 Output may be to a file, in which case the name of the file is
1766 Output may be to a file, in which case the name of the file is
1767 given using a template string. See :hg:`help templates`. In addition
1767 given using a template string. See :hg:`help templates`. In addition
1768 to the common template keywords, the following formatting rules are
1768 to the common template keywords, the following formatting rules are
1769 supported:
1769 supported:
1770
1770
1771 :``%%``: literal "%" character
1771 :``%%``: literal "%" character
1772 :``%s``: basename of file being printed
1772 :``%s``: basename of file being printed
1773 :``%d``: dirname of file being printed, or '.' if in repository root
1773 :``%d``: dirname of file being printed, or '.' if in repository root
1774 :``%p``: root-relative path name of file being printed
1774 :``%p``: root-relative path name of file being printed
1775 :``%H``: changeset hash (40 hexadecimal digits)
1775 :``%H``: changeset hash (40 hexadecimal digits)
1776 :``%R``: changeset revision number
1776 :``%R``: changeset revision number
1777 :``%h``: short-form changeset hash (12 hexadecimal digits)
1777 :``%h``: short-form changeset hash (12 hexadecimal digits)
1778 :``%r``: zero-padded changeset revision number
1778 :``%r``: zero-padded changeset revision number
1779 :``%b``: basename of the exporting repository
1779 :``%b``: basename of the exporting repository
1780 :``\\``: literal "\\" character
1780 :``\\``: literal "\\" character
1781
1781
1782 .. container:: verbose
1782 .. container:: verbose
1783
1783
1784 Template:
1784 Template:
1785
1785
1786 The following keywords are supported in addition to the common template
1786 The following keywords are supported in addition to the common template
1787 keywords and functions. See also :hg:`help templates`.
1787 keywords and functions. See also :hg:`help templates`.
1788
1788
1789 :data: String. File content.
1789 :data: String. File content.
1790 :path: String. Repository-absolute path of the file.
1790 :path: String. Repository-absolute path of the file.
1791
1791
1792 Returns 0 on success.
1792 Returns 0 on success.
1793 """
1793 """
1794 rev = opts.get('rev')
1794 rev = opts.get('rev')
1795 if rev:
1795 if rev:
1796 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
1796 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
1797 ctx = logcmdutil.revsingle(repo, rev)
1797 ctx = logcmdutil.revsingle(repo, rev)
1798 m = scmutil.match(ctx, (file1,) + pats, pycompat.byteskwargs(opts))
1798 m = scmutil.match(ctx, (file1,) + pats, pycompat.byteskwargs(opts))
1799 fntemplate = opts.pop('output', b'')
1799 fntemplate = opts.pop('output', b'')
1800 if cmdutil.isstdiofilename(fntemplate):
1800 if cmdutil.isstdiofilename(fntemplate):
1801 fntemplate = b''
1801 fntemplate = b''
1802
1802
1803 if fntemplate:
1803 if fntemplate:
1804 fm = formatter.nullformatter(ui, b'cat', pycompat.byteskwargs(opts))
1804 fm = formatter.nullformatter(ui, b'cat', pycompat.byteskwargs(opts))
1805 else:
1805 else:
1806 ui.pager(b'cat')
1806 ui.pager(b'cat')
1807 fm = ui.formatter(b'cat', pycompat.byteskwargs(opts))
1807 fm = ui.formatter(b'cat', pycompat.byteskwargs(opts))
1808 with fm:
1808 with fm:
1809 return cmdutil.cat(ui, repo, ctx, m, fm, fntemplate, b'', **opts)
1809 return cmdutil.cat(ui, repo, ctx, m, fm, fntemplate, b'', **opts)
1810
1810
1811
1811
1812 @command(
1812 @command(
1813 b'clone',
1813 b'clone',
1814 [
1814 [
1815 (
1815 (
1816 b'U',
1816 b'U',
1817 b'noupdate',
1817 b'noupdate',
1818 None,
1818 None,
1819 _(
1819 _(
1820 b'the clone will include an empty working '
1820 b'the clone will include an empty working '
1821 b'directory (only a repository)'
1821 b'directory (only a repository)'
1822 ),
1822 ),
1823 ),
1823 ),
1824 (
1824 (
1825 b'u',
1825 b'u',
1826 b'updaterev',
1826 b'updaterev',
1827 b'',
1827 b'',
1828 _(b'revision, tag, or branch to check out'),
1828 _(b'revision, tag, or branch to check out'),
1829 _(b'REV'),
1829 _(b'REV'),
1830 ),
1830 ),
1831 (
1831 (
1832 b'r',
1832 b'r',
1833 b'rev',
1833 b'rev',
1834 [],
1834 [],
1835 _(
1835 _(
1836 b'do not clone everything, but include this changeset'
1836 b'do not clone everything, but include this changeset'
1837 b' and its ancestors'
1837 b' and its ancestors'
1838 ),
1838 ),
1839 _(b'REV'),
1839 _(b'REV'),
1840 ),
1840 ),
1841 (
1841 (
1842 b'b',
1842 b'b',
1843 b'branch',
1843 b'branch',
1844 [],
1844 [],
1845 _(
1845 _(
1846 b'do not clone everything, but include this branch\'s'
1846 b'do not clone everything, but include this branch\'s'
1847 b' changesets and their ancestors'
1847 b' changesets and their ancestors'
1848 ),
1848 ),
1849 _(b'BRANCH'),
1849 _(b'BRANCH'),
1850 ),
1850 ),
1851 (b'', b'pull', None, _(b'use pull protocol to copy metadata')),
1851 (b'', b'pull', None, _(b'use pull protocol to copy metadata')),
1852 (b'', b'uncompressed', None, _(b'an alias to --stream (DEPRECATED)')),
1852 (b'', b'uncompressed', None, _(b'an alias to --stream (DEPRECATED)')),
1853 (b'', b'stream', None, _(b'clone with minimal data processing')),
1853 (b'', b'stream', None, _(b'clone with minimal data processing')),
1854 ]
1854 ]
1855 + remoteopts,
1855 + remoteopts,
1856 _(b'[OPTION]... SOURCE [DEST]'),
1856 _(b'[OPTION]... SOURCE [DEST]'),
1857 helpcategory=command.CATEGORY_REPO_CREATION,
1857 helpcategory=command.CATEGORY_REPO_CREATION,
1858 helpbasic=True,
1858 helpbasic=True,
1859 norepo=True,
1859 norepo=True,
1860 )
1860 )
1861 def clone(ui, source, dest=None, **opts):
1861 def clone(ui, source, dest=None, **opts):
1862 """make a copy of an existing repository
1862 """make a copy of an existing repository
1863
1863
1864 Create a copy of an existing repository in a new directory.
1864 Create a copy of an existing repository in a new directory.
1865
1865
1866 If no destination directory name is specified, it defaults to the
1866 If no destination directory name is specified, it defaults to the
1867 basename of the source.
1867 basename of the source.
1868
1868
1869 The location of the source is added to the new repository's
1869 The location of the source is added to the new repository's
1870 ``.hg/hgrc`` file, as the default to be used for future pulls.
1870 ``.hg/hgrc`` file, as the default to be used for future pulls.
1871
1871
1872 Only local paths and ``ssh://`` URLs are supported as
1872 Only local paths and ``ssh://`` URLs are supported as
1873 destinations. For ``ssh://`` destinations, no working directory or
1873 destinations. For ``ssh://`` destinations, no working directory or
1874 ``.hg/hgrc`` will be created on the remote side.
1874 ``.hg/hgrc`` will be created on the remote side.
1875
1875
1876 If the source repository has a bookmark called '@' set, that
1876 If the source repository has a bookmark called '@' set, that
1877 revision will be checked out in the new repository by default.
1877 revision will be checked out in the new repository by default.
1878
1878
1879 To check out a particular version, use -u/--update, or
1879 To check out a particular version, use -u/--update, or
1880 -U/--noupdate to create a clone with no working directory.
1880 -U/--noupdate to create a clone with no working directory.
1881
1881
1882 To pull only a subset of changesets, specify one or more revisions
1882 To pull only a subset of changesets, specify one or more revisions
1883 identifiers with -r/--rev or branches with -b/--branch. The
1883 identifiers with -r/--rev or branches with -b/--branch. The
1884 resulting clone will contain only the specified changesets and
1884 resulting clone will contain only the specified changesets and
1885 their ancestors. These options (or 'clone src#rev dest') imply
1885 their ancestors. These options (or 'clone src#rev dest') imply
1886 --pull, even for local source repositories.
1886 --pull, even for local source repositories.
1887
1887
1888 In normal clone mode, the remote normalizes repository data into a common
1888 In normal clone mode, the remote normalizes repository data into a common
1889 exchange format and the receiving end translates this data into its local
1889 exchange format and the receiving end translates this data into its local
1890 storage format. --stream activates a different clone mode that essentially
1890 storage format. --stream activates a different clone mode that essentially
1891 copies repository files from the remote with minimal data processing. This
1891 copies repository files from the remote with minimal data processing. This
1892 significantly reduces the CPU cost of a clone both remotely and locally.
1892 significantly reduces the CPU cost of a clone both remotely and locally.
1893 However, it often increases the transferred data size by 30-40%. This can
1893 However, it often increases the transferred data size by 30-40%. This can
1894 result in substantially faster clones where I/O throughput is plentiful,
1894 result in substantially faster clones where I/O throughput is plentiful,
1895 especially for larger repositories. A side-effect of --stream clones is
1895 especially for larger repositories. A side-effect of --stream clones is
1896 that storage settings and requirements on the remote are applied locally:
1896 that storage settings and requirements on the remote are applied locally:
1897 a modern client may inherit legacy or inefficient storage used by the
1897 a modern client may inherit legacy or inefficient storage used by the
1898 remote or a legacy Mercurial client may not be able to clone from a
1898 remote or a legacy Mercurial client may not be able to clone from a
1899 modern Mercurial remote.
1899 modern Mercurial remote.
1900
1900
1901 .. note::
1901 .. note::
1902
1902
1903 Specifying a tag will include the tagged changeset but not the
1903 Specifying a tag will include the tagged changeset but not the
1904 changeset containing the tag.
1904 changeset containing the tag.
1905
1905
1906 .. container:: verbose
1906 .. container:: verbose
1907
1907
1908 For efficiency, hardlinks are used for cloning whenever the
1908 For efficiency, hardlinks are used for cloning whenever the
1909 source and destination are on the same filesystem (note this
1909 source and destination are on the same filesystem (note this
1910 applies only to the repository data, not to the working
1910 applies only to the repository data, not to the working
1911 directory). Some filesystems, such as AFS, implement hardlinking
1911 directory). Some filesystems, such as AFS, implement hardlinking
1912 incorrectly, but do not report errors. In these cases, use the
1912 incorrectly, but do not report errors. In these cases, use the
1913 --pull option to avoid hardlinking.
1913 --pull option to avoid hardlinking.
1914
1914
1915 Mercurial will update the working directory to the first applicable
1915 Mercurial will update the working directory to the first applicable
1916 revision from this list:
1916 revision from this list:
1917
1917
1918 a) null if -U or the source repository has no changesets
1918 a) null if -U or the source repository has no changesets
1919 b) if -u . and the source repository is local, the first parent of
1919 b) if -u . and the source repository is local, the first parent of
1920 the source repository's working directory
1920 the source repository's working directory
1921 c) the changeset specified with -u (if a branch name, this means the
1921 c) the changeset specified with -u (if a branch name, this means the
1922 latest head of that branch)
1922 latest head of that branch)
1923 d) the changeset specified with -r
1923 d) the changeset specified with -r
1924 e) the tipmost head specified with -b
1924 e) the tipmost head specified with -b
1925 f) the tipmost head specified with the url#branch source syntax
1925 f) the tipmost head specified with the url#branch source syntax
1926 g) the revision marked with the '@' bookmark, if present
1926 g) the revision marked with the '@' bookmark, if present
1927 h) the tipmost head of the default branch
1927 h) the tipmost head of the default branch
1928 i) tip
1928 i) tip
1929
1929
1930 When cloning from servers that support it, Mercurial may fetch
1930 When cloning from servers that support it, Mercurial may fetch
1931 pre-generated data from a server-advertised URL or inline from the
1931 pre-generated data from a server-advertised URL or inline from the
1932 same stream. When this is done, hooks operating on incoming changesets
1932 same stream. When this is done, hooks operating on incoming changesets
1933 and changegroups may fire more than once, once for each pre-generated
1933 and changegroups may fire more than once, once for each pre-generated
1934 bundle and as well as for any additional remaining data. In addition,
1934 bundle and as well as for any additional remaining data. In addition,
1935 if an error occurs, the repository may be rolled back to a partial
1935 if an error occurs, the repository may be rolled back to a partial
1936 clone. This behavior may change in future releases.
1936 clone. This behavior may change in future releases.
1937 See :hg:`help -e clonebundles` for more.
1937 See :hg:`help -e clonebundles` for more.
1938
1938
1939 Examples:
1939 Examples:
1940
1940
1941 - clone a remote repository to a new directory named hg/::
1941 - clone a remote repository to a new directory named hg/::
1942
1942
1943 hg clone https://www.mercurial-scm.org/repo/hg/
1943 hg clone https://www.mercurial-scm.org/repo/hg/
1944
1944
1945 - create a lightweight local clone::
1945 - create a lightweight local clone::
1946
1946
1947 hg clone project/ project-feature/
1947 hg clone project/ project-feature/
1948
1948
1949 - clone from an absolute path on an ssh server (note double-slash)::
1949 - clone from an absolute path on an ssh server (note double-slash)::
1950
1950
1951 hg clone ssh://user@server//home/projects/alpha/
1951 hg clone ssh://user@server//home/projects/alpha/
1952
1952
1953 - do a streaming clone while checking out a specified version::
1953 - do a streaming clone while checking out a specified version::
1954
1954
1955 hg clone --stream http://server/repo -u 1.5
1955 hg clone --stream http://server/repo -u 1.5
1956
1956
1957 - create a repository without changesets after a particular revision::
1957 - create a repository without changesets after a particular revision::
1958
1958
1959 hg clone -r 04e544 experimental/ good/
1959 hg clone -r 04e544 experimental/ good/
1960
1960
1961 - clone (and track) a particular named branch::
1961 - clone (and track) a particular named branch::
1962
1962
1963 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1963 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1964
1964
1965 See :hg:`help urls` for details on specifying URLs.
1965 See :hg:`help urls` for details on specifying URLs.
1966
1966
1967 Returns 0 on success.
1967 Returns 0 on success.
1968 """
1968 """
1969 cmdutil.check_at_most_one_arg(opts, 'noupdate', 'updaterev')
1969 cmdutil.check_at_most_one_arg(opts, 'noupdate', 'updaterev')
1970
1970
1971 # --include/--exclude can come from narrow or sparse.
1971 # --include/--exclude can come from narrow or sparse.
1972 includepats, excludepats = None, None
1972 includepats, excludepats = None, None
1973
1973
1974 # hg.clone() differentiates between None and an empty set. So make sure
1974 # hg.clone() differentiates between None and an empty set. So make sure
1975 # patterns are sets if narrow is requested without patterns.
1975 # patterns are sets if narrow is requested without patterns.
1976 if opts.get('narrow'):
1976 if opts.get('narrow'):
1977 includepats = set()
1977 includepats = set()
1978 excludepats = set()
1978 excludepats = set()
1979
1979
1980 if opts.get('include'):
1980 if opts.get('include'):
1981 includepats = narrowspec.parsepatterns(opts.get('include'))
1981 includepats = narrowspec.parsepatterns(opts.get('include'))
1982 if opts.get('exclude'):
1982 if opts.get('exclude'):
1983 excludepats = narrowspec.parsepatterns(opts.get('exclude'))
1983 excludepats = narrowspec.parsepatterns(opts.get('exclude'))
1984
1984
1985 r = hg.clone(
1985 r = hg.clone(
1986 ui,
1986 ui,
1987 pycompat.byteskwargs(opts),
1987 pycompat.byteskwargs(opts),
1988 source,
1988 source,
1989 dest,
1989 dest,
1990 pull=opts.get('pull'),
1990 pull=opts.get('pull'),
1991 stream=opts.get('stream') or opts.get('uncompressed'),
1991 stream=opts.get('stream') or opts.get('uncompressed'),
1992 revs=opts.get('rev'),
1992 revs=opts.get('rev'),
1993 update=opts.get('updaterev') or not opts.get('noupdate'),
1993 update=opts.get('updaterev') or not opts.get('noupdate'),
1994 branch=opts.get('branch'),
1994 branch=opts.get('branch'),
1995 shareopts=opts.get('shareopts'),
1995 shareopts=opts.get('shareopts'),
1996 storeincludepats=includepats,
1996 storeincludepats=includepats,
1997 storeexcludepats=excludepats,
1997 storeexcludepats=excludepats,
1998 depth=opts.get('depth') or None,
1998 depth=opts.get('depth') or None,
1999 )
1999 )
2000
2000
2001 return r is None
2001 return r is None
2002
2002
2003
2003
2004 @command(
2004 @command(
2005 b'commit|ci',
2005 b'commit|ci',
2006 [
2006 [
2007 (
2007 (
2008 b'A',
2008 b'A',
2009 b'addremove',
2009 b'addremove',
2010 None,
2010 None,
2011 _(b'mark new/missing files as added/removed before committing'),
2011 _(b'mark new/missing files as added/removed before committing'),
2012 ),
2012 ),
2013 (b'', b'close-branch', None, _(b'mark a branch head as closed')),
2013 (b'', b'close-branch', None, _(b'mark a branch head as closed')),
2014 (b'', b'amend', None, _(b'amend the parent of the working directory')),
2014 (b'', b'amend', None, _(b'amend the parent of the working directory')),
2015 (b's', b'secret', None, _(b'use the secret phase for committing')),
2015 (b's', b'secret', None, _(b'use the secret phase for committing')),
2016 (b'', b'draft', None, _(b'use the draft phase for committing')),
2016 (b'', b'draft', None, _(b'use the draft phase for committing')),
2017 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
2017 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
2018 (
2018 (
2019 b'',
2019 b'',
2020 b'force-close-branch',
2020 b'force-close-branch',
2021 None,
2021 None,
2022 _(b'forcibly close branch from a non-head changeset (ADVANCED)'),
2022 _(b'forcibly close branch from a non-head changeset (ADVANCED)'),
2023 ),
2023 ),
2024 (b'i', b'interactive', None, _(b'use interactive mode')),
2024 (b'i', b'interactive', None, _(b'use interactive mode')),
2025 ]
2025 ]
2026 + walkopts
2026 + walkopts
2027 + commitopts
2027 + commitopts
2028 + commitopts2
2028 + commitopts2
2029 + subrepoopts,
2029 + subrepoopts,
2030 _(b'[OPTION]... [FILE]...'),
2030 _(b'[OPTION]... [FILE]...'),
2031 helpcategory=command.CATEGORY_COMMITTING,
2031 helpcategory=command.CATEGORY_COMMITTING,
2032 helpbasic=True,
2032 helpbasic=True,
2033 inferrepo=True,
2033 inferrepo=True,
2034 )
2034 )
2035 def commit(ui, repo, *pats, **opts):
2035 def commit(ui, repo, *pats, **opts):
2036 """commit the specified files or all outstanding changes
2036 """commit the specified files or all outstanding changes
2037
2037
2038 Commit changes to the given files into the repository. Unlike a
2038 Commit changes to the given files into the repository. Unlike a
2039 centralized SCM, this operation is a local operation. See
2039 centralized SCM, this operation is a local operation. See
2040 :hg:`push` for a way to actively distribute your changes.
2040 :hg:`push` for a way to actively distribute your changes.
2041
2041
2042 If a list of files is omitted, all changes reported by :hg:`status`
2042 If a list of files is omitted, all changes reported by :hg:`status`
2043 will be committed.
2043 will be committed.
2044
2044
2045 If you are committing the result of a merge, do not provide any
2045 If you are committing the result of a merge, do not provide any
2046 filenames or -I/-X filters.
2046 filenames or -I/-X filters.
2047
2047
2048 If no commit message is specified, Mercurial starts your
2048 If no commit message is specified, Mercurial starts your
2049 configured editor where you can enter a message. In case your
2049 configured editor where you can enter a message. In case your
2050 commit fails, you will find a backup of your message in
2050 commit fails, you will find a backup of your message in
2051 ``.hg/last-message.txt``.
2051 ``.hg/last-message.txt``.
2052
2052
2053 The --close-branch flag can be used to mark the current branch
2053 The --close-branch flag can be used to mark the current branch
2054 head closed. When all heads of a branch are closed, the branch
2054 head closed. When all heads of a branch are closed, the branch
2055 will be considered closed and no longer listed.
2055 will be considered closed and no longer listed.
2056
2056
2057 The --amend flag can be used to amend the parent of the
2057 The --amend flag can be used to amend the parent of the
2058 working directory with a new commit that contains the changes
2058 working directory with a new commit that contains the changes
2059 in the parent in addition to those currently reported by :hg:`status`,
2059 in the parent in addition to those currently reported by :hg:`status`,
2060 if there are any. The old commit is stored in a backup bundle in
2060 if there are any. The old commit is stored in a backup bundle in
2061 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
2061 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
2062 on how to restore it).
2062 on how to restore it).
2063
2063
2064 Message, user and date are taken from the amended commit unless
2064 Message, user and date are taken from the amended commit unless
2065 specified. When a message isn't specified on the command line,
2065 specified. When a message isn't specified on the command line,
2066 the editor will open with the message of the amended commit.
2066 the editor will open with the message of the amended commit.
2067
2067
2068 It is not possible to amend public changesets (see :hg:`help phases`)
2068 It is not possible to amend public changesets (see :hg:`help phases`)
2069 or changesets that have children.
2069 or changesets that have children.
2070
2070
2071 See :hg:`help dates` for a list of formats valid for -d/--date.
2071 See :hg:`help dates` for a list of formats valid for -d/--date.
2072
2072
2073 Returns 0 on success, 1 if nothing changed.
2073 Returns 0 on success, 1 if nothing changed.
2074
2074
2075 .. container:: verbose
2075 .. container:: verbose
2076
2076
2077 Examples:
2077 Examples:
2078
2078
2079 - commit all files ending in .py::
2079 - commit all files ending in .py::
2080
2080
2081 hg commit --include "set:**.py"
2081 hg commit --include "set:**.py"
2082
2082
2083 - commit all non-binary files::
2083 - commit all non-binary files::
2084
2084
2085 hg commit --exclude "set:binary()"
2085 hg commit --exclude "set:binary()"
2086
2086
2087 - amend the current commit and set the date to now::
2087 - amend the current commit and set the date to now::
2088
2088
2089 hg commit --amend --date now
2089 hg commit --amend --date now
2090 """
2090 """
2091 cmdutil.check_at_most_one_arg(opts, 'draft', 'secret')
2091 cmdutil.check_at_most_one_arg(opts, 'draft', 'secret')
2092 cmdutil.check_incompatible_arguments(opts, 'subrepos', ['amend'])
2092 cmdutil.check_incompatible_arguments(opts, 'subrepos', ['amend'])
2093 with repo.wlock(), repo.lock():
2093 with repo.wlock(), repo.lock():
2094 return _docommit(ui, repo, *pats, **opts)
2094 return _docommit(ui, repo, *pats, **opts)
2095
2095
2096
2096
2097 def _docommit(ui, repo, *pats, **opts):
2097 def _docommit(ui, repo, *pats, **opts):
2098 if opts.get('interactive'):
2098 if opts.get('interactive'):
2099 opts.pop('interactive')
2099 opts.pop('interactive')
2100 ret = cmdutil.dorecord(
2100 ret = cmdutil.dorecord(
2101 ui, repo, commit, None, False, cmdutil.recordfilter, *pats, **opts
2101 ui, repo, commit, None, False, cmdutil.recordfilter, *pats, **opts
2102 )
2102 )
2103 # ret can be 0 (no changes to record) or the value returned by
2103 # ret can be 0 (no changes to record) or the value returned by
2104 # commit(), 1 if nothing changed or None on success.
2104 # commit(), 1 if nothing changed or None on success.
2105 return 1 if ret == 0 else ret
2105 return 1 if ret == 0 else ret
2106
2106
2107 if opts.get('subrepos'):
2107 if opts.get('subrepos'):
2108 # Let --subrepos on the command line override config setting.
2108 # Let --subrepos on the command line override config setting.
2109 ui.setconfig(b'ui', b'commitsubrepos', True, b'commit')
2109 ui.setconfig(b'ui', b'commitsubrepos', True, b'commit')
2110
2110
2111 cmdutil.checkunfinished(repo, commit=True)
2111 cmdutil.checkunfinished(repo, commit=True)
2112
2112
2113 branch = repo[None].branch()
2113 branch = repo[None].branch()
2114 bheads = repo.branchheads(branch)
2114 bheads = repo.branchheads(branch)
2115 tip = repo.changelog.tip()
2115 tip = repo.changelog.tip()
2116
2116
2117 extra = {}
2117 extra = {}
2118 if opts.get('close_branch') or opts.get('force_close_branch'):
2118 if opts.get('close_branch') or opts.get('force_close_branch'):
2119 extra[b'close'] = b'1'
2119 extra[b'close'] = b'1'
2120
2120
2121 if repo[b'.'].closesbranch():
2121 if repo[b'.'].closesbranch():
2122 # Not ideal, but let us do an extra status early to prevent early
2122 # Not ideal, but let us do an extra status early to prevent early
2123 # bail out.
2123 # bail out.
2124 matcher = scmutil.match(
2124 matcher = scmutil.match(
2125 repo[None], pats, pycompat.byteskwargs(opts)
2125 repo[None], pats, pycompat.byteskwargs(opts)
2126 )
2126 )
2127 s = repo.status(match=matcher)
2127 s = repo.status(match=matcher)
2128 if s.modified or s.added or s.removed:
2128 if s.modified or s.added or s.removed:
2129 bheads = repo.branchheads(branch, closed=True)
2129 bheads = repo.branchheads(branch, closed=True)
2130 else:
2130 else:
2131 msg = _(b'current revision is already a branch closing head')
2131 msg = _(b'current revision is already a branch closing head')
2132 raise error.InputError(msg)
2132 raise error.InputError(msg)
2133
2133
2134 if not bheads:
2134 if not bheads:
2135 raise error.InputError(
2135 raise error.InputError(
2136 _(b'branch "%s" has no heads to close') % branch
2136 _(b'branch "%s" has no heads to close') % branch
2137 )
2137 )
2138 elif (
2138 elif (
2139 branch == repo[b'.'].branch()
2139 branch == repo[b'.'].branch()
2140 and repo[b'.'].node() not in bheads
2140 and repo[b'.'].node() not in bheads
2141 and not opts.get('force_close_branch')
2141 and not opts.get('force_close_branch')
2142 ):
2142 ):
2143 hint = _(
2143 hint = _(
2144 b'use --force-close-branch to close branch from a non-head'
2144 b'use --force-close-branch to close branch from a non-head'
2145 b' changeset'
2145 b' changeset'
2146 )
2146 )
2147 raise error.InputError(_(b'can only close branch heads'), hint=hint)
2147 raise error.InputError(_(b'can only close branch heads'), hint=hint)
2148 elif opts.get('amend'):
2148 elif opts.get('amend'):
2149 if (
2149 if (
2150 repo[b'.'].p1().branch() != branch
2150 repo[b'.'].p1().branch() != branch
2151 and repo[b'.'].p2().branch() != branch
2151 and repo[b'.'].p2().branch() != branch
2152 ):
2152 ):
2153 raise error.InputError(_(b'can only close branch heads'))
2153 raise error.InputError(_(b'can only close branch heads'))
2154
2154
2155 if opts.get('amend'):
2155 if opts.get('amend'):
2156 if ui.configbool(b'ui', b'commitsubrepos'):
2156 if ui.configbool(b'ui', b'commitsubrepos'):
2157 raise error.InputError(
2157 raise error.InputError(
2158 _(b'cannot amend with ui.commitsubrepos enabled')
2158 _(b'cannot amend with ui.commitsubrepos enabled')
2159 )
2159 )
2160
2160
2161 old = repo[b'.']
2161 old = repo[b'.']
2162 rewriteutil.precheck(repo, [old.rev()], b'amend')
2162 rewriteutil.precheck(repo, [old.rev()], b'amend')
2163
2163
2164 # Currently histedit gets confused if an amend happens while histedit
2164 # Currently histedit gets confused if an amend happens while histedit
2165 # is in progress. Since we have a checkunfinished command, we are
2165 # is in progress. Since we have a checkunfinished command, we are
2166 # temporarily honoring it.
2166 # temporarily honoring it.
2167 #
2167 #
2168 # Note: eventually this guard will be removed. Please do not expect
2168 # Note: eventually this guard will be removed. Please do not expect
2169 # this behavior to remain.
2169 # this behavior to remain.
2170 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
2170 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
2171 cmdutil.checkunfinished(repo)
2171 cmdutil.checkunfinished(repo)
2172
2172
2173 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
2173 node = cmdutil.amend(ui, repo, old, extra, pats, opts)
2174 if node == old.node():
2174 if node == old.node():
2175 ui.status(_(b"nothing changed\n"))
2175 ui.status(_(b"nothing changed\n"))
2176 return 1
2176 return 1
2177 else:
2177 else:
2178
2178
2179 def commitfunc(ui, repo, message, match, opts):
2179 def commitfunc(ui, repo, message, match, opts):
2180 overrides = {}
2180 overrides = {}
2181 if opts.get(b'secret'):
2181 if opts.get(b'secret'):
2182 overrides[(b'phases', b'new-commit')] = b'secret'
2182 overrides[(b'phases', b'new-commit')] = b'secret'
2183 elif opts.get(b'draft'):
2183 elif opts.get(b'draft'):
2184 overrides[(b'phases', b'new-commit')] = b'draft'
2184 overrides[(b'phases', b'new-commit')] = b'draft'
2185
2185
2186 baseui = repo.baseui
2186 baseui = repo.baseui
2187 with baseui.configoverride(overrides, b'commit'):
2187 with baseui.configoverride(overrides, b'commit'):
2188 with ui.configoverride(overrides, b'commit'):
2188 with ui.configoverride(overrides, b'commit'):
2189 editform = cmdutil.mergeeditform(
2189 editform = cmdutil.mergeeditform(
2190 repo[None], b'commit.normal'
2190 repo[None], b'commit.normal'
2191 )
2191 )
2192 editor = cmdutil.getcommiteditor(
2192 editor = cmdutil.getcommiteditor(
2193 editform=editform, **pycompat.strkwargs(opts)
2193 editform=editform, **pycompat.strkwargs(opts)
2194 )
2194 )
2195 return repo.commit(
2195 return repo.commit(
2196 message,
2196 message,
2197 opts.get(b'user'),
2197 opts.get(b'user'),
2198 opts.get(b'date'),
2198 opts.get(b'date'),
2199 match,
2199 match,
2200 editor=editor,
2200 editor=editor,
2201 extra=extra,
2201 extra=extra,
2202 )
2202 )
2203
2203
2204 node = cmdutil.commit(
2204 node = cmdutil.commit(
2205 ui, repo, commitfunc, pats, pycompat.byteskwargs(opts)
2205 ui, repo, commitfunc, pats, pycompat.byteskwargs(opts)
2206 )
2206 )
2207
2207
2208 if not node:
2208 if not node:
2209 stat = cmdutil.postcommitstatus(
2209 stat = cmdutil.postcommitstatus(
2210 repo, pats, pycompat.byteskwargs(opts)
2210 repo, pats, pycompat.byteskwargs(opts)
2211 )
2211 )
2212 if stat.deleted:
2212 if stat.deleted:
2213 ui.status(
2213 ui.status(
2214 _(
2214 _(
2215 b"nothing changed (%d missing files, see "
2215 b"nothing changed (%d missing files, see "
2216 b"'hg status')\n"
2216 b"'hg status')\n"
2217 )
2217 )
2218 % len(stat.deleted)
2218 % len(stat.deleted)
2219 )
2219 )
2220 else:
2220 else:
2221 ui.status(_(b"nothing changed\n"))
2221 ui.status(_(b"nothing changed\n"))
2222 return 1
2222 return 1
2223
2223
2224 cmdutil.commitstatus(repo, node, branch, bheads, tip, **opts)
2224 cmdutil.commitstatus(repo, node, branch, bheads, tip, **opts)
2225
2225
2226 if not ui.quiet and ui.configbool(b'commands', b'commit.post-status'):
2226 if not ui.quiet and ui.configbool(b'commands', b'commit.post-status'):
2227 status(
2227 status(
2228 ui,
2228 ui,
2229 repo,
2229 repo,
2230 modified=True,
2230 modified=True,
2231 added=True,
2231 added=True,
2232 removed=True,
2232 removed=True,
2233 deleted=True,
2233 deleted=True,
2234 unknown=True,
2234 unknown=True,
2235 subrepos=opts.get('subrepos'),
2235 subrepos=opts.get('subrepos'),
2236 )
2236 )
2237
2237
2238
2238
2239 @command(
2239 @command(
2240 b'config|showconfig|debugconfig',
2240 b'config|showconfig|debugconfig',
2241 [
2241 [
2242 (b'u', b'untrusted', None, _(b'show untrusted configuration options')),
2242 (b'u', b'untrusted', None, _(b'show untrusted configuration options')),
2243 # This is experimental because we need
2243 # This is experimental because we need
2244 # * reasonable behavior around aliases,
2244 # * reasonable behavior around aliases,
2245 # * decide if we display [debug] [experimental] and [devel] section par
2245 # * decide if we display [debug] [experimental] and [devel] section par
2246 # default
2246 # default
2247 # * some way to display "generic" config entry (the one matching
2247 # * some way to display "generic" config entry (the one matching
2248 # regexp,
2248 # regexp,
2249 # * proper display of the different value type
2249 # * proper display of the different value type
2250 # * a better way to handle <DYNAMIC> values (and variable types),
2250 # * a better way to handle <DYNAMIC> values (and variable types),
2251 # * maybe some type information ?
2251 # * maybe some type information ?
2252 (
2252 (
2253 b'',
2253 b'',
2254 b'exp-all-known',
2254 b'exp-all-known',
2255 None,
2255 None,
2256 _(b'show all known config option (EXPERIMENTAL)'),
2256 _(b'show all known config option (EXPERIMENTAL)'),
2257 ),
2257 ),
2258 (b'e', b'edit', None, _(b'edit user config')),
2258 (b'e', b'edit', None, _(b'edit user config')),
2259 (b'l', b'local', None, _(b'edit repository config')),
2259 (b'l', b'local', None, _(b'edit repository config')),
2260 (b'', b'source', None, _(b'show source of configuration value')),
2260 (b'', b'source', None, _(b'show source of configuration value')),
2261 (
2261 (
2262 b'',
2262 b'',
2263 b'shared',
2263 b'shared',
2264 None,
2264 None,
2265 _(b'edit shared source repository config (EXPERIMENTAL)'),
2265 _(b'edit shared source repository config (EXPERIMENTAL)'),
2266 ),
2266 ),
2267 (b'', b'non-shared', None, _(b'edit non shared config (EXPERIMENTAL)')),
2267 (b'', b'non-shared', None, _(b'edit non shared config (EXPERIMENTAL)')),
2268 (b'g', b'global', None, _(b'edit global config')),
2268 (b'g', b'global', None, _(b'edit global config')),
2269 ]
2269 ]
2270 + formatteropts,
2270 + formatteropts,
2271 _(b'[-u] [NAME]...'),
2271 _(b'[-u] [NAME]...'),
2272 helpcategory=command.CATEGORY_HELP,
2272 helpcategory=command.CATEGORY_HELP,
2273 optionalrepo=True,
2273 optionalrepo=True,
2274 intents={INTENT_READONLY},
2274 intents={INTENT_READONLY},
2275 )
2275 )
2276 def config(ui, repo, *values, **opts):
2276 def config(ui, repo, *values, **opts):
2277 """show combined config settings from all hgrc files
2277 """show combined config settings from all hgrc files
2278
2278
2279 With no arguments, print names and values of all config items.
2279 With no arguments, print names and values of all config items.
2280
2280
2281 With one argument of the form section.name, print just the value
2281 With one argument of the form section.name, print just the value
2282 of that config item.
2282 of that config item.
2283
2283
2284 With multiple arguments, print names and values of all config
2284 With multiple arguments, print names and values of all config
2285 items with matching section names or section.names.
2285 items with matching section names or section.names.
2286
2286
2287 With --edit, start an editor on the user-level config file. With
2287 With --edit, start an editor on the user-level config file. With
2288 --global, edit the system-wide config file. With --local, edit the
2288 --global, edit the system-wide config file. With --local, edit the
2289 repository-level config file.
2289 repository-level config file.
2290
2290
2291 With --source, the source (filename and line number) is printed
2291 With --source, the source (filename and line number) is printed
2292 for each config item.
2292 for each config item.
2293
2293
2294 See :hg:`help config` for more information about config files.
2294 See :hg:`help config` for more information about config files.
2295
2295
2296 .. container:: verbose
2296 .. container:: verbose
2297
2297
2298 --non-shared flag is used to edit `.hg/hgrc-not-shared` config file.
2298 --non-shared flag is used to edit `.hg/hgrc-not-shared` config file.
2299 This file is not shared across shares when in share-safe mode.
2299 This file is not shared across shares when in share-safe mode.
2300
2300
2301 Template:
2301 Template:
2302
2302
2303 The following keywords are supported. See also :hg:`help templates`.
2303 The following keywords are supported. See also :hg:`help templates`.
2304
2304
2305 :name: String. Config name.
2305 :name: String. Config name.
2306 :source: String. Filename and line number where the item is defined.
2306 :source: String. Filename and line number where the item is defined.
2307 :value: String. Config value.
2307 :value: String. Config value.
2308
2308
2309 The --shared flag can be used to edit the config file of shared source
2309 The --shared flag can be used to edit the config file of shared source
2310 repository. It only works when you have shared using the experimental
2310 repository. It only works when you have shared using the experimental
2311 share safe feature.
2311 share safe feature.
2312
2312
2313 Returns 0 on success, 1 if NAME does not exist.
2313 Returns 0 on success, 1 if NAME does not exist.
2314
2314
2315 """
2315 """
2316
2316
2317 editopts = ('edit', 'local', 'global', 'shared', 'non_shared')
2317 editopts = ('edit', 'local', 'global', 'shared', 'non_shared')
2318 if any(opts.get(o) for o in editopts):
2318 if any(opts.get(o) for o in editopts):
2319 cmdutil.check_at_most_one_arg(opts, *editopts[1:])
2319 cmdutil.check_at_most_one_arg(opts, *editopts[1:])
2320 if opts.get('local'):
2320 if opts.get('local'):
2321 if not repo:
2321 if not repo:
2322 raise error.InputError(
2322 raise error.InputError(
2323 _(b"can't use --local outside a repository")
2323 _(b"can't use --local outside a repository")
2324 )
2324 )
2325 paths = [repo.vfs.join(b'hgrc')]
2325 paths = [repo.vfs.join(b'hgrc')]
2326 elif opts.get('global'):
2326 elif opts.get('global'):
2327 paths = rcutil.systemrcpath()
2327 paths = rcutil.systemrcpath()
2328 elif opts.get('shared'):
2328 elif opts.get('shared'):
2329 if not repo.shared():
2329 if not repo.shared():
2330 raise error.InputError(
2330 raise error.InputError(
2331 _(b"repository is not shared; can't use --shared")
2331 _(b"repository is not shared; can't use --shared")
2332 )
2332 )
2333 if requirements.SHARESAFE_REQUIREMENT not in repo.requirements:
2333 if requirements.SHARESAFE_REQUIREMENT not in repo.requirements:
2334 raise error.InputError(
2334 raise error.InputError(
2335 _(
2335 _(
2336 b"share safe feature not enabled; "
2336 b"share safe feature not enabled; "
2337 b"unable to edit shared source repository config"
2337 b"unable to edit shared source repository config"
2338 )
2338 )
2339 )
2339 )
2340 paths = [vfsmod.vfs(repo.sharedpath).join(b'hgrc')]
2340 paths = [vfsmod.vfs(repo.sharedpath).join(b'hgrc')]
2341 elif opts.get('non_shared'):
2341 elif opts.get('non_shared'):
2342 paths = [repo.vfs.join(b'hgrc-not-shared')]
2342 paths = [repo.vfs.join(b'hgrc-not-shared')]
2343 else:
2343 else:
2344 paths = rcutil.userrcpath()
2344 paths = rcutil.userrcpath()
2345
2345
2346 for f in paths:
2346 for f in paths:
2347 if os.path.exists(f):
2347 if os.path.exists(f):
2348 break
2348 break
2349 else:
2349 else:
2350 if opts.get('global'):
2350 if opts.get('global'):
2351 samplehgrc = uimod.samplehgrcs[b'global']
2351 samplehgrc = uimod.samplehgrcs[b'global']
2352 elif opts.get('local'):
2352 elif opts.get('local'):
2353 samplehgrc = uimod.samplehgrcs[b'local']
2353 samplehgrc = uimod.samplehgrcs[b'local']
2354 else:
2354 else:
2355 samplehgrc = uimod.samplehgrcs[b'user']
2355 samplehgrc = uimod.samplehgrcs[b'user']
2356
2356
2357 f = paths[0]
2357 f = paths[0]
2358 util.writefile(f, util.tonativeeol(samplehgrc))
2358 util.writefile(f, util.tonativeeol(samplehgrc))
2359
2359
2360 editor = ui.geteditor()
2360 editor = ui.geteditor()
2361 ui.system(
2361 ui.system(
2362 b"%s \"%s\"" % (editor, f),
2362 b"%s \"%s\"" % (editor, f),
2363 onerr=error.InputError,
2363 onerr=error.InputError,
2364 errprefix=_(b"edit failed"),
2364 errprefix=_(b"edit failed"),
2365 blockedtag=b'config_edit',
2365 blockedtag=b'config_edit',
2366 )
2366 )
2367 return
2367 return
2368 ui.pager(b'config')
2368 ui.pager(b'config')
2369 fm = ui.formatter(b'config', pycompat.byteskwargs(opts))
2369 fm = ui.formatter(b'config', pycompat.byteskwargs(opts))
2370 for t, f in rcutil.rccomponents():
2370 for t, f in rcutil.rccomponents():
2371 if t == b'path':
2371 if t == b'path':
2372 ui.debug(b'read config from: %s\n' % f)
2372 ui.debug(b'read config from: %s\n' % f)
2373 elif t == b'resource':
2373 elif t == b'resource':
2374 ui.debug(b'read config from: resource:%s.%s\n' % (f[0], f[1]))
2374 ui.debug(b'read config from: resource:%s.%s\n' % (f[0], f[1]))
2375 elif t == b'items':
2375 elif t == b'items':
2376 # Don't print anything for 'items'.
2376 # Don't print anything for 'items'.
2377 pass
2377 pass
2378 else:
2378 else:
2379 raise error.ProgrammingError(b'unknown rctype: %s' % t)
2379 raise error.ProgrammingError(b'unknown rctype: %s' % t)
2380 untrusted = bool(opts.get('untrusted'))
2380 untrusted = bool(opts.get('untrusted'))
2381
2381
2382 selsections = selentries = []
2382 selsections = selentries = []
2383 if values:
2383 if values:
2384 selsections = [v for v in values if b'.' not in v]
2384 selsections = [v for v in values if b'.' not in v]
2385 selentries = [v for v in values if b'.' in v]
2385 selentries = [v for v in values if b'.' in v]
2386 uniquesel = len(selentries) == 1 and not selsections
2386 uniquesel = len(selentries) == 1 and not selsections
2387 selsections = set(selsections)
2387 selsections = set(selsections)
2388 selentries = set(selentries)
2388 selentries = set(selentries)
2389
2389
2390 matched = False
2390 matched = False
2391 all_known = opts['exp_all_known']
2391 all_known = opts['exp_all_known']
2392 show_source = ui.debugflag or opts.get('source')
2392 show_source = ui.debugflag or opts.get('source')
2393 entries = ui.walkconfig(untrusted=untrusted, all_known=all_known)
2393 entries = ui.walkconfig(untrusted=untrusted, all_known=all_known)
2394 for section, name, value in entries:
2394 for section, name, value in entries:
2395 source = ui.configsource(section, name, untrusted)
2395 source = ui.configsource(section, name, untrusted)
2396 value = pycompat.bytestr(value)
2396 value = pycompat.bytestr(value)
2397 defaultvalue = ui.configdefault(section, name)
2397 defaultvalue = ui.configdefault(section, name)
2398 if fm.isplain():
2398 if fm.isplain():
2399 source = source or b'none'
2399 source = source or b'none'
2400 value = value.replace(b'\n', b'\\n')
2400 value = value.replace(b'\n', b'\\n')
2401 entryname = section + b'.' + name
2401 entryname = section + b'.' + name
2402 if values and not (section in selsections or entryname in selentries):
2402 if values and not (section in selsections or entryname in selentries):
2403 continue
2403 continue
2404 fm.startitem()
2404 fm.startitem()
2405 fm.condwrite(show_source, b'source', b'%s: ', source)
2405 fm.condwrite(show_source, b'source', b'%s: ', source)
2406 if uniquesel:
2406 if uniquesel:
2407 fm.data(name=entryname)
2407 fm.data(name=entryname)
2408 fm.write(b'value', b'%s\n', value)
2408 fm.write(b'value', b'%s\n', value)
2409 else:
2409 else:
2410 fm.write(b'name value', b'%s=%s\n', entryname, value)
2410 fm.write(b'name value', b'%s=%s\n', entryname, value)
2411 if formatter.isprintable(defaultvalue):
2411 if formatter.isprintable(defaultvalue):
2412 fm.data(defaultvalue=defaultvalue)
2412 fm.data(defaultvalue=defaultvalue)
2413 elif isinstance(defaultvalue, list) and all(
2413 elif isinstance(defaultvalue, list) and all(
2414 formatter.isprintable(e) for e in defaultvalue
2414 formatter.isprintable(e) for e in defaultvalue
2415 ):
2415 ):
2416 fm.data(defaultvalue=fm.formatlist(defaultvalue, name=b'value'))
2416 fm.data(defaultvalue=fm.formatlist(defaultvalue, name=b'value'))
2417 # TODO: no idea how to process unsupported defaultvalue types
2417 # TODO: no idea how to process unsupported defaultvalue types
2418 matched = True
2418 matched = True
2419 fm.end()
2419 fm.end()
2420 if matched:
2420 if matched:
2421 return 0
2421 return 0
2422 return 1
2422 return 1
2423
2423
2424
2424
2425 @command(
2425 @command(
2426 b'continue',
2426 b'continue',
2427 dryrunopts,
2427 dryrunopts,
2428 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2428 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
2429 helpbasic=True,
2429 helpbasic=True,
2430 )
2430 )
2431 def continuecmd(ui, repo, **opts):
2431 def continuecmd(ui, repo, **opts):
2432 """resumes an interrupted operation (EXPERIMENTAL)
2432 """resumes an interrupted operation (EXPERIMENTAL)
2433
2433
2434 Finishes a multistep operation like graft, histedit, rebase, merge,
2434 Finishes a multistep operation like graft, histedit, rebase, merge,
2435 and unshelve if they are in an interrupted state.
2435 and unshelve if they are in an interrupted state.
2436
2436
2437 use --dry-run/-n to dry run the command.
2437 use --dry-run/-n to dry run the command.
2438 """
2438 """
2439 dryrun = opts.get('dry_run')
2439 dryrun = opts.get('dry_run')
2440 contstate = cmdutil.getunfinishedstate(repo)
2440 contstate = cmdutil.getunfinishedstate(repo)
2441 if not contstate:
2441 if not contstate:
2442 raise error.StateError(_(b'no operation in progress'))
2442 raise error.StateError(_(b'no operation in progress'))
2443 if not contstate.continuefunc:
2443 if not contstate.continuefunc:
2444 raise error.StateError(
2444 raise error.StateError(
2445 (
2445 (
2446 _(b"%s in progress but does not support 'hg continue'")
2446 _(b"%s in progress but does not support 'hg continue'")
2447 % (contstate._opname)
2447 % (contstate._opname)
2448 ),
2448 ),
2449 hint=contstate.continuemsg(),
2449 hint=contstate.continuemsg(),
2450 )
2450 )
2451 if dryrun:
2451 if dryrun:
2452 ui.status(_(b'%s in progress, will be resumed\n') % (contstate._opname))
2452 ui.status(_(b'%s in progress, will be resumed\n') % (contstate._opname))
2453 return
2453 return
2454 return contstate.continuefunc(ui, repo)
2454 return contstate.continuefunc(ui, repo)
2455
2455
2456
2456
2457 @command(
2457 @command(
2458 b'copy|cp',
2458 b'copy|cp',
2459 [
2459 [
2460 (b'', b'forget', None, _(b'unmark a destination file as copied')),
2460 (b'', b'forget', None, _(b'unmark a destination file as copied')),
2461 (b'A', b'after', None, _(b'record a copy that has already occurred')),
2461 (b'A', b'after', None, _(b'record a copy that has already occurred')),
2462 (
2462 (
2463 b'',
2463 b'',
2464 b'at-rev',
2464 b'at-rev',
2465 b'',
2465 b'',
2466 _(b'(un)mark copies in the given revision (EXPERIMENTAL)'),
2466 _(b'(un)mark copies in the given revision (EXPERIMENTAL)'),
2467 _(b'REV'),
2467 _(b'REV'),
2468 ),
2468 ),
2469 (
2469 (
2470 b'f',
2470 b'f',
2471 b'force',
2471 b'force',
2472 None,
2472 None,
2473 _(b'forcibly copy over an existing managed file'),
2473 _(b'forcibly copy over an existing managed file'),
2474 ),
2474 ),
2475 ]
2475 ]
2476 + walkopts
2476 + walkopts
2477 + dryrunopts,
2477 + dryrunopts,
2478 _(b'[OPTION]... (SOURCE... DEST | --forget DEST...)'),
2478 _(b'[OPTION]... (SOURCE... DEST | --forget DEST...)'),
2479 helpcategory=command.CATEGORY_FILE_CONTENTS,
2479 helpcategory=command.CATEGORY_FILE_CONTENTS,
2480 )
2480 )
2481 def copy(ui, repo, *pats, **opts):
2481 def copy(ui, repo, *pats, **opts):
2482 """mark files as copied for the next commit
2482 """mark files as copied for the next commit
2483
2483
2484 Mark dest as having copies of source files. If dest is a
2484 Mark dest as having copies of source files. If dest is a
2485 directory, copies are put in that directory. If dest is a file,
2485 directory, copies are put in that directory. If dest is a file,
2486 the source must be a single file.
2486 the source must be a single file.
2487
2487
2488 By default, this command copies the contents of files as they
2488 By default, this command copies the contents of files as they
2489 exist in the working directory. If invoked with -A/--after, the
2489 exist in the working directory. If invoked with -A/--after, the
2490 operation is recorded, but no copying is performed.
2490 operation is recorded, but no copying is performed.
2491
2491
2492 To undo marking a destination file as copied, use --forget. With that
2492 To undo marking a destination file as copied, use --forget. With that
2493 option, all given (positional) arguments are unmarked as copies. The
2493 option, all given (positional) arguments are unmarked as copies. The
2494 destination file(s) will be left in place (still tracked). Note that
2494 destination file(s) will be left in place (still tracked). Note that
2495 :hg:`copy --forget` behaves the same way as :hg:`rename --forget`.
2495 :hg:`copy --forget` behaves the same way as :hg:`rename --forget`.
2496
2496
2497 This command takes effect with the next commit by default.
2497 This command takes effect with the next commit by default.
2498
2498
2499 Returns 0 on success, 1 if errors are encountered.
2499 Returns 0 on success, 1 if errors are encountered.
2500 """
2500 """
2501
2501
2502 context = lambda repo: repo.dirstate.changing_files(repo)
2502 context = lambda repo: repo.dirstate.changing_files(repo)
2503 rev = opts.get('at_rev')
2503 rev = opts.get('at_rev')
2504
2504
2505 if rev:
2505 if rev:
2506 ctx = logcmdutil.revsingle(repo, rev)
2506 ctx = logcmdutil.revsingle(repo, rev)
2507 if ctx.rev() is not None:
2507 if ctx.rev() is not None:
2508
2508
2509 def context(repo):
2509 def context(repo):
2510 return util.nullcontextmanager()
2510 return util.nullcontextmanager()
2511
2511
2512 opts['at_rev'] = ctx.rev()
2512 opts['at_rev'] = ctx.rev()
2513 with repo.wlock(), context(repo):
2513 with repo.wlock(), context(repo):
2514 return cmdutil.copy(ui, repo, pats, pycompat.byteskwargs(opts))
2514 return cmdutil.copy(ui, repo, pats, pycompat.byteskwargs(opts))
2515
2515
2516
2516
2517 @command(
2517 @command(
2518 b'debugcommands',
2518 b'debugcommands',
2519 [],
2519 [],
2520 _(b'[COMMAND]'),
2520 _(b'[COMMAND]'),
2521 helpcategory=command.CATEGORY_HELP,
2521 helpcategory=command.CATEGORY_HELP,
2522 norepo=True,
2522 norepo=True,
2523 )
2523 )
2524 def debugcommands(ui, cmd=b'', *args):
2524 def debugcommands(ui, cmd=b'', *args):
2525 """list all available commands and options"""
2525 """list all available commands and options"""
2526 for cmd, vals in sorted(table.items()):
2526 for cmd, vals in sorted(table.items()):
2527 cmd = cmd.split(b'|')[0]
2527 cmd = cmd.split(b'|')[0]
2528 opts = b', '.join([i[1] for i in vals[1]])
2528 opts = b', '.join([i[1] for i in vals[1]])
2529 ui.write(b'%s: %s\n' % (cmd, opts))
2529 ui.write(b'%s: %s\n' % (cmd, opts))
2530
2530
2531
2531
2532 @command(
2532 @command(
2533 b'debugcomplete',
2533 b'debugcomplete',
2534 [(b'o', b'options', None, _(b'show the command options'))],
2534 [(b'o', b'options', None, _(b'show the command options'))],
2535 _(b'[-o] CMD'),
2535 _(b'[-o] CMD'),
2536 helpcategory=command.CATEGORY_HELP,
2536 helpcategory=command.CATEGORY_HELP,
2537 norepo=True,
2537 norepo=True,
2538 )
2538 )
2539 def debugcomplete(ui, cmd=b'', **opts):
2539 def debugcomplete(ui, cmd=b'', **opts):
2540 """returns the completion list associated with the given command"""
2540 """returns the completion list associated with the given command"""
2541
2541
2542 if opts.get('options'):
2542 if opts.get('options'):
2543 options = []
2543 options = []
2544 otables = [globalopts]
2544 otables = [globalopts]
2545 if cmd:
2545 if cmd:
2546 aliases, entry = cmdutil.findcmd(cmd, table, False)
2546 aliases, entry = cmdutil.findcmd(cmd, table, False)
2547 otables.append(entry[1])
2547 otables.append(entry[1])
2548 for t in otables:
2548 for t in otables:
2549 for o in t:
2549 for o in t:
2550 if b"(DEPRECATED)" in o[3]:
2550 if b"(DEPRECATED)" in o[3]:
2551 continue
2551 continue
2552 if o[0]:
2552 if o[0]:
2553 options.append(b'-%s' % o[0])
2553 options.append(b'-%s' % o[0])
2554 options.append(b'--%s' % o[1])
2554 options.append(b'--%s' % o[1])
2555 ui.write(b"%s\n" % b"\n".join(options))
2555 ui.write(b"%s\n" % b"\n".join(options))
2556 return
2556 return
2557
2557
2558 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2558 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2559 if ui.verbose:
2559 if ui.verbose:
2560 cmdlist = [b' '.join(c[0]) for c in cmdlist.values()]
2560 cmdlist = [b' '.join(c[0]) for c in cmdlist.values()]
2561 ui.write(b"%s\n" % b"\n".join(sorted(cmdlist)))
2561 ui.write(b"%s\n" % b"\n".join(sorted(cmdlist)))
2562
2562
2563
2563
2564 @command(
2564 @command(
2565 b'diff',
2565 b'diff',
2566 [
2566 [
2567 (b'r', b'rev', [], _(b'revision (DEPRECATED)'), _(b'REV')),
2567 (b'r', b'rev', [], _(b'revision (DEPRECATED)'), _(b'REV')),
2568 (b'', b'from', b'', _(b'revision to diff from'), _(b'REV1')),
2568 (b'', b'from', b'', _(b'revision to diff from'), _(b'REV1')),
2569 (b'', b'to', b'', _(b'revision to diff to'), _(b'REV2')),
2569 (b'', b'to', b'', _(b'revision to diff to'), _(b'REV2')),
2570 (b'c', b'change', b'', _(b'change made by revision'), _(b'REV')),
2570 (b'c', b'change', b'', _(b'change made by revision'), _(b'REV')),
2571 ]
2571 ]
2572 + diffopts
2572 + diffopts
2573 + diffopts2
2573 + diffopts2
2574 + walkopts
2574 + walkopts
2575 + subrepoopts,
2575 + subrepoopts,
2576 _(b'[OPTION]... ([-c REV] | [--from REV1] [--to REV2]) [FILE]...'),
2576 _(b'[OPTION]... ([-c REV] | [--from REV1] [--to REV2]) [FILE]...'),
2577 helpcategory=command.CATEGORY_FILE_CONTENTS,
2577 helpcategory=command.CATEGORY_FILE_CONTENTS,
2578 helpbasic=True,
2578 helpbasic=True,
2579 inferrepo=True,
2579 inferrepo=True,
2580 intents={INTENT_READONLY},
2580 intents={INTENT_READONLY},
2581 )
2581 )
2582 def diff(ui, repo, *pats, **opts):
2582 def diff(ui, repo, *pats, **opts):
2583 """diff repository (or selected files)
2583 """diff repository (or selected files)
2584
2584
2585 Show differences between revisions for the specified files.
2585 Show differences between revisions for the specified files.
2586
2586
2587 Differences between files are shown using the unified diff format.
2587 Differences between files are shown using the unified diff format.
2588
2588
2589 .. note::
2589 .. note::
2590
2590
2591 :hg:`diff` may generate unexpected results for merges, as it will
2591 :hg:`diff` may generate unexpected results for merges, as it will
2592 default to comparing against the working directory's first
2592 default to comparing against the working directory's first
2593 parent changeset if no revisions are specified. To diff against the
2593 parent changeset if no revisions are specified. To diff against the
2594 conflict regions, you can use `--config diff.merge=yes`.
2594 conflict regions, you can use `--config diff.merge=yes`.
2595
2595
2596 By default, the working directory files are compared to its first parent. To
2596 By default, the working directory files are compared to its first parent. To
2597 see the differences from another revision, use --from. To see the difference
2597 see the differences from another revision, use --from. To see the difference
2598 to another revision, use --to. For example, :hg:`diff --from .^` will show
2598 to another revision, use --to. For example, :hg:`diff --from .^` will show
2599 the differences from the working copy's grandparent to the working copy,
2599 the differences from the working copy's grandparent to the working copy,
2600 :hg:`diff --to .` will show the diff from the working copy to its parent
2600 :hg:`diff --to .` will show the diff from the working copy to its parent
2601 (i.e. the reverse of the default), and :hg:`diff --from 1.0 --to 1.2` will
2601 (i.e. the reverse of the default), and :hg:`diff --from 1.0 --to 1.2` will
2602 show the diff between those two revisions.
2602 show the diff between those two revisions.
2603
2603
2604 Alternatively you can specify -c/--change with a revision to see the changes
2604 Alternatively you can specify -c/--change with a revision to see the changes
2605 in that changeset relative to its first parent (i.e. :hg:`diff -c 42` is
2605 in that changeset relative to its first parent (i.e. :hg:`diff -c 42` is
2606 equivalent to :hg:`diff --from 42^ --to 42`)
2606 equivalent to :hg:`diff --from 42^ --to 42`)
2607
2607
2608 Without the -a/--text option, diff will avoid generating diffs of
2608 Without the -a/--text option, diff will avoid generating diffs of
2609 files it detects as binary. With -a, diff will generate a diff
2609 files it detects as binary. With -a, diff will generate a diff
2610 anyway, probably with undesirable results.
2610 anyway, probably with undesirable results.
2611
2611
2612 Use the -g/--git option to generate diffs in the git extended diff
2612 Use the -g/--git option to generate diffs in the git extended diff
2613 format. For more information, read :hg:`help diffs`.
2613 format. For more information, read :hg:`help diffs`.
2614
2614
2615 .. container:: verbose
2615 .. container:: verbose
2616
2616
2617 Examples:
2617 Examples:
2618
2618
2619 - compare a file in the current working directory to its parent::
2619 - compare a file in the current working directory to its parent::
2620
2620
2621 hg diff foo.c
2621 hg diff foo.c
2622
2622
2623 - compare two historical versions of a directory, with rename info::
2623 - compare two historical versions of a directory, with rename info::
2624
2624
2625 hg diff --git --from 1.0 --to 1.2 lib/
2625 hg diff --git --from 1.0 --to 1.2 lib/
2626
2626
2627 - get change stats relative to the last change on some date::
2627 - get change stats relative to the last change on some date::
2628
2628
2629 hg diff --stat --from "date('may 2')"
2629 hg diff --stat --from "date('may 2')"
2630
2630
2631 - diff all newly-added files that contain a keyword::
2631 - diff all newly-added files that contain a keyword::
2632
2632
2633 hg diff "set:added() and grep(GNU)"
2633 hg diff "set:added() and grep(GNU)"
2634
2634
2635 - compare a revision and its parents::
2635 - compare a revision and its parents::
2636
2636
2637 hg diff -c 9353 # compare against first parent
2637 hg diff -c 9353 # compare against first parent
2638 hg diff --from 9353^ --to 9353 # same using revset syntax
2638 hg diff --from 9353^ --to 9353 # same using revset syntax
2639 hg diff --from 9353^2 --to 9353 # compare against the second parent
2639 hg diff --from 9353^2 --to 9353 # compare against the second parent
2640
2640
2641 Returns 0 on success.
2641 Returns 0 on success.
2642 """
2642 """
2643
2643
2644 cmdutil.check_at_most_one_arg(opts, 'rev', 'change')
2644 cmdutil.check_at_most_one_arg(opts, 'rev', 'change')
2645 opts = pycompat.byteskwargs(opts)
2645 opts = pycompat.byteskwargs(opts)
2646 revs = opts.get(b'rev')
2646 revs = opts.get(b'rev')
2647 change = opts.get(b'change')
2647 change = opts.get(b'change')
2648 from_rev = opts.get(b'from')
2648 from_rev = opts.get(b'from')
2649 to_rev = opts.get(b'to')
2649 to_rev = opts.get(b'to')
2650 stat = opts.get(b'stat')
2650 stat = opts.get(b'stat')
2651 reverse = opts.get(b'reverse')
2651 reverse = opts.get(b'reverse')
2652
2652
2653 cmdutil.check_incompatible_arguments(opts, b'from', [b'rev', b'change'])
2653 cmdutil.check_incompatible_arguments(opts, b'from', [b'rev', b'change'])
2654 cmdutil.check_incompatible_arguments(opts, b'to', [b'rev', b'change'])
2654 cmdutil.check_incompatible_arguments(opts, b'to', [b'rev', b'change'])
2655 if change:
2655 if change:
2656 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
2656 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
2657 ctx2 = logcmdutil.revsingle(repo, change, None)
2657 ctx2 = logcmdutil.revsingle(repo, change, None)
2658 ctx1 = logcmdutil.diff_parent(ctx2)
2658 ctx1 = logcmdutil.diff_parent(ctx2)
2659 elif from_rev or to_rev:
2659 elif from_rev or to_rev:
2660 repo = scmutil.unhidehashlikerevs(
2660 repo = scmutil.unhidehashlikerevs(
2661 repo, [from_rev] + [to_rev], b'nowarn'
2661 repo, [from_rev] + [to_rev], b'nowarn'
2662 )
2662 )
2663 ctx1 = logcmdutil.revsingle(repo, from_rev, None)
2663 ctx1 = logcmdutil.revsingle(repo, from_rev, None)
2664 ctx2 = logcmdutil.revsingle(repo, to_rev, None)
2664 ctx2 = logcmdutil.revsingle(repo, to_rev, None)
2665 else:
2665 else:
2666 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
2666 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
2667 ctx1, ctx2 = logcmdutil.revpair(repo, revs)
2667 ctx1, ctx2 = logcmdutil.revpair(repo, revs)
2668
2668
2669 if reverse:
2669 if reverse:
2670 ctxleft = ctx2
2670 ctxleft = ctx2
2671 ctxright = ctx1
2671 ctxright = ctx1
2672 else:
2672 else:
2673 ctxleft = ctx1
2673 ctxleft = ctx1
2674 ctxright = ctx2
2674 ctxright = ctx2
2675
2675
2676 diffopts = patch.diffallopts(ui, opts)
2676 diffopts = patch.diffallopts(ui, opts)
2677 m = scmutil.match(ctx2, pats, opts)
2677 m = scmutil.match(ctx2, pats, opts)
2678 m = repo.narrowmatch(m)
2678 m = repo.narrowmatch(m)
2679 ui.pager(b'diff')
2679 ui.pager(b'diff')
2680 logcmdutil.diffordiffstat(
2680 logcmdutil.diffordiffstat(
2681 ui,
2681 ui,
2682 repo,
2682 repo,
2683 diffopts,
2683 diffopts,
2684 ctxleft,
2684 ctxleft,
2685 ctxright,
2685 ctxright,
2686 m,
2686 m,
2687 stat=stat,
2687 stat=stat,
2688 listsubrepos=opts.get(b'subrepos'),
2688 listsubrepos=opts.get(b'subrepos'),
2689 root=opts.get(b'root'),
2689 root=opts.get(b'root'),
2690 )
2690 )
2691
2691
2692
2692
2693 @command(
2693 @command(
2694 b'export',
2694 b'export',
2695 [
2695 [
2696 (
2696 (
2697 b'B',
2697 b'B',
2698 b'bookmark',
2698 b'bookmark',
2699 b'',
2699 b'',
2700 _(b'export changes only reachable by given bookmark'),
2700 _(b'export changes only reachable by given bookmark'),
2701 _(b'BOOKMARK'),
2701 _(b'BOOKMARK'),
2702 ),
2702 ),
2703 (
2703 (
2704 b'o',
2704 b'o',
2705 b'output',
2705 b'output',
2706 b'',
2706 b'',
2707 _(b'print output to file with formatted name'),
2707 _(b'print output to file with formatted name'),
2708 _(b'FORMAT'),
2708 _(b'FORMAT'),
2709 ),
2709 ),
2710 (b'', b'switch-parent', None, _(b'diff against the second parent')),
2710 (b'', b'switch-parent', None, _(b'diff against the second parent')),
2711 (b'r', b'rev', [], _(b'revisions to export'), _(b'REV')),
2711 (b'r', b'rev', [], _(b'revisions to export'), _(b'REV')),
2712 ]
2712 ]
2713 + diffopts
2713 + diffopts
2714 + formatteropts,
2714 + formatteropts,
2715 _(b'[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2715 _(b'[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
2716 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2716 helpcategory=command.CATEGORY_IMPORT_EXPORT,
2717 helpbasic=True,
2717 helpbasic=True,
2718 intents={INTENT_READONLY},
2718 intents={INTENT_READONLY},
2719 )
2719 )
2720 def export(ui, repo, *changesets, **opts):
2720 def export(ui, repo, *changesets, **opts):
2721 """dump the header and diffs for one or more changesets
2721 """dump the header and diffs for one or more changesets
2722
2722
2723 Print the changeset header and diffs for one or more revisions.
2723 Print the changeset header and diffs for one or more revisions.
2724 If no revision is given, the parent of the working directory is used.
2724 If no revision is given, the parent of the working directory is used.
2725
2725
2726 The information shown in the changeset header is: author, date,
2726 The information shown in the changeset header is: author, date,
2727 branch name (if non-default), changeset hash, parent(s) and commit
2727 branch name (if non-default), changeset hash, parent(s) and commit
2728 comment.
2728 comment.
2729
2729
2730 .. note::
2730 .. note::
2731
2731
2732 :hg:`export` may generate unexpected diff output for merge
2732 :hg:`export` may generate unexpected diff output for merge
2733 changesets, as it will compare the merge changeset against its
2733 changesets, as it will compare the merge changeset against its
2734 first parent only.
2734 first parent only.
2735
2735
2736 Output may be to a file, in which case the name of the file is
2736 Output may be to a file, in which case the name of the file is
2737 given using a template string. See :hg:`help templates`. In addition
2737 given using a template string. See :hg:`help templates`. In addition
2738 to the common template keywords, the following formatting rules are
2738 to the common template keywords, the following formatting rules are
2739 supported:
2739 supported:
2740
2740
2741 :``%%``: literal "%" character
2741 :``%%``: literal "%" character
2742 :``%H``: changeset hash (40 hexadecimal digits)
2742 :``%H``: changeset hash (40 hexadecimal digits)
2743 :``%N``: number of patches being generated
2743 :``%N``: number of patches being generated
2744 :``%R``: changeset revision number
2744 :``%R``: changeset revision number
2745 :``%b``: basename of the exporting repository
2745 :``%b``: basename of the exporting repository
2746 :``%h``: short-form changeset hash (12 hexadecimal digits)
2746 :``%h``: short-form changeset hash (12 hexadecimal digits)
2747 :``%m``: first line of the commit message (only alphanumeric characters)
2747 :``%m``: first line of the commit message (only alphanumeric characters)
2748 :``%n``: zero-padded sequence number, starting at 1
2748 :``%n``: zero-padded sequence number, starting at 1
2749 :``%r``: zero-padded changeset revision number
2749 :``%r``: zero-padded changeset revision number
2750 :``\\``: literal "\\" character
2750 :``\\``: literal "\\" character
2751
2751
2752 Without the -a/--text option, export will avoid generating diffs
2752 Without the -a/--text option, export will avoid generating diffs
2753 of files it detects as binary. With -a, export will generate a
2753 of files it detects as binary. With -a, export will generate a
2754 diff anyway, probably with undesirable results.
2754 diff anyway, probably with undesirable results.
2755
2755
2756 With -B/--bookmark changesets reachable by the given bookmark are
2756 With -B/--bookmark changesets reachable by the given bookmark are
2757 selected.
2757 selected.
2758
2758
2759 Use the -g/--git option to generate diffs in the git extended diff
2759 Use the -g/--git option to generate diffs in the git extended diff
2760 format. See :hg:`help diffs` for more information.
2760 format. See :hg:`help diffs` for more information.
2761
2761
2762 With the --switch-parent option, the diff will be against the
2762 With the --switch-parent option, the diff will be against the
2763 second parent. It can be useful to review a merge.
2763 second parent. It can be useful to review a merge.
2764
2764
2765 .. container:: verbose
2765 .. container:: verbose
2766
2766
2767 Template:
2767 Template:
2768
2768
2769 The following keywords are supported in addition to the common template
2769 The following keywords are supported in addition to the common template
2770 keywords and functions. See also :hg:`help templates`.
2770 keywords and functions. See also :hg:`help templates`.
2771
2771
2772 :diff: String. Diff content.
2772 :diff: String. Diff content.
2773 :parents: List of strings. Parent nodes of the changeset.
2773 :parents: List of strings. Parent nodes of the changeset.
2774
2774
2775 Examples:
2775 Examples:
2776
2776
2777 - use export and import to transplant a bugfix to the current
2777 - use export and import to transplant a bugfix to the current
2778 branch::
2778 branch::
2779
2779
2780 hg export -r 9353 | hg import -
2780 hg export -r 9353 | hg import -
2781
2781
2782 - export all the changesets between two revisions to a file with
2782 - export all the changesets between two revisions to a file with
2783 rename information::
2783 rename information::
2784
2784
2785 hg export --git -r 123:150 > changes.txt
2785 hg export --git -r 123:150 > changes.txt
2786
2786
2787 - split outgoing changes into a series of patches with
2787 - split outgoing changes into a series of patches with
2788 descriptive names::
2788 descriptive names::
2789
2789
2790 hg export -r "outgoing()" -o "%n-%m.patch"
2790 hg export -r "outgoing()" -o "%n-%m.patch"
2791
2791
2792 Returns 0 on success.
2792 Returns 0 on success.
2793 """
2793 """
2794 opts = pycompat.byteskwargs(opts)
2794 opts = pycompat.byteskwargs(opts)
2795 bookmark = opts.get(b'bookmark')
2795 bookmark = opts.get(b'bookmark')
2796 changesets += tuple(opts.get(b'rev', []))
2796 changesets += tuple(opts.get(b'rev', []))
2797
2797
2798 cmdutil.check_at_most_one_arg(opts, b'rev', b'bookmark')
2798 cmdutil.check_at_most_one_arg(opts, b'rev', b'bookmark')
2799
2799
2800 if bookmark:
2800 if bookmark:
2801 if bookmark not in repo._bookmarks:
2801 if bookmark not in repo._bookmarks:
2802 raise error.InputError(_(b"bookmark '%s' not found") % bookmark)
2802 raise error.InputError(_(b"bookmark '%s' not found") % bookmark)
2803
2803
2804 revs = scmutil.bookmarkrevs(repo, bookmark)
2804 revs = scmutil.bookmarkrevs(repo, bookmark)
2805 else:
2805 else:
2806 if not changesets:
2806 if not changesets:
2807 changesets = [b'.']
2807 changesets = [b'.']
2808
2808
2809 repo = scmutil.unhidehashlikerevs(repo, changesets, b'nowarn')
2809 repo = scmutil.unhidehashlikerevs(repo, changesets, b'nowarn')
2810 revs = logcmdutil.revrange(repo, changesets)
2810 revs = logcmdutil.revrange(repo, changesets)
2811
2811
2812 if not revs:
2812 if not revs:
2813 raise error.InputError(_(b"export requires at least one changeset"))
2813 raise error.InputError(_(b"export requires at least one changeset"))
2814 if len(revs) > 1:
2814 if len(revs) > 1:
2815 ui.note(_(b'exporting patches:\n'))
2815 ui.note(_(b'exporting patches:\n'))
2816 else:
2816 else:
2817 ui.note(_(b'exporting patch:\n'))
2817 ui.note(_(b'exporting patch:\n'))
2818
2818
2819 fntemplate = opts.get(b'output')
2819 fntemplate = opts.get(b'output')
2820 if cmdutil.isstdiofilename(fntemplate):
2820 if cmdutil.isstdiofilename(fntemplate):
2821 fntemplate = b''
2821 fntemplate = b''
2822
2822
2823 if fntemplate:
2823 if fntemplate:
2824 fm = formatter.nullformatter(ui, b'export', opts)
2824 fm = formatter.nullformatter(ui, b'export', opts)
2825 else:
2825 else:
2826 ui.pager(b'export')
2826 ui.pager(b'export')
2827 fm = ui.formatter(b'export', opts)
2827 fm = ui.formatter(b'export', opts)
2828 with fm:
2828 with fm:
2829 cmdutil.export(
2829 cmdutil.export(
2830 repo,
2830 repo,
2831 revs,
2831 revs,
2832 fm,
2832 fm,
2833 fntemplate=fntemplate,
2833 fntemplate=fntemplate,
2834 switch_parent=opts.get(b'switch_parent'),
2834 switch_parent=opts.get(b'switch_parent'),
2835 opts=patch.diffallopts(ui, opts),
2835 opts=patch.diffallopts(ui, opts),
2836 )
2836 )
2837
2837
2838
2838
2839 @command(
2839 @command(
2840 b'files',
2840 b'files',
2841 [
2841 [
2842 (
2842 (
2843 b'r',
2843 b'r',
2844 b'rev',
2844 b'rev',
2845 b'',
2845 b'',
2846 _(b'search the repository as it is in REV'),
2846 _(b'search the repository as it is in REV'),
2847 _(b'REV'),
2847 _(b'REV'),
2848 ),
2848 ),
2849 (
2849 (
2850 b'0',
2850 b'0',
2851 b'print0',
2851 b'print0',
2852 None,
2852 None,
2853 _(b'end filenames with NUL, for use with xargs'),
2853 _(b'end filenames with NUL, for use with xargs'),
2854 ),
2854 ),
2855 ]
2855 ]
2856 + walkopts
2856 + walkopts
2857 + formatteropts
2857 + formatteropts
2858 + subrepoopts,
2858 + subrepoopts,
2859 _(b'[OPTION]... [FILE]...'),
2859 _(b'[OPTION]... [FILE]...'),
2860 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2860 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2861 intents={INTENT_READONLY},
2861 intents={INTENT_READONLY},
2862 )
2862 )
2863 def files(ui, repo, *pats, **opts):
2863 def files(ui, repo, *pats, **opts):
2864 """list tracked files
2864 """list tracked files
2865
2865
2866 Print files under Mercurial control in the working directory or
2866 Print files under Mercurial control in the working directory or
2867 specified revision for given files (excluding removed files).
2867 specified revision for given files (excluding removed files).
2868 Files can be specified as filenames or filesets.
2868 Files can be specified as filenames or filesets.
2869
2869
2870 If no files are given to match, this command prints the names
2870 If no files are given to match, this command prints the names
2871 of all files under Mercurial control.
2871 of all files under Mercurial control.
2872
2872
2873 .. container:: verbose
2873 .. container:: verbose
2874
2874
2875 Template:
2875 Template:
2876
2876
2877 The following keywords are supported in addition to the common template
2877 The following keywords are supported in addition to the common template
2878 keywords and functions. See also :hg:`help templates`.
2878 keywords and functions. See also :hg:`help templates`.
2879
2879
2880 :flags: String. Character denoting file's symlink and executable bits.
2880 :flags: String. Character denoting file's symlink and executable bits.
2881 :path: String. Repository-absolute path of the file.
2881 :path: String. Repository-absolute path of the file.
2882 :size: Integer. Size of the file in bytes.
2882 :size: Integer. Size of the file in bytes.
2883
2883
2884 Examples:
2884 Examples:
2885
2885
2886 - list all files under the current directory::
2886 - list all files under the current directory::
2887
2887
2888 hg files .
2888 hg files .
2889
2889
2890 - shows sizes and flags for current revision::
2890 - shows sizes and flags for current revision::
2891
2891
2892 hg files -vr .
2892 hg files -vr .
2893
2893
2894 - list all files named README::
2894 - list all files named README::
2895
2895
2896 hg files -I "**/README"
2896 hg files -I "**/README"
2897
2897
2898 - list all binary files::
2898 - list all binary files::
2899
2899
2900 hg files "set:binary()"
2900 hg files "set:binary()"
2901
2901
2902 - find files containing a regular expression::
2902 - find files containing a regular expression::
2903
2903
2904 hg files "set:grep('bob')"
2904 hg files "set:grep('bob')"
2905
2905
2906 - search tracked file contents with xargs and grep::
2906 - search tracked file contents with xargs and grep::
2907
2907
2908 hg files -0 | xargs -0 grep foo
2908 hg files -0 | xargs -0 grep foo
2909
2909
2910 See :hg:`help patterns` and :hg:`help filesets` for more information
2910 See :hg:`help patterns` and :hg:`help filesets` for more information
2911 on specifying file patterns.
2911 on specifying file patterns.
2912
2912
2913 Returns 0 if a match is found, 1 otherwise.
2913 Returns 0 if a match is found, 1 otherwise.
2914
2914
2915 """
2915 """
2916
2916
2917 opts = pycompat.byteskwargs(opts)
2917 opts = pycompat.byteskwargs(opts)
2918 rev = opts.get(b'rev')
2918 rev = opts.get(b'rev')
2919 if rev:
2919 if rev:
2920 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
2920 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
2921 ctx = logcmdutil.revsingle(repo, rev, None)
2921 ctx = logcmdutil.revsingle(repo, rev, None)
2922
2922
2923 end = b'\n'
2923 end = b'\n'
2924 if opts.get(b'print0'):
2924 if opts.get(b'print0'):
2925 end = b'\0'
2925 end = b'\0'
2926 fmt = b'%s' + end
2926 fmt = b'%s' + end
2927
2927
2928 m = scmutil.match(ctx, pats, opts)
2928 m = scmutil.match(ctx, pats, opts)
2929 ui.pager(b'files')
2929 ui.pager(b'files')
2930 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2930 uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
2931 with ui.formatter(b'files', opts) as fm:
2931 with ui.formatter(b'files', opts) as fm:
2932 return cmdutil.files(
2932 return cmdutil.files(
2933 ui, ctx, m, uipathfn, fm, fmt, opts.get(b'subrepos')
2933 ui, ctx, m, uipathfn, fm, fmt, opts.get(b'subrepos')
2934 )
2934 )
2935
2935
2936
2936
2937 @command(
2937 @command(
2938 b'forget',
2938 b'forget',
2939 [
2939 [
2940 (b'i', b'interactive', None, _(b'use interactive mode')),
2940 (b'i', b'interactive', None, _(b'use interactive mode')),
2941 ]
2941 ]
2942 + walkopts
2942 + walkopts
2943 + dryrunopts,
2943 + dryrunopts,
2944 _(b'[OPTION]... FILE...'),
2944 _(b'[OPTION]... FILE...'),
2945 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2945 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
2946 helpbasic=True,
2946 helpbasic=True,
2947 inferrepo=True,
2947 inferrepo=True,
2948 )
2948 )
2949 def forget(ui, repo, *pats, **opts):
2949 def forget(ui, repo, *pats, **opts):
2950 """forget the specified files on the next commit
2950 """forget the specified files on the next commit
2951
2951
2952 Mark the specified files so they will no longer be tracked
2952 Mark the specified files so they will no longer be tracked
2953 after the next commit.
2953 after the next commit.
2954
2954
2955 This only removes files from the current branch, not from the
2955 This only removes files from the current branch, not from the
2956 entire project history, and it does not delete them from the
2956 entire project history, and it does not delete them from the
2957 working directory.
2957 working directory.
2958
2958
2959 To delete the file from the working directory, see :hg:`remove`.
2959 To delete the file from the working directory, see :hg:`remove`.
2960
2960
2961 To undo a forget before the next commit, see :hg:`add`.
2961 To undo a forget before the next commit, see :hg:`add`.
2962
2962
2963 .. container:: verbose
2963 .. container:: verbose
2964
2964
2965 Examples:
2965 Examples:
2966
2966
2967 - forget newly-added binary files::
2967 - forget newly-added binary files::
2968
2968
2969 hg forget "set:added() and binary()"
2969 hg forget "set:added() and binary()"
2970
2970
2971 - forget files that would be excluded by .hgignore::
2971 - forget files that would be excluded by .hgignore::
2972
2972
2973 hg forget "set:hgignore()"
2973 hg forget "set:hgignore()"
2974
2974
2975 Returns 0 on success.
2975 Returns 0 on success.
2976 """
2976 """
2977
2977
2978 if not pats:
2978 if not pats:
2979 raise error.InputError(_(b'no files specified'))
2979 raise error.InputError(_(b'no files specified'))
2980
2980
2981 with repo.wlock(), repo.dirstate.changing_files(repo):
2981 with repo.wlock(), repo.dirstate.changing_files(repo):
2982 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
2982 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
2983 dryrun, interactive = opts.get('dry_run'), opts.get('interactive')
2983 dryrun, interactive = opts.get('dry_run'), opts.get('interactive')
2984 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2984 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2985 rejected = cmdutil.forget(
2985 rejected = cmdutil.forget(
2986 ui,
2986 ui,
2987 repo,
2987 repo,
2988 m,
2988 m,
2989 prefix=b"",
2989 prefix=b"",
2990 uipathfn=uipathfn,
2990 uipathfn=uipathfn,
2991 explicitonly=False,
2991 explicitonly=False,
2992 dryrun=dryrun,
2992 dryrun=dryrun,
2993 interactive=interactive,
2993 interactive=interactive,
2994 )[0]
2994 )[0]
2995 return rejected and 1 or 0
2995 return rejected and 1 or 0
2996
2996
2997
2997
2998 @command(
2998 @command(
2999 b'graft',
2999 b'graft',
3000 [
3000 [
3001 (b'r', b'rev', [], _(b'revisions to graft'), _(b'REV')),
3001 (b'r', b'rev', [], _(b'revisions to graft'), _(b'REV')),
3002 (
3002 (
3003 b'',
3003 b'',
3004 b'base',
3004 b'base',
3005 b'',
3005 b'',
3006 _(b'base revision when doing the graft merge (ADVANCED)'),
3006 _(b'base revision when doing the graft merge (ADVANCED)'),
3007 _(b'REV'),
3007 _(b'REV'),
3008 ),
3008 ),
3009 (b'c', b'continue', False, _(b'resume interrupted graft')),
3009 (b'c', b'continue', False, _(b'resume interrupted graft')),
3010 (b'', b'stop', False, _(b'stop interrupted graft')),
3010 (b'', b'stop', False, _(b'stop interrupted graft')),
3011 (b'', b'abort', False, _(b'abort interrupted graft')),
3011 (b'', b'abort', False, _(b'abort interrupted graft')),
3012 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
3012 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
3013 (b'', b'log', None, _(b'append graft info to log message')),
3013 (b'', b'log', None, _(b'append graft info to log message')),
3014 (
3014 (
3015 b'',
3015 b'',
3016 b'no-commit',
3016 b'no-commit',
3017 None,
3017 None,
3018 _(b"don't commit, just apply the changes in working directory"),
3018 _(b"don't commit, just apply the changes in working directory"),
3019 ),
3019 ),
3020 (b'f', b'force', False, _(b'force graft')),
3020 (b'f', b'force', False, _(b'force graft')),
3021 (
3021 (
3022 b'D',
3022 b'D',
3023 b'currentdate',
3023 b'currentdate',
3024 False,
3024 False,
3025 _(b'record the current date as commit date'),
3025 _(b'record the current date as commit date'),
3026 ),
3026 ),
3027 (
3027 (
3028 b'U',
3028 b'U',
3029 b'currentuser',
3029 b'currentuser',
3030 False,
3030 False,
3031 _(b'record the current user as committer'),
3031 _(b'record the current user as committer'),
3032 ),
3032 ),
3033 ]
3033 ]
3034 + commitopts2
3034 + commitopts2
3035 + mergetoolopts
3035 + mergetoolopts
3036 + dryrunopts,
3036 + dryrunopts,
3037 _(b'[OPTION]... [-r REV]... REV...'),
3037 _(b'[OPTION]... [-r REV]... REV...'),
3038 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
3038 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
3039 )
3039 )
3040 def graft(ui, repo, *revs, **opts):
3040 def graft(ui, repo, *revs, **opts):
3041 """copy changes from other branches onto the current branch
3041 """copy changes from other branches onto the current branch
3042
3042
3043 This command uses Mercurial's merge logic to copy individual
3043 This command uses Mercurial's merge logic to copy individual
3044 changes from other branches without merging branches in the
3044 changes from other branches without merging branches in the
3045 history graph. This is sometimes known as 'backporting' or
3045 history graph. This is sometimes known as 'backporting' or
3046 'cherry-picking'. By default, graft will copy user, date, and
3046 'cherry-picking'. By default, graft will copy user, date, and
3047 description from the source changesets.
3047 description from the source changesets.
3048
3048
3049 Changesets that are ancestors of the current revision, that have
3049 Changesets that are ancestors of the current revision, that have
3050 already been grafted, or that are merges will be skipped.
3050 already been grafted, or that are merges will be skipped.
3051
3051
3052 If --log is specified, log messages will have a comment appended
3052 If --log is specified, log messages will have a comment appended
3053 of the form::
3053 of the form::
3054
3054
3055 (grafted from CHANGESETHASH)
3055 (grafted from CHANGESETHASH)
3056
3056
3057 If --force is specified, revisions will be grafted even if they
3057 If --force is specified, revisions will be grafted even if they
3058 are already ancestors of, or have been grafted to, the destination.
3058 are already ancestors of, or have been grafted to, the destination.
3059 This is useful when the revisions have since been backed out.
3059 This is useful when the revisions have since been backed out.
3060
3060
3061 If a graft merge results in conflicts, the graft process is
3061 If a graft merge results in conflicts, the graft process is
3062 interrupted so that the current merge can be manually resolved.
3062 interrupted so that the current merge can be manually resolved.
3063 Once all conflicts are addressed, the graft process can be
3063 Once all conflicts are addressed, the graft process can be
3064 continued with the -c/--continue option.
3064 continued with the -c/--continue option.
3065
3065
3066 The -c/--continue option reapplies all the earlier options.
3066 The -c/--continue option reapplies all the earlier options.
3067
3067
3068 .. container:: verbose
3068 .. container:: verbose
3069
3069
3070 The --base option exposes more of how graft internally uses merge with a
3070 The --base option exposes more of how graft internally uses merge with a
3071 custom base revision. --base can be used to specify another ancestor than
3071 custom base revision. --base can be used to specify another ancestor than
3072 the first and only parent.
3072 the first and only parent.
3073
3073
3074 The command::
3074 The command::
3075
3075
3076 hg graft -r 345 --base 234
3076 hg graft -r 345 --base 234
3077
3077
3078 is thus pretty much the same as::
3078 is thus pretty much the same as::
3079
3079
3080 hg diff --from 234 --to 345 | hg import
3080 hg diff --from 234 --to 345 | hg import
3081
3081
3082 but using merge to resolve conflicts and track moved files.
3082 but using merge to resolve conflicts and track moved files.
3083
3083
3084 The result of a merge can thus be backported as a single commit by
3084 The result of a merge can thus be backported as a single commit by
3085 specifying one of the merge parents as base, and thus effectively
3085 specifying one of the merge parents as base, and thus effectively
3086 grafting the changes from the other side.
3086 grafting the changes from the other side.
3087
3087
3088 It is also possible to collapse multiple changesets and clean up history
3088 It is also possible to collapse multiple changesets and clean up history
3089 by specifying another ancestor as base, much like rebase --collapse
3089 by specifying another ancestor as base, much like rebase --collapse
3090 --keep.
3090 --keep.
3091
3091
3092 The commit message can be tweaked after the fact using commit --amend .
3092 The commit message can be tweaked after the fact using commit --amend .
3093
3093
3094 For using non-ancestors as the base to backout changes, see the backout
3094 For using non-ancestors as the base to backout changes, see the backout
3095 command and the hidden --parent option.
3095 command and the hidden --parent option.
3096
3096
3097 .. container:: verbose
3097 .. container:: verbose
3098
3098
3099 Examples:
3099 Examples:
3100
3100
3101 - copy a single change to the stable branch and edit its description::
3101 - copy a single change to the stable branch and edit its description::
3102
3102
3103 hg update stable
3103 hg update stable
3104 hg graft --edit 9393
3104 hg graft --edit 9393
3105
3105
3106 - graft a range of changesets with one exception, updating dates::
3106 - graft a range of changesets with one exception, updating dates::
3107
3107
3108 hg graft -D "2085::2093 and not 2091"
3108 hg graft -D "2085::2093 and not 2091"
3109
3109
3110 - continue a graft after resolving conflicts::
3110 - continue a graft after resolving conflicts::
3111
3111
3112 hg graft -c
3112 hg graft -c
3113
3113
3114 - show the source of a grafted changeset::
3114 - show the source of a grafted changeset::
3115
3115
3116 hg log --debug -r .
3116 hg log --debug -r .
3117
3117
3118 - show revisions sorted by date::
3118 - show revisions sorted by date::
3119
3119
3120 hg log -r "sort(all(), date)"
3120 hg log -r "sort(all(), date)"
3121
3121
3122 - backport the result of a merge as a single commit::
3122 - backport the result of a merge as a single commit::
3123
3123
3124 hg graft -r 123 --base 123^
3124 hg graft -r 123 --base 123^
3125
3125
3126 - land a feature branch as one changeset::
3126 - land a feature branch as one changeset::
3127
3127
3128 hg up -cr default
3128 hg up -cr default
3129 hg graft -r featureX --base "ancestor('featureX', 'default')"
3129 hg graft -r featureX --base "ancestor('featureX', 'default')"
3130
3130
3131 See :hg:`help revisions` for more about specifying revisions.
3131 See :hg:`help revisions` for more about specifying revisions.
3132
3132
3133 Returns 0 on successful completion, 1 if there are unresolved files.
3133 Returns 0 on successful completion, 1 if there are unresolved files.
3134 """
3134 """
3135 with repo.wlock():
3135 with repo.wlock():
3136 return _dograft(ui, repo, *revs, **opts)
3136 return _dograft(ui, repo, *revs, **opts)
3137
3137
3138
3138
3139 def _dograft(ui, repo, *revs, **opts):
3139 def _dograft(ui, repo, *revs, **opts):
3140 if revs and opts.get('rev'):
3140 if revs and opts.get('rev'):
3141 ui.warn(
3141 ui.warn(
3142 _(
3142 _(
3143 b'warning: inconsistent use of --rev might give unexpected '
3143 b'warning: inconsistent use of --rev might give unexpected '
3144 b'revision ordering!\n'
3144 b'revision ordering!\n'
3145 )
3145 )
3146 )
3146 )
3147
3147
3148 revs = list(revs)
3148 revs = list(revs)
3149 revs.extend(opts.get('rev'))
3149 revs.extend(opts.get('rev'))
3150 # a dict of data to be stored in state file
3150 # a dict of data to be stored in state file
3151 statedata = {}
3151 statedata = {}
3152 # list of new nodes created by ongoing graft
3152 # list of new nodes created by ongoing graft
3153 statedata[b'newnodes'] = []
3153 statedata[b'newnodes'] = []
3154
3154
3155 cmdutil.resolve_commit_options(ui, opts)
3155 cmdutil.resolve_commit_options(ui, opts)
3156
3156
3157 editor = cmdutil.getcommiteditor(editform=b'graft', **opts)
3157 editor = cmdutil.getcommiteditor(editform=b'graft', **opts)
3158
3158
3159 cmdutil.check_at_most_one_arg(opts, 'abort', 'stop', 'continue')
3159 cmdutil.check_at_most_one_arg(opts, 'abort', 'stop', 'continue')
3160
3160
3161 cont = False
3161 cont = False
3162 if opts.get('no_commit'):
3162 if opts.get('no_commit'):
3163 cmdutil.check_incompatible_arguments(
3163 cmdutil.check_incompatible_arguments(
3164 opts,
3164 opts,
3165 'no_commit',
3165 'no_commit',
3166 ['edit', 'currentuser', 'currentdate', 'log'],
3166 ['edit', 'currentuser', 'currentdate', 'log'],
3167 )
3167 )
3168
3168
3169 graftstate = statemod.cmdstate(repo, b'graftstate')
3169 graftstate = statemod.cmdstate(repo, b'graftstate')
3170
3170
3171 if opts.get('stop'):
3171 if opts.get('stop'):
3172 cmdutil.check_incompatible_arguments(
3172 cmdutil.check_incompatible_arguments(
3173 opts,
3173 opts,
3174 'stop',
3174 'stop',
3175 [
3175 [
3176 'edit',
3176 'edit',
3177 'log',
3177 'log',
3178 'user',
3178 'user',
3179 'date',
3179 'date',
3180 'currentdate',
3180 'currentdate',
3181 'currentuser',
3181 'currentuser',
3182 'rev',
3182 'rev',
3183 ],
3183 ],
3184 )
3184 )
3185 return _stopgraft(ui, repo, graftstate)
3185 return _stopgraft(ui, repo, graftstate)
3186 elif opts.get('abort'):
3186 elif opts.get('abort'):
3187 cmdutil.check_incompatible_arguments(
3187 cmdutil.check_incompatible_arguments(
3188 opts,
3188 opts,
3189 'abort',
3189 'abort',
3190 [
3190 [
3191 'edit',
3191 'edit',
3192 'log',
3192 'log',
3193 'user',
3193 'user',
3194 'date',
3194 'date',
3195 'currentdate',
3195 'currentdate',
3196 'currentuser',
3196 'currentuser',
3197 'rev',
3197 'rev',
3198 ],
3198 ],
3199 )
3199 )
3200 return cmdutil.abortgraft(ui, repo, graftstate)
3200 return cmdutil.abortgraft(ui, repo, graftstate)
3201 elif opts.get('continue'):
3201 elif opts.get('continue'):
3202 cont = True
3202 cont = True
3203 if revs:
3203 if revs:
3204 raise error.InputError(_(b"can't specify --continue and revisions"))
3204 raise error.InputError(_(b"can't specify --continue and revisions"))
3205 # read in unfinished revisions
3205 # read in unfinished revisions
3206 if graftstate.exists():
3206 if graftstate.exists():
3207 statedata = cmdutil.readgraftstate(repo, graftstate)
3207 statedata = cmdutil.readgraftstate(repo, graftstate)
3208 if statedata.get(b'date'):
3208 if statedata.get(b'date'):
3209 opts['date'] = statedata[b'date']
3209 opts['date'] = statedata[b'date']
3210 if statedata.get(b'user'):
3210 if statedata.get(b'user'):
3211 opts['user'] = statedata[b'user']
3211 opts['user'] = statedata[b'user']
3212 if statedata.get(b'log'):
3212 if statedata.get(b'log'):
3213 opts['log'] = True
3213 opts['log'] = True
3214 if statedata.get(b'no_commit'):
3214 if statedata.get(b'no_commit'):
3215 opts['no_commit'] = statedata.get(b'no_commit')
3215 opts['no_commit'] = statedata.get(b'no_commit')
3216 if statedata.get(b'base'):
3216 if statedata.get(b'base'):
3217 opts['base'] = statedata.get(b'base')
3217 opts['base'] = statedata.get(b'base')
3218 nodes = statedata[b'nodes']
3218 nodes = statedata[b'nodes']
3219 revs = [repo[node].rev() for node in nodes]
3219 revs = [repo[node].rev() for node in nodes]
3220 else:
3220 else:
3221 cmdutil.wrongtooltocontinue(repo, _(b'graft'))
3221 cmdutil.wrongtooltocontinue(repo, _(b'graft'))
3222 else:
3222 else:
3223 if not revs:
3223 if not revs:
3224 raise error.InputError(_(b'no revisions specified'))
3224 raise error.InputError(_(b'no revisions specified'))
3225 cmdutil.checkunfinished(repo)
3225 cmdutil.checkunfinished(repo)
3226 cmdutil.bailifchanged(repo)
3226 cmdutil.bailifchanged(repo)
3227 revs = logcmdutil.revrange(repo, revs)
3227 revs = logcmdutil.revrange(repo, revs)
3228
3228
3229 skipped = set()
3229 skipped = set()
3230 basectx = None
3230 basectx = None
3231 if opts.get('base'):
3231 if opts.get('base'):
3232 basectx = logcmdutil.revsingle(repo, opts['base'], None)
3232 basectx = logcmdutil.revsingle(repo, opts['base'], None)
3233 if basectx is None:
3233 if basectx is None:
3234 # check for merges
3234 # check for merges
3235 for rev in repo.revs(b'%ld and merge()', revs):
3235 for rev in repo.revs(b'%ld and merge()', revs):
3236 ui.warn(_(b'skipping ungraftable merge revision %d\n') % rev)
3236 ui.warn(_(b'skipping ungraftable merge revision %d\n') % rev)
3237 skipped.add(rev)
3237 skipped.add(rev)
3238 revs = [r for r in revs if r not in skipped]
3238 revs = [r for r in revs if r not in skipped]
3239 if not revs:
3239 if not revs:
3240 return -1
3240 return -1
3241 if basectx is not None and len(revs) != 1:
3241 if basectx is not None and len(revs) != 1:
3242 raise error.InputError(_(b'only one revision allowed with --base '))
3242 raise error.InputError(_(b'only one revision allowed with --base '))
3243
3243
3244 # Don't check in the --continue case, in effect retaining --force across
3244 # Don't check in the --continue case, in effect retaining --force across
3245 # --continues. That's because without --force, any revisions we decided to
3245 # --continues. That's because without --force, any revisions we decided to
3246 # skip would have been filtered out here, so they wouldn't have made their
3246 # skip would have been filtered out here, so they wouldn't have made their
3247 # way to the graftstate. With --force, any revisions we would have otherwise
3247 # way to the graftstate. With --force, any revisions we would have otherwise
3248 # skipped would not have been filtered out, and if they hadn't been applied
3248 # skipped would not have been filtered out, and if they hadn't been applied
3249 # already, they'd have been in the graftstate.
3249 # already, they'd have been in the graftstate.
3250 if not (cont or opts.get('force')) and basectx is None:
3250 if not (cont or opts.get('force')) and basectx is None:
3251 # check for ancestors of dest branch
3251 # check for ancestors of dest branch
3252 ancestors = repo.revs(b'%ld & (::.)', revs)
3252 ancestors = repo.revs(b'%ld & (::.)', revs)
3253 for rev in ancestors:
3253 for rev in ancestors:
3254 ui.warn(_(b'skipping ancestor revision %d:%s\n') % (rev, repo[rev]))
3254 ui.warn(_(b'skipping ancestor revision %d:%s\n') % (rev, repo[rev]))
3255
3255
3256 revs = [r for r in revs if r not in ancestors]
3256 revs = [r for r in revs if r not in ancestors]
3257
3257
3258 if not revs:
3258 if not revs:
3259 return -1
3259 return -1
3260
3260
3261 # analyze revs for earlier grafts
3261 # analyze revs for earlier grafts
3262 ids = {}
3262 ids = {}
3263 for ctx in repo.set(b"%ld", revs):
3263 for ctx in repo.set(b"%ld", revs):
3264 ids[ctx.hex()] = ctx.rev()
3264 ids[ctx.hex()] = ctx.rev()
3265 n = ctx.extra().get(b'source')
3265 n = ctx.extra().get(b'source')
3266 if n:
3266 if n:
3267 ids[n] = ctx.rev()
3267 ids[n] = ctx.rev()
3268
3268
3269 # check ancestors for earlier grafts
3269 # check ancestors for earlier grafts
3270 ui.debug(b'scanning for duplicate grafts\n')
3270 ui.debug(b'scanning for duplicate grafts\n')
3271
3271
3272 # The only changesets we can be sure doesn't contain grafts of any
3272 # The only changesets we can be sure doesn't contain grafts of any
3273 # revs, are the ones that are common ancestors of *all* revs:
3273 # revs, are the ones that are common ancestors of *all* revs:
3274 for rev in repo.revs(b'only(%d,ancestor(%ld))', repo[b'.'].rev(), revs):
3274 for rev in repo.revs(b'only(%d,ancestor(%ld))', repo[b'.'].rev(), revs):
3275 ctx = repo[rev]
3275 ctx = repo[rev]
3276 n = ctx.extra().get(b'source')
3276 n = ctx.extra().get(b'source')
3277 if n in ids:
3277 if n in ids:
3278 try:
3278 try:
3279 r = repo[n].rev()
3279 r = repo[n].rev()
3280 except error.RepoLookupError:
3280 except error.RepoLookupError:
3281 r = None
3281 r = None
3282 if r in revs:
3282 if r in revs:
3283 ui.warn(
3283 ui.warn(
3284 _(
3284 _(
3285 b'skipping revision %d:%s '
3285 b'skipping revision %d:%s '
3286 b'(already grafted to %d:%s)\n'
3286 b'(already grafted to %d:%s)\n'
3287 )
3287 )
3288 % (r, repo[r], rev, ctx)
3288 % (r, repo[r], rev, ctx)
3289 )
3289 )
3290 revs.remove(r)
3290 revs.remove(r)
3291 elif ids[n] in revs:
3291 elif ids[n] in revs:
3292 if r is None:
3292 if r is None:
3293 ui.warn(
3293 ui.warn(
3294 _(
3294 _(
3295 b'skipping already grafted revision %d:%s '
3295 b'skipping already grafted revision %d:%s '
3296 b'(%d:%s also has unknown origin %s)\n'
3296 b'(%d:%s also has unknown origin %s)\n'
3297 )
3297 )
3298 % (ids[n], repo[ids[n]], rev, ctx, n[:12])
3298 % (ids[n], repo[ids[n]], rev, ctx, n[:12])
3299 )
3299 )
3300 else:
3300 else:
3301 ui.warn(
3301 ui.warn(
3302 _(
3302 _(
3303 b'skipping already grafted revision %d:%s '
3303 b'skipping already grafted revision %d:%s '
3304 b'(%d:%s also has origin %d:%s)\n'
3304 b'(%d:%s also has origin %d:%s)\n'
3305 )
3305 )
3306 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12])
3306 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12])
3307 )
3307 )
3308 revs.remove(ids[n])
3308 revs.remove(ids[n])
3309 elif ctx.hex() in ids:
3309 elif ctx.hex() in ids:
3310 r = ids[ctx.hex()]
3310 r = ids[ctx.hex()]
3311 if r in revs:
3311 if r in revs:
3312 ui.warn(
3312 ui.warn(
3313 _(
3313 _(
3314 b'skipping already grafted revision %d:%s '
3314 b'skipping already grafted revision %d:%s '
3315 b'(was grafted from %d:%s)\n'
3315 b'(was grafted from %d:%s)\n'
3316 )
3316 )
3317 % (r, repo[r], rev, ctx)
3317 % (r, repo[r], rev, ctx)
3318 )
3318 )
3319 revs.remove(r)
3319 revs.remove(r)
3320 if not revs:
3320 if not revs:
3321 return -1
3321 return -1
3322
3322
3323 if opts.get('no_commit'):
3323 if opts.get('no_commit'):
3324 statedata[b'no_commit'] = True
3324 statedata[b'no_commit'] = True
3325 if opts.get('base'):
3325 if opts.get('base'):
3326 statedata[b'base'] = opts['base']
3326 statedata[b'base'] = opts['base']
3327 for pos, ctx in enumerate(repo.set(b"%ld", revs)):
3327 for pos, ctx in enumerate(repo.set(b"%ld", revs)):
3328 desc = b'%d:%s "%s"' % (
3328 desc = b'%d:%s "%s"' % (
3329 ctx.rev(),
3329 ctx.rev(),
3330 ctx,
3330 ctx,
3331 ctx.description().split(b'\n', 1)[0],
3331 ctx.description().split(b'\n', 1)[0],
3332 )
3332 )
3333 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3333 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3334 if names:
3334 if names:
3335 desc += b' (%s)' % b' '.join(names)
3335 desc += b' (%s)' % b' '.join(names)
3336 ui.status(_(b'grafting %s\n') % desc)
3336 ui.status(_(b'grafting %s\n') % desc)
3337 if opts.get('dry_run'):
3337 if opts.get('dry_run'):
3338 continue
3338 continue
3339
3339
3340 source = ctx.extra().get(b'source')
3340 source = ctx.extra().get(b'source')
3341 extra = {}
3341 extra = {}
3342 if source:
3342 if source:
3343 extra[b'source'] = source
3343 extra[b'source'] = source
3344 extra[b'intermediate-source'] = ctx.hex()
3344 extra[b'intermediate-source'] = ctx.hex()
3345 else:
3345 else:
3346 extra[b'source'] = ctx.hex()
3346 extra[b'source'] = ctx.hex()
3347 user = ctx.user()
3347 user = ctx.user()
3348 if opts.get('user'):
3348 if opts.get('user'):
3349 user = opts['user']
3349 user = opts['user']
3350 statedata[b'user'] = user
3350 statedata[b'user'] = user
3351 date = ctx.date()
3351 date = ctx.date()
3352 if opts.get('date'):
3352 if opts.get('date'):
3353 date = opts['date']
3353 date = opts['date']
3354 statedata[b'date'] = date
3354 statedata[b'date'] = date
3355 message = ctx.description()
3355 message = ctx.description()
3356 if opts.get('log'):
3356 if opts.get('log'):
3357 message += b'\n(grafted from %s)' % ctx.hex()
3357 message += b'\n(grafted from %s)' % ctx.hex()
3358 statedata[b'log'] = True
3358 statedata[b'log'] = True
3359
3359
3360 # we don't merge the first commit when continuing
3360 # we don't merge the first commit when continuing
3361 if not cont:
3361 if not cont:
3362 # perform the graft merge with p1(rev) as 'ancestor'
3362 # perform the graft merge with p1(rev) as 'ancestor'
3363 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
3363 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
3364 base = ctx.p1() if basectx is None else basectx
3364 base = ctx.p1() if basectx is None else basectx
3365 with ui.configoverride(overrides, b'graft'):
3365 with ui.configoverride(overrides, b'graft'):
3366 stats = mergemod.graft(
3366 stats = mergemod.graft(
3367 repo, ctx, base, [b'local', b'graft', b'parent of graft']
3367 repo, ctx, base, [b'local', b'graft', b'parent of graft']
3368 )
3368 )
3369 # report any conflicts
3369 # report any conflicts
3370 if stats.unresolvedcount > 0:
3370 if stats.unresolvedcount > 0:
3371 # write out state for --continue
3371 # write out state for --continue
3372 nodes = [repo[rev].hex() for rev in revs[pos:]]
3372 nodes = [repo[rev].hex() for rev in revs[pos:]]
3373 statedata[b'nodes'] = nodes
3373 statedata[b'nodes'] = nodes
3374 stateversion = 1
3374 stateversion = 1
3375 graftstate.save(stateversion, statedata)
3375 graftstate.save(stateversion, statedata)
3376 ui.error(_(b"abort: unresolved conflicts, can't continue\n"))
3376 ui.error(_(b"abort: unresolved conflicts, can't continue\n"))
3377 ui.error(_(b"(use 'hg resolve' and 'hg graft --continue')\n"))
3377 ui.error(_(b"(use 'hg resolve' and 'hg graft --continue')\n"))
3378 return 1
3378 return 1
3379 else:
3379 else:
3380 cont = False
3380 cont = False
3381
3381
3382 # commit if --no-commit is false
3382 # commit if --no-commit is false
3383 if not opts.get('no_commit'):
3383 if not opts.get('no_commit'):
3384 node = repo.commit(
3384 node = repo.commit(
3385 text=message, user=user, date=date, extra=extra, editor=editor
3385 text=message, user=user, date=date, extra=extra, editor=editor
3386 )
3386 )
3387 if node is None:
3387 if node is None:
3388 ui.warn(
3388 ui.warn(
3389 _(b'note: graft of %d:%s created no changes to commit\n')
3389 _(b'note: graft of %d:%s created no changes to commit\n')
3390 % (ctx.rev(), ctx)
3390 % (ctx.rev(), ctx)
3391 )
3391 )
3392 # checking that newnodes exist because old state files won't have it
3392 # checking that newnodes exist because old state files won't have it
3393 elif statedata.get(b'newnodes') is not None:
3393 elif statedata.get(b'newnodes') is not None:
3394 nn = statedata[b'newnodes']
3394 nn = statedata[b'newnodes']
3395 assert isinstance(nn, list) # list of bytes
3395 assert isinstance(nn, list) # list of bytes
3396 nn.append(node)
3396 nn.append(node)
3397
3397
3398 # remove state when we complete successfully
3398 # remove state when we complete successfully
3399 if not opts.get('dry_run'):
3399 if not opts.get('dry_run'):
3400 graftstate.delete()
3400 graftstate.delete()
3401
3401
3402 return 0
3402 return 0
3403
3403
3404
3404
3405 def _stopgraft(ui, repo, graftstate):
3405 def _stopgraft(ui, repo, graftstate):
3406 """stop the interrupted graft"""
3406 """stop the interrupted graft"""
3407 if not graftstate.exists():
3407 if not graftstate.exists():
3408 raise error.StateError(_(b"no interrupted graft found"))
3408 raise error.StateError(_(b"no interrupted graft found"))
3409 pctx = repo[b'.']
3409 pctx = repo[b'.']
3410 mergemod.clean_update(pctx)
3410 mergemod.clean_update(pctx)
3411 graftstate.delete()
3411 graftstate.delete()
3412 ui.status(_(b"stopped the interrupted graft\n"))
3412 ui.status(_(b"stopped the interrupted graft\n"))
3413 ui.status(_(b"working directory is now at %s\n") % pctx.hex()[:12])
3413 ui.status(_(b"working directory is now at %s\n") % pctx.hex()[:12])
3414 return 0
3414 return 0
3415
3415
3416
3416
3417 statemod.addunfinished(
3417 statemod.addunfinished(
3418 b'graft',
3418 b'graft',
3419 fname=b'graftstate',
3419 fname=b'graftstate',
3420 clearable=True,
3420 clearable=True,
3421 stopflag=True,
3421 stopflag=True,
3422 continueflag=True,
3422 continueflag=True,
3423 abortfunc=cmdutil.hgabortgraft,
3423 abortfunc=cmdutil.hgabortgraft,
3424 cmdhint=_(b"use 'hg graft --continue' or 'hg graft --stop' to stop"),
3424 cmdhint=_(b"use 'hg graft --continue' or 'hg graft --stop' to stop"),
3425 )
3425 )
3426
3426
3427
3427
3428 @command(
3428 @command(
3429 b'grep',
3429 b'grep',
3430 [
3430 [
3431 (b'0', b'print0', None, _(b'end fields with NUL')),
3431 (b'0', b'print0', None, _(b'end fields with NUL')),
3432 (b'', b'all', None, _(b'an alias to --diff (DEPRECATED)')),
3432 (b'', b'all', None, _(b'an alias to --diff (DEPRECATED)')),
3433 (
3433 (
3434 b'',
3434 b'',
3435 b'diff',
3435 b'diff',
3436 None,
3436 None,
3437 _(
3437 _(
3438 b'search revision differences for when the pattern was added '
3438 b'search revision differences for when the pattern was added '
3439 b'or removed'
3439 b'or removed'
3440 ),
3440 ),
3441 ),
3441 ),
3442 (b'a', b'text', None, _(b'treat all files as text')),
3442 (b'a', b'text', None, _(b'treat all files as text')),
3443 (
3443 (
3444 b'f',
3444 b'f',
3445 b'follow',
3445 b'follow',
3446 None,
3446 None,
3447 _(
3447 _(
3448 b'follow changeset history,'
3448 b'follow changeset history,'
3449 b' or file history across copies and renames'
3449 b' or file history across copies and renames'
3450 ),
3450 ),
3451 ),
3451 ),
3452 (b'i', b'ignore-case', None, _(b'ignore case when matching')),
3452 (b'i', b'ignore-case', None, _(b'ignore case when matching')),
3453 (
3453 (
3454 b'l',
3454 b'l',
3455 b'files-with-matches',
3455 b'files-with-matches',
3456 None,
3456 None,
3457 _(b'print only filenames and revisions that match'),
3457 _(b'print only filenames and revisions that match'),
3458 ),
3458 ),
3459 (b'n', b'line-number', None, _(b'print matching line numbers')),
3459 (b'n', b'line-number', None, _(b'print matching line numbers')),
3460 (
3460 (
3461 b'r',
3461 b'r',
3462 b'rev',
3462 b'rev',
3463 [],
3463 [],
3464 _(b'search files changed within revision range'),
3464 _(b'search files changed within revision range'),
3465 _(b'REV'),
3465 _(b'REV'),
3466 ),
3466 ),
3467 (
3467 (
3468 b'',
3468 b'',
3469 b'all-files',
3469 b'all-files',
3470 None,
3470 None,
3471 _(
3471 _(
3472 b'include all files in the changeset while grepping (DEPRECATED)'
3472 b'include all files in the changeset while grepping (DEPRECATED)'
3473 ),
3473 ),
3474 ),
3474 ),
3475 (b'u', b'user', None, _(b'list the author (long with -v)')),
3475 (b'u', b'user', None, _(b'list the author (long with -v)')),
3476 (b'd', b'date', None, _(b'list the date (short with -q)')),
3476 (b'd', b'date', None, _(b'list the date (short with -q)')),
3477 ]
3477 ]
3478 + formatteropts
3478 + formatteropts
3479 + walkopts,
3479 + walkopts,
3480 _(b'[--diff] [OPTION]... PATTERN [FILE]...'),
3480 _(b'[--diff] [OPTION]... PATTERN [FILE]...'),
3481 helpcategory=command.CATEGORY_FILE_CONTENTS,
3481 helpcategory=command.CATEGORY_FILE_CONTENTS,
3482 inferrepo=True,
3482 inferrepo=True,
3483 intents={INTENT_READONLY},
3483 intents={INTENT_READONLY},
3484 )
3484 )
3485 def grep(ui, repo, pattern, *pats, **opts):
3485 def grep(ui, repo, pattern, *pats, **opts):
3486 """search for a pattern in specified files
3486 """search for a pattern in specified files
3487
3487
3488 Search the working directory or revision history for a regular
3488 Search the working directory or revision history for a regular
3489 expression in the specified files for the entire repository.
3489 expression in the specified files for the entire repository.
3490
3490
3491 By default, grep searches the repository files in the working
3491 By default, grep searches the repository files in the working
3492 directory and prints the files where it finds a match. To specify
3492 directory and prints the files where it finds a match. To specify
3493 historical revisions instead of the working directory, use the
3493 historical revisions instead of the working directory, use the
3494 --rev flag.
3494 --rev flag.
3495
3495
3496 To search instead historical revision differences that contains a
3496 To search instead historical revision differences that contains a
3497 change in match status ("-" for a match that becomes a non-match,
3497 change in match status ("-" for a match that becomes a non-match,
3498 or "+" for a non-match that becomes a match), use the --diff flag.
3498 or "+" for a non-match that becomes a match), use the --diff flag.
3499
3499
3500 PATTERN can be any Python (roughly Perl-compatible) regular
3500 PATTERN can be any Python (roughly Perl-compatible) regular
3501 expression.
3501 expression.
3502
3502
3503 If no FILEs are specified and the --rev flag isn't supplied, all
3503 If no FILEs are specified and the --rev flag isn't supplied, all
3504 files in the working directory are searched. When using the --rev
3504 files in the working directory are searched. When using the --rev
3505 flag and specifying FILEs, use the --follow argument to also
3505 flag and specifying FILEs, use the --follow argument to also
3506 follow the specified FILEs across renames and copies.
3506 follow the specified FILEs across renames and copies.
3507
3507
3508 .. container:: verbose
3508 .. container:: verbose
3509
3509
3510 Template:
3510 Template:
3511
3511
3512 The following keywords are supported in addition to the common template
3512 The following keywords are supported in addition to the common template
3513 keywords and functions. See also :hg:`help templates`.
3513 keywords and functions. See also :hg:`help templates`.
3514
3514
3515 :change: String. Character denoting insertion ``+`` or removal ``-``.
3515 :change: String. Character denoting insertion ``+`` or removal ``-``.
3516 Available if ``--diff`` is specified.
3516 Available if ``--diff`` is specified.
3517 :lineno: Integer. Line number of the match.
3517 :lineno: Integer. Line number of the match.
3518 :path: String. Repository-absolute path of the file.
3518 :path: String. Repository-absolute path of the file.
3519 :texts: List of text chunks.
3519 :texts: List of text chunks.
3520
3520
3521 And each entry of ``{texts}`` provides the following sub-keywords.
3521 And each entry of ``{texts}`` provides the following sub-keywords.
3522
3522
3523 :matched: Boolean. True if the chunk matches the specified pattern.
3523 :matched: Boolean. True if the chunk matches the specified pattern.
3524 :text: String. Chunk content.
3524 :text: String. Chunk content.
3525
3525
3526 See :hg:`help templates.operators` for the list expansion syntax.
3526 See :hg:`help templates.operators` for the list expansion syntax.
3527
3527
3528 Returns 0 if a match is found, 1 otherwise.
3528 Returns 0 if a match is found, 1 otherwise.
3529
3529
3530 """
3530 """
3531 cmdutil.check_incompatible_arguments(opts, 'all_files', ['all', 'diff'])
3531 cmdutil.check_incompatible_arguments(opts, 'all_files', ['all', 'diff'])
3532
3532
3533 diff = opts.get('all') or opts.get('diff')
3533 diff = opts.get('all') or opts.get('diff')
3534 follow = opts.get('follow')
3534 follow = opts.get('follow')
3535 if opts.get('all_files') is None and not diff:
3535 if opts.get('all_files') is None and not diff:
3536 opts['all_files'] = True
3536 opts['all_files'] = True
3537 plaingrep = (
3537 plaingrep = (
3538 opts.get('all_files') and not opts.get('rev') and not opts.get('follow')
3538 opts.get('all_files') and not opts.get('rev') and not opts.get('follow')
3539 )
3539 )
3540 all_files = opts.get('all_files')
3540 all_files = opts.get('all_files')
3541 if plaingrep:
3541 if plaingrep:
3542 opts['rev'] = [b'wdir()']
3542 opts['rev'] = [b'wdir()']
3543
3543
3544 reflags = re.M
3544 reflags = re.M
3545 if opts.get('ignore_case'):
3545 if opts.get('ignore_case'):
3546 reflags |= re.I
3546 reflags |= re.I
3547 try:
3547 try:
3548 regexp = util.re.compile(pattern, reflags)
3548 regexp = util.re.compile(pattern, reflags)
3549 except re.error as inst:
3549 except re.error as inst:
3550 ui.warn(
3550 ui.warn(
3551 _(b"grep: invalid match pattern: %s\n")
3551 _(b"grep: invalid match pattern: %s\n")
3552 % stringutil.forcebytestr(inst)
3552 % stringutil.forcebytestr(inst)
3553 )
3553 )
3554 return 1
3554 return 1
3555 sep, eol = b':', b'\n'
3555 sep, eol = b':', b'\n'
3556 if opts.get('print0'):
3556 if opts.get('print0'):
3557 sep = eol = b'\0'
3557 sep = eol = b'\0'
3558
3558
3559 searcher = grepmod.grepsearcher(
3559 searcher = grepmod.grepsearcher(
3560 ui, repo, regexp, all_files=all_files, diff=diff, follow=follow
3560 ui, repo, regexp, all_files=all_files, diff=diff, follow=follow
3561 )
3561 )
3562
3562
3563 getfile = searcher._getfile
3563 getfile = searcher._getfile
3564
3564
3565 uipathfn = scmutil.getuipathfn(repo)
3565 uipathfn = scmutil.getuipathfn(repo)
3566
3566
3567 def display(fm, fn, ctx, pstates, states):
3567 def display(fm, fn, ctx, pstates, states):
3568 rev = scmutil.intrev(ctx)
3568 rev = scmutil.intrev(ctx)
3569 if fm.isplain():
3569 if fm.isplain():
3570 formatuser = ui.shortuser
3570 formatuser = ui.shortuser
3571 else:
3571 else:
3572 formatuser = pycompat.bytestr
3572 formatuser = pycompat.bytestr
3573 if ui.quiet:
3573 if ui.quiet:
3574 datefmt = b'%Y-%m-%d'
3574 datefmt = b'%Y-%m-%d'
3575 else:
3575 else:
3576 datefmt = b'%a %b %d %H:%M:%S %Y %1%2'
3576 datefmt = b'%a %b %d %H:%M:%S %Y %1%2'
3577 found = False
3577 found = False
3578
3578
3579 @util.cachefunc
3579 @util.cachefunc
3580 def binary():
3580 def binary():
3581 flog = getfile(fn)
3581 flog = getfile(fn)
3582 try:
3582 try:
3583 return stringutil.binary(flog.read(ctx.filenode(fn)))
3583 return stringutil.binary(flog.read(ctx.filenode(fn)))
3584 except error.WdirUnsupported:
3584 except error.WdirUnsupported:
3585 return ctx[fn].isbinary()
3585 return ctx[fn].isbinary()
3586
3586
3587 fieldnamemap = {b'linenumber': b'lineno'}
3587 fieldnamemap = {b'linenumber': b'lineno'}
3588 if diff:
3588 if diff:
3589 iter = grepmod.difflinestates(pstates, states)
3589 iter = grepmod.difflinestates(pstates, states)
3590 else:
3590 else:
3591 iter = [(b'', l) for l in states]
3591 iter = [(b'', l) for l in states]
3592 for change, l in iter:
3592 for change, l in iter:
3593 fm.startitem()
3593 fm.startitem()
3594 fm.context(ctx=ctx)
3594 fm.context(ctx=ctx)
3595 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
3595 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
3596 fm.plain(uipathfn(fn), label=b'grep.filename')
3596 fm.plain(uipathfn(fn), label=b'grep.filename')
3597
3597
3598 cols = [
3598 cols = [
3599 (b'rev', b'%d', rev, not plaingrep, b''),
3599 (b'rev', b'%d', rev, not plaingrep, b''),
3600 (
3600 (
3601 b'linenumber',
3601 b'linenumber',
3602 b'%d',
3602 b'%d',
3603 l.linenum,
3603 l.linenum,
3604 opts.get('line_number'),
3604 opts.get('line_number'),
3605 b'',
3605 b'',
3606 ),
3606 ),
3607 ]
3607 ]
3608 if diff:
3608 if diff:
3609 cols.append(
3609 cols.append(
3610 (
3610 (
3611 b'change',
3611 b'change',
3612 b'%s',
3612 b'%s',
3613 change,
3613 change,
3614 True,
3614 True,
3615 b'grep.inserted '
3615 b'grep.inserted '
3616 if change == b'+'
3616 if change == b'+'
3617 else b'grep.deleted ',
3617 else b'grep.deleted ',
3618 )
3618 )
3619 )
3619 )
3620 cols.extend(
3620 cols.extend(
3621 [
3621 [
3622 (
3622 (
3623 b'user',
3623 b'user',
3624 b'%s',
3624 b'%s',
3625 formatuser(ctx.user()),
3625 formatuser(ctx.user()),
3626 opts.get('user'),
3626 opts.get('user'),
3627 b'',
3627 b'',
3628 ),
3628 ),
3629 (
3629 (
3630 b'date',
3630 b'date',
3631 b'%s',
3631 b'%s',
3632 fm.formatdate(ctx.date(), datefmt),
3632 fm.formatdate(ctx.date(), datefmt),
3633 opts.get('date'),
3633 opts.get('date'),
3634 b'',
3634 b'',
3635 ),
3635 ),
3636 ]
3636 ]
3637 )
3637 )
3638 for name, fmt, data, cond, extra_label in cols:
3638 for name, fmt, data, cond, extra_label in cols:
3639 if cond:
3639 if cond:
3640 fm.plain(sep, label=b'grep.sep')
3640 fm.plain(sep, label=b'grep.sep')
3641 field = fieldnamemap.get(name, name)
3641 field = fieldnamemap.get(name, name)
3642 label = extra_label + (b'grep.%s' % name)
3642 label = extra_label + (b'grep.%s' % name)
3643 fm.condwrite(cond, field, fmt, data, label=label)
3643 fm.condwrite(cond, field, fmt, data, label=label)
3644 if not opts.get('files_with_matches'):
3644 if not opts.get('files_with_matches'):
3645 fm.plain(sep, label=b'grep.sep')
3645 fm.plain(sep, label=b'grep.sep')
3646 if not opts.get('text') and binary():
3646 if not opts.get('text') and binary():
3647 fm.plain(_(b" Binary file matches"))
3647 fm.plain(_(b" Binary file matches"))
3648 else:
3648 else:
3649 displaymatches(fm.nested(b'texts', tmpl=b'{text}'), l)
3649 displaymatches(fm.nested(b'texts', tmpl=b'{text}'), l)
3650 fm.plain(eol)
3650 fm.plain(eol)
3651 found = True
3651 found = True
3652 if opts.get('files_with_matches'):
3652 if opts.get('files_with_matches'):
3653 break
3653 break
3654 return found
3654 return found
3655
3655
3656 def displaymatches(fm, l):
3656 def displaymatches(fm, l):
3657 p = 0
3657 p = 0
3658 for s, e in l.findpos(regexp):
3658 for s, e in l.findpos(regexp):
3659 if p < s:
3659 if p < s:
3660 fm.startitem()
3660 fm.startitem()
3661 fm.write(b'text', b'%s', l.line[p:s])
3661 fm.write(b'text', b'%s', l.line[p:s])
3662 fm.data(matched=False)
3662 fm.data(matched=False)
3663 fm.startitem()
3663 fm.startitem()
3664 fm.write(b'text', b'%s', l.line[s:e], label=b'grep.match')
3664 fm.write(b'text', b'%s', l.line[s:e], label=b'grep.match')
3665 fm.data(matched=True)
3665 fm.data(matched=True)
3666 p = e
3666 p = e
3667 if p < len(l.line):
3667 if p < len(l.line):
3668 fm.startitem()
3668 fm.startitem()
3669 fm.write(b'text', b'%s', l.line[p:])
3669 fm.write(b'text', b'%s', l.line[p:])
3670 fm.data(matched=False)
3670 fm.data(matched=False)
3671 fm.end()
3671 fm.end()
3672
3672
3673 found = False
3673 found = False
3674
3674
3675 wopts = logcmdutil.walkopts(
3675 wopts = logcmdutil.walkopts(
3676 pats=pats,
3676 pats=pats,
3677 opts=opts,
3677 opts=opts,
3678 revspec=opts['rev'],
3678 revspec=opts['rev'],
3679 include_pats=opts['include'],
3679 include_pats=opts['include'],
3680 exclude_pats=opts['exclude'],
3680 exclude_pats=opts['exclude'],
3681 follow=follow,
3681 follow=follow,
3682 force_changelog_traversal=all_files,
3682 force_changelog_traversal=all_files,
3683 filter_revisions_by_pats=not all_files,
3683 filter_revisions_by_pats=not all_files,
3684 )
3684 )
3685 revs, makefilematcher = logcmdutil.makewalker(repo, wopts)
3685 revs, makefilematcher = logcmdutil.makewalker(repo, wopts)
3686
3686
3687 ui.pager(b'grep')
3687 ui.pager(b'grep')
3688 fm = ui.formatter(b'grep', pycompat.byteskwargs(opts))
3688 fm = ui.formatter(b'grep', pycompat.byteskwargs(opts))
3689 for fn, ctx, pstates, states in searcher.searchfiles(revs, makefilematcher):
3689 for fn, ctx, pstates, states in searcher.searchfiles(revs, makefilematcher):
3690 r = display(fm, fn, ctx, pstates, states)
3690 r = display(fm, fn, ctx, pstates, states)
3691 found = found or r
3691 found = found or r
3692 if r and not diff and not all_files:
3692 if r and not diff and not all_files:
3693 searcher.skipfile(fn, ctx.rev())
3693 searcher.skipfile(fn, ctx.rev())
3694 fm.end()
3694 fm.end()
3695
3695
3696 return not found
3696 return not found
3697
3697
3698
3698
3699 @command(
3699 @command(
3700 b'heads',
3700 b'heads',
3701 [
3701 [
3702 (
3702 (
3703 b'r',
3703 b'r',
3704 b'rev',
3704 b'rev',
3705 b'',
3705 b'',
3706 _(b'show only heads which are descendants of STARTREV'),
3706 _(b'show only heads which are descendants of STARTREV'),
3707 _(b'STARTREV'),
3707 _(b'STARTREV'),
3708 ),
3708 ),
3709 (b't', b'topo', False, _(b'show topological heads only')),
3709 (b't', b'topo', False, _(b'show topological heads only')),
3710 (
3710 (
3711 b'a',
3711 b'a',
3712 b'active',
3712 b'active',
3713 False,
3713 False,
3714 _(b'show active branchheads only (DEPRECATED)'),
3714 _(b'show active branchheads only (DEPRECATED)'),
3715 ),
3715 ),
3716 (b'c', b'closed', False, _(b'show normal and closed branch heads')),
3716 (b'c', b'closed', False, _(b'show normal and closed branch heads')),
3717 ]
3717 ]
3718 + templateopts,
3718 + templateopts,
3719 _(b'[-ct] [-r STARTREV] [REV]...'),
3719 _(b'[-ct] [-r STARTREV] [REV]...'),
3720 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3720 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3721 intents={INTENT_READONLY},
3721 intents={INTENT_READONLY},
3722 )
3722 )
3723 def heads(ui, repo, *branchrevs, **opts):
3723 def heads(ui, repo, *branchrevs, **opts):
3724 """show branch heads
3724 """show branch heads
3725
3725
3726 With no arguments, show all open branch heads in the repository.
3726 With no arguments, show all open branch heads in the repository.
3727 Branch heads are changesets that have no descendants on the
3727 Branch heads are changesets that have no descendants on the
3728 same branch. They are where development generally takes place and
3728 same branch. They are where development generally takes place and
3729 are the usual targets for update and merge operations.
3729 are the usual targets for update and merge operations.
3730
3730
3731 If one or more REVs are given, only open branch heads on the
3731 If one or more REVs are given, only open branch heads on the
3732 branches associated with the specified changesets are shown. This
3732 branches associated with the specified changesets are shown. This
3733 means that you can use :hg:`heads .` to see the heads on the
3733 means that you can use :hg:`heads .` to see the heads on the
3734 currently checked-out branch.
3734 currently checked-out branch.
3735
3735
3736 If -c/--closed is specified, also show branch heads marked closed
3736 If -c/--closed is specified, also show branch heads marked closed
3737 (see :hg:`commit --close-branch`).
3737 (see :hg:`commit --close-branch`).
3738
3738
3739 If STARTREV is specified, only those heads that are descendants of
3739 If STARTREV is specified, only those heads that are descendants of
3740 STARTREV will be displayed.
3740 STARTREV will be displayed.
3741
3741
3742 If -t/--topo is specified, named branch mechanics will be ignored and only
3742 If -t/--topo is specified, named branch mechanics will be ignored and only
3743 topological heads (changesets with no children) will be shown.
3743 topological heads (changesets with no children) will be shown.
3744
3744
3745 Returns 0 if matching heads are found, 1 if not.
3745 Returns 0 if matching heads are found, 1 if not.
3746 """
3746 """
3747
3747
3748 start = None
3748 start = None
3749 rev = opts.get('rev')
3749 rev = opts.get('rev')
3750 if rev:
3750 if rev:
3751 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3751 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3752 start = logcmdutil.revsingle(repo, rev, None).node()
3752 start = logcmdutil.revsingle(repo, rev, None).node()
3753
3753
3754 if opts.get('topo'):
3754 if opts.get('topo'):
3755 heads = [repo[h] for h in repo.heads(start)]
3755 heads = [repo[h] for h in repo.heads(start)]
3756 else:
3756 else:
3757 heads = []
3757 heads = []
3758 for branch in repo.branchmap():
3758 for branch in repo.branchmap():
3759 heads += repo.branchheads(branch, start, opts.get('closed'))
3759 heads += repo.branchheads(branch, start, opts.get('closed'))
3760 heads = [repo[h] for h in heads]
3760 heads = [repo[h] for h in heads]
3761
3761
3762 if branchrevs:
3762 if branchrevs:
3763 branches = {
3763 branches = {
3764 repo[r].branch() for r in logcmdutil.revrange(repo, branchrevs)
3764 repo[r].branch() for r in logcmdutil.revrange(repo, branchrevs)
3765 }
3765 }
3766 heads = [h for h in heads if h.branch() in branches]
3766 heads = [h for h in heads if h.branch() in branches]
3767
3767
3768 if opts.get('active') and branchrevs:
3768 if opts.get('active') and branchrevs:
3769 dagheads = repo.heads(start)
3769 dagheads = repo.heads(start)
3770 heads = [h for h in heads if h.node() in dagheads]
3770 heads = [h for h in heads if h.node() in dagheads]
3771
3771
3772 if branchrevs:
3772 if branchrevs:
3773 haveheads = {h.branch() for h in heads}
3773 haveheads = {h.branch() for h in heads}
3774 if branches - haveheads:
3774 if branches - haveheads:
3775 headless = b', '.join(b for b in branches - haveheads)
3775 headless = b', '.join(b for b in branches - haveheads)
3776 msg = _(b'no open branch heads found on branches %s')
3776 msg = _(b'no open branch heads found on branches %s')
3777 if opts.get('rev'):
3777 if opts.get('rev'):
3778 msg += _(b' (started at %s)') % opts['rev']
3778 msg += _(b' (started at %s)') % opts['rev']
3779 ui.warn((msg + b'\n') % headless)
3779 ui.warn((msg + b'\n') % headless)
3780
3780
3781 if not heads:
3781 if not heads:
3782 return 1
3782 return 1
3783
3783
3784 ui.pager(b'heads')
3784 ui.pager(b'heads')
3785 heads = sorted(heads, key=lambda x: -(x.rev()))
3785 heads = sorted(heads, key=lambda x: -(x.rev()))
3786 displayer = logcmdutil.changesetdisplayer(
3786 displayer = logcmdutil.changesetdisplayer(
3787 ui, repo, pycompat.byteskwargs(opts)
3787 ui, repo, pycompat.byteskwargs(opts)
3788 )
3788 )
3789 for ctx in heads:
3789 for ctx in heads:
3790 displayer.show(ctx)
3790 displayer.show(ctx)
3791 displayer.close()
3791 displayer.close()
3792
3792
3793
3793
3794 @command(
3794 @command(
3795 b'help',
3795 b'help',
3796 [
3796 [
3797 (b'e', b'extension', None, _(b'show only help for extensions')),
3797 (b'e', b'extension', None, _(b'show only help for extensions')),
3798 (b'c', b'command', None, _(b'show only help for commands')),
3798 (b'c', b'command', None, _(b'show only help for commands')),
3799 (b'k', b'keyword', None, _(b'show topics matching keyword')),
3799 (b'k', b'keyword', None, _(b'show topics matching keyword')),
3800 (
3800 (
3801 b's',
3801 b's',
3802 b'system',
3802 b'system',
3803 [],
3803 [],
3804 _(b'show help for specific platform(s)'),
3804 _(b'show help for specific platform(s)'),
3805 _(b'PLATFORM'),
3805 _(b'PLATFORM'),
3806 ),
3806 ),
3807 ],
3807 ],
3808 _(b'[-eck] [-s PLATFORM] [TOPIC]'),
3808 _(b'[-eck] [-s PLATFORM] [TOPIC]'),
3809 helpcategory=command.CATEGORY_HELP,
3809 helpcategory=command.CATEGORY_HELP,
3810 norepo=True,
3810 norepo=True,
3811 intents={INTENT_READONLY},
3811 intents={INTENT_READONLY},
3812 )
3812 )
3813 def help_(ui, name=None, **opts):
3813 def help_(ui, name=None, **opts):
3814 """show help for a given topic or a help overview
3814 """show help for a given topic or a help overview
3815
3815
3816 With no arguments, print a list of commands with short help messages.
3816 With no arguments, print a list of commands with short help messages.
3817
3817
3818 Given a topic, extension, or command name, print help for that
3818 Given a topic, extension, or command name, print help for that
3819 topic.
3819 topic.
3820
3820
3821 Returns 0 if successful.
3821 Returns 0 if successful.
3822 """
3822 """
3823
3823
3824 keep = opts.get('system') or []
3824 keep = opts.get('system') or []
3825 if len(keep) == 0:
3825 if len(keep) == 0:
3826 if pycompat.sysplatform.startswith(b'win'):
3826 if pycompat.sysplatform.startswith(b'win'):
3827 keep.append(b'windows')
3827 keep.append(b'windows')
3828 elif pycompat.sysplatform == b'OpenVMS':
3828 elif pycompat.sysplatform == b'OpenVMS':
3829 keep.append(b'vms')
3829 keep.append(b'vms')
3830 elif pycompat.sysplatform == b'plan9':
3830 elif pycompat.sysplatform == b'plan9':
3831 keep.append(b'plan9')
3831 keep.append(b'plan9')
3832 else:
3832 else:
3833 keep.append(b'unix')
3833 keep.append(b'unix')
3834 keep.append(pycompat.sysplatform.lower())
3834 keep.append(pycompat.sysplatform.lower())
3835 if ui.verbose:
3835 if ui.verbose:
3836 keep.append(b'verbose')
3836 keep.append(b'verbose')
3837
3837
3838 commands = sys.modules[__name__]
3838 commands = sys.modules[__name__]
3839 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3839 formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
3840 ui.pager(b'help')
3840 ui.pager(b'help')
3841 ui.write(formatted)
3841 ui.write(formatted)
3842
3842
3843
3843
3844 @command(
3844 @command(
3845 b'identify|id',
3845 b'identify|id',
3846 [
3846 [
3847 (b'r', b'rev', b'', _(b'identify the specified revision'), _(b'REV')),
3847 (b'r', b'rev', b'', _(b'identify the specified revision'), _(b'REV')),
3848 (b'n', b'num', None, _(b'show local revision number')),
3848 (b'n', b'num', None, _(b'show local revision number')),
3849 (b'i', b'id', None, _(b'show global revision id')),
3849 (b'i', b'id', None, _(b'show global revision id')),
3850 (b'b', b'branch', None, _(b'show branch')),
3850 (b'b', b'branch', None, _(b'show branch')),
3851 (b't', b'tags', None, _(b'show tags')),
3851 (b't', b'tags', None, _(b'show tags')),
3852 (b'B', b'bookmarks', None, _(b'show bookmarks')),
3852 (b'B', b'bookmarks', None, _(b'show bookmarks')),
3853 ]
3853 ]
3854 + remoteopts
3854 + remoteopts
3855 + formatteropts,
3855 + formatteropts,
3856 _(b'[-nibtB] [-r REV] [SOURCE]'),
3856 _(b'[-nibtB] [-r REV] [SOURCE]'),
3857 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3857 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
3858 optionalrepo=True,
3858 optionalrepo=True,
3859 intents={INTENT_READONLY},
3859 intents={INTENT_READONLY},
3860 )
3860 )
3861 def identify(
3861 def identify(
3862 ui,
3862 ui,
3863 repo,
3863 repo,
3864 source=None,
3864 source=None,
3865 rev=None,
3865 rev=None,
3866 num=None,
3866 num=None,
3867 id=None,
3867 id=None,
3868 branch=None,
3868 branch=None,
3869 tags=None,
3869 tags=None,
3870 bookmarks=None,
3870 bookmarks=None,
3871 **opts
3871 **opts
3872 ):
3872 ):
3873 """identify the working directory or specified revision
3873 """identify the working directory or specified revision
3874
3874
3875 Print a summary identifying the repository state at REV using one or
3875 Print a summary identifying the repository state at REV using one or
3876 two parent hash identifiers, followed by a "+" if the working
3876 two parent hash identifiers, followed by a "+" if the working
3877 directory has uncommitted changes, the branch name (if not default),
3877 directory has uncommitted changes, the branch name (if not default),
3878 a list of tags, and a list of bookmarks.
3878 a list of tags, and a list of bookmarks.
3879
3879
3880 When REV is not given, print a summary of the current state of the
3880 When REV is not given, print a summary of the current state of the
3881 repository including the working directory. Specify -r. to get information
3881 repository including the working directory. Specify -r. to get information
3882 of the working directory parent without scanning uncommitted changes.
3882 of the working directory parent without scanning uncommitted changes.
3883
3883
3884 Specifying a path to a repository root or Mercurial bundle will
3884 Specifying a path to a repository root or Mercurial bundle will
3885 cause lookup to operate on that repository/bundle.
3885 cause lookup to operate on that repository/bundle.
3886
3886
3887 .. container:: verbose
3887 .. container:: verbose
3888
3888
3889 Template:
3889 Template:
3890
3890
3891 The following keywords are supported in addition to the common template
3891 The following keywords are supported in addition to the common template
3892 keywords and functions. See also :hg:`help templates`.
3892 keywords and functions. See also :hg:`help templates`.
3893
3893
3894 :dirty: String. Character ``+`` denoting if the working directory has
3894 :dirty: String. Character ``+`` denoting if the working directory has
3895 uncommitted changes.
3895 uncommitted changes.
3896 :id: String. One or two nodes, optionally followed by ``+``.
3896 :id: String. One or two nodes, optionally followed by ``+``.
3897 :parents: List of strings. Parent nodes of the changeset.
3897 :parents: List of strings. Parent nodes of the changeset.
3898
3898
3899 Examples:
3899 Examples:
3900
3900
3901 - generate a build identifier for the working directory::
3901 - generate a build identifier for the working directory::
3902
3902
3903 hg id --id > build-id.dat
3903 hg id --id > build-id.dat
3904
3904
3905 - find the revision corresponding to a tag::
3905 - find the revision corresponding to a tag::
3906
3906
3907 hg id -n -r 1.3
3907 hg id -n -r 1.3
3908
3908
3909 - check the most recent revision of a remote repository::
3909 - check the most recent revision of a remote repository::
3910
3910
3911 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3911 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3912
3912
3913 See :hg:`log` for generating more information about specific revisions,
3913 See :hg:`log` for generating more information about specific revisions,
3914 including full hash identifiers.
3914 including full hash identifiers.
3915
3915
3916 Returns 0 if successful.
3916 Returns 0 if successful.
3917 """
3917 """
3918
3918
3919 opts = pycompat.byteskwargs(opts)
3919 opts = pycompat.byteskwargs(opts)
3920 if not repo and not source:
3920 if not repo and not source:
3921 raise error.InputError(
3921 raise error.InputError(
3922 _(b"there is no Mercurial repository here (.hg not found)")
3922 _(b"there is no Mercurial repository here (.hg not found)")
3923 )
3923 )
3924
3924
3925 default = not (num or id or branch or tags or bookmarks)
3925 default = not (num or id or branch or tags or bookmarks)
3926 output = []
3926 output = []
3927 revs = []
3927 revs = []
3928
3928
3929 peer = None
3929 peer = None
3930 try:
3930 try:
3931 if source:
3931 if source:
3932 path = urlutil.get_unique_pull_path_obj(b'identify', ui, source)
3932 path = urlutil.get_unique_pull_path_obj(b'identify', ui, source)
3933 # only pass ui when no repo
3933 # only pass ui when no repo
3934 peer = hg.peer(repo or ui, opts, path)
3934 peer = hg.peer(repo or ui, opts, path)
3935 repo = peer.local()
3935 repo = peer.local()
3936 branches = (path.branch, [])
3936 branches = (path.branch, [])
3937 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3937 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3938
3938
3939 fm = ui.formatter(b'identify', opts)
3939 fm = ui.formatter(b'identify', opts)
3940 fm.startitem()
3940 fm.startitem()
3941
3941
3942 if not repo:
3942 if not repo:
3943 if num or branch or tags:
3943 if num or branch or tags:
3944 raise error.InputError(
3944 raise error.InputError(
3945 _(b"can't query remote revision number, branch, or tags")
3945 _(b"can't query remote revision number, branch, or tags")
3946 )
3946 )
3947 if not rev and revs:
3947 if not rev and revs:
3948 rev = revs[0]
3948 rev = revs[0]
3949 if not rev:
3949 if not rev:
3950 rev = b"tip"
3950 rev = b"tip"
3951
3951
3952 remoterev = peer.lookup(rev)
3952 remoterev = peer.lookup(rev)
3953 hexrev = fm.hexfunc(remoterev)
3953 hexrev = fm.hexfunc(remoterev)
3954 if default or id:
3954 if default or id:
3955 output = [hexrev]
3955 output = [hexrev]
3956 fm.data(id=hexrev)
3956 fm.data(id=hexrev)
3957
3957
3958 @util.cachefunc
3958 @util.cachefunc
3959 def getbms():
3959 def getbms():
3960 bms = []
3960 bms = []
3961
3961
3962 if b'bookmarks' in peer.listkeys(b'namespaces'):
3962 if b'bookmarks' in peer.listkeys(b'namespaces'):
3963 hexremoterev = hex(remoterev)
3963 hexremoterev = hex(remoterev)
3964 bms = [
3964 bms = [
3965 bm
3965 bm
3966 for bm, bmr in peer.listkeys(b'bookmarks').items()
3966 for bm, bmr in peer.listkeys(b'bookmarks').items()
3967 if bmr == hexremoterev
3967 if bmr == hexremoterev
3968 ]
3968 ]
3969
3969
3970 return sorted(bms)
3970 return sorted(bms)
3971
3971
3972 if fm.isplain():
3972 if fm.isplain():
3973 if bookmarks:
3973 if bookmarks:
3974 output.extend(getbms())
3974 output.extend(getbms())
3975 elif default and not ui.quiet:
3975 elif default and not ui.quiet:
3976 # multiple bookmarks for a single parent separated by '/'
3976 # multiple bookmarks for a single parent separated by '/'
3977 bm = b'/'.join(getbms())
3977 bm = b'/'.join(getbms())
3978 if bm:
3978 if bm:
3979 output.append(bm)
3979 output.append(bm)
3980 else:
3980 else:
3981 fm.data(node=hex(remoterev))
3981 fm.data(node=hex(remoterev))
3982 if bookmarks or b'bookmarks' in fm.datahint():
3982 if bookmarks or b'bookmarks' in fm.datahint():
3983 fm.data(bookmarks=fm.formatlist(getbms(), name=b'bookmark'))
3983 fm.data(bookmarks=fm.formatlist(getbms(), name=b'bookmark'))
3984 else:
3984 else:
3985 if rev:
3985 if rev:
3986 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3986 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
3987 ctx = logcmdutil.revsingle(repo, rev, None)
3987 ctx = logcmdutil.revsingle(repo, rev, None)
3988
3988
3989 if ctx.rev() is None:
3989 if ctx.rev() is None:
3990 ctx = repo[None]
3990 ctx = repo[None]
3991 parents = ctx.parents()
3991 parents = ctx.parents()
3992 taglist = []
3992 taglist = []
3993 for p in parents:
3993 for p in parents:
3994 taglist.extend(p.tags())
3994 taglist.extend(p.tags())
3995
3995
3996 dirty = b""
3996 dirty = b""
3997 if ctx.dirty(missing=True, merge=False, branch=False):
3997 if ctx.dirty(missing=True, merge=False, branch=False):
3998 dirty = b'+'
3998 dirty = b'+'
3999 fm.data(dirty=dirty)
3999 fm.data(dirty=dirty)
4000
4000
4001 hexoutput = [fm.hexfunc(p.node()) for p in parents]
4001 hexoutput = [fm.hexfunc(p.node()) for p in parents]
4002 if default or id:
4002 if default or id:
4003 output = [b"%s%s" % (b'+'.join(hexoutput), dirty)]
4003 output = [b"%s%s" % (b'+'.join(hexoutput), dirty)]
4004 fm.data(id=b"%s%s" % (b'+'.join(hexoutput), dirty))
4004 fm.data(id=b"%s%s" % (b'+'.join(hexoutput), dirty))
4005
4005
4006 if num:
4006 if num:
4007 numoutput = [b"%d" % p.rev() for p in parents]
4007 numoutput = [b"%d" % p.rev() for p in parents]
4008 output.append(b"%s%s" % (b'+'.join(numoutput), dirty))
4008 output.append(b"%s%s" % (b'+'.join(numoutput), dirty))
4009
4009
4010 fm.data(
4010 fm.data(
4011 parents=fm.formatlist(
4011 parents=fm.formatlist(
4012 [fm.hexfunc(p.node()) for p in parents], name=b'node'
4012 [fm.hexfunc(p.node()) for p in parents], name=b'node'
4013 )
4013 )
4014 )
4014 )
4015 else:
4015 else:
4016 hexoutput = fm.hexfunc(ctx.node())
4016 hexoutput = fm.hexfunc(ctx.node())
4017 if default or id:
4017 if default or id:
4018 output = [hexoutput]
4018 output = [hexoutput]
4019 fm.data(id=hexoutput)
4019 fm.data(id=hexoutput)
4020
4020
4021 if num:
4021 if num:
4022 output.append(pycompat.bytestr(ctx.rev()))
4022 output.append(pycompat.bytestr(ctx.rev()))
4023 taglist = ctx.tags()
4023 taglist = ctx.tags()
4024
4024
4025 if default and not ui.quiet:
4025 if default and not ui.quiet:
4026 b = ctx.branch()
4026 b = ctx.branch()
4027 if b != b'default':
4027 if b != b'default':
4028 output.append(b"(%s)" % b)
4028 output.append(b"(%s)" % b)
4029
4029
4030 # multiple tags for a single parent separated by '/'
4030 # multiple tags for a single parent separated by '/'
4031 t = b'/'.join(taglist)
4031 t = b'/'.join(taglist)
4032 if t:
4032 if t:
4033 output.append(t)
4033 output.append(t)
4034
4034
4035 # multiple bookmarks for a single parent separated by '/'
4035 # multiple bookmarks for a single parent separated by '/'
4036 bm = b'/'.join(ctx.bookmarks())
4036 bm = b'/'.join(ctx.bookmarks())
4037 if bm:
4037 if bm:
4038 output.append(bm)
4038 output.append(bm)
4039 else:
4039 else:
4040 if branch:
4040 if branch:
4041 output.append(ctx.branch())
4041 output.append(ctx.branch())
4042
4042
4043 if tags:
4043 if tags:
4044 output.extend(taglist)
4044 output.extend(taglist)
4045
4045
4046 if bookmarks:
4046 if bookmarks:
4047 output.extend(ctx.bookmarks())
4047 output.extend(ctx.bookmarks())
4048
4048
4049 fm.data(node=ctx.hex())
4049 fm.data(node=ctx.hex())
4050 fm.data(branch=ctx.branch())
4050 fm.data(branch=ctx.branch())
4051 fm.data(tags=fm.formatlist(taglist, name=b'tag', sep=b':'))
4051 fm.data(tags=fm.formatlist(taglist, name=b'tag', sep=b':'))
4052 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name=b'bookmark'))
4052 fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name=b'bookmark'))
4053 fm.context(ctx=ctx)
4053 fm.context(ctx=ctx)
4054
4054
4055 fm.plain(b"%s\n" % b' '.join(output))
4055 fm.plain(b"%s\n" % b' '.join(output))
4056 fm.end()
4056 fm.end()
4057 finally:
4057 finally:
4058 if peer:
4058 if peer:
4059 peer.close()
4059 peer.close()
4060
4060
4061
4061
4062 @command(
4062 @command(
4063 b'import|patch',
4063 b'import|patch',
4064 [
4064 [
4065 (
4065 (
4066 b'p',
4066 b'p',
4067 b'strip',
4067 b'strip',
4068 1,
4068 1,
4069 _(
4069 _(
4070 b'directory strip option for patch. This has the same '
4070 b'directory strip option for patch. This has the same '
4071 b'meaning as the corresponding patch option'
4071 b'meaning as the corresponding patch option'
4072 ),
4072 ),
4073 _(b'NUM'),
4073 _(b'NUM'),
4074 ),
4074 ),
4075 (b'b', b'base', b'', _(b'base path (DEPRECATED)'), _(b'PATH')),
4075 (b'b', b'base', b'', _(b'base path (DEPRECATED)'), _(b'PATH')),
4076 (b'', b'secret', None, _(b'use the secret phase for committing')),
4076 (b'', b'secret', None, _(b'use the secret phase for committing')),
4077 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
4077 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
4078 (
4078 (
4079 b'f',
4079 b'f',
4080 b'force',
4080 b'force',
4081 None,
4081 None,
4082 _(b'skip check for outstanding uncommitted changes (DEPRECATED)'),
4082 _(b'skip check for outstanding uncommitted changes (DEPRECATED)'),
4083 ),
4083 ),
4084 (
4084 (
4085 b'',
4085 b'',
4086 b'no-commit',
4086 b'no-commit',
4087 None,
4087 None,
4088 _(b"don't commit, just update the working directory"),
4088 _(b"don't commit, just update the working directory"),
4089 ),
4089 ),
4090 (
4090 (
4091 b'',
4091 b'',
4092 b'bypass',
4092 b'bypass',
4093 None,
4093 None,
4094 _(b"apply patch without touching the working directory"),
4094 _(b"apply patch without touching the working directory"),
4095 ),
4095 ),
4096 (b'', b'partial', None, _(b'commit even if some hunks fail')),
4096 (b'', b'partial', None, _(b'commit even if some hunks fail')),
4097 (b'', b'exact', None, _(b'abort if patch would apply lossily')),
4097 (b'', b'exact', None, _(b'abort if patch would apply lossily')),
4098 (b'', b'prefix', b'', _(b'apply patch to subdirectory'), _(b'DIR')),
4098 (b'', b'prefix', b'', _(b'apply patch to subdirectory'), _(b'DIR')),
4099 (
4099 (
4100 b'',
4100 b'',
4101 b'import-branch',
4101 b'import-branch',
4102 None,
4102 None,
4103 _(b'use any branch information in patch (implied by --exact)'),
4103 _(b'use any branch information in patch (implied by --exact)'),
4104 ),
4104 ),
4105 ]
4105 ]
4106 + commitopts
4106 + commitopts
4107 + commitopts2
4107 + commitopts2
4108 + similarityopts,
4108 + similarityopts,
4109 _(b'[OPTION]... PATCH...'),
4109 _(b'[OPTION]... PATCH...'),
4110 helpcategory=command.CATEGORY_IMPORT_EXPORT,
4110 helpcategory=command.CATEGORY_IMPORT_EXPORT,
4111 )
4111 )
4112 def import_(ui, repo, patch1=None, *patches, **opts):
4112 def import_(ui, repo, patch1=None, *patches, **opts):
4113 """import an ordered set of patches
4113 """import an ordered set of patches
4114
4114
4115 Import a list of patches and commit them individually (unless
4115 Import a list of patches and commit them individually (unless
4116 --no-commit is specified).
4116 --no-commit is specified).
4117
4117
4118 To read a patch from standard input (stdin), use "-" as the patch
4118 To read a patch from standard input (stdin), use "-" as the patch
4119 name. If a URL is specified, the patch will be downloaded from
4119 name. If a URL is specified, the patch will be downloaded from
4120 there.
4120 there.
4121
4121
4122 Import first applies changes to the working directory (unless
4122 Import first applies changes to the working directory (unless
4123 --bypass is specified), import will abort if there are outstanding
4123 --bypass is specified), import will abort if there are outstanding
4124 changes.
4124 changes.
4125
4125
4126 Use --bypass to apply and commit patches directly to the
4126 Use --bypass to apply and commit patches directly to the
4127 repository, without affecting the working directory. Without
4127 repository, without affecting the working directory. Without
4128 --exact, patches will be applied on top of the working directory
4128 --exact, patches will be applied on top of the working directory
4129 parent revision.
4129 parent revision.
4130
4130
4131 You can import a patch straight from a mail message. Even patches
4131 You can import a patch straight from a mail message. Even patches
4132 as attachments work (to use the body part, it must have type
4132 as attachments work (to use the body part, it must have type
4133 text/plain or text/x-patch). From and Subject headers of email
4133 text/plain or text/x-patch). From and Subject headers of email
4134 message are used as default committer and commit message. All
4134 message are used as default committer and commit message. All
4135 text/plain body parts before first diff are added to the commit
4135 text/plain body parts before first diff are added to the commit
4136 message.
4136 message.
4137
4137
4138 If the imported patch was generated by :hg:`export`, user and
4138 If the imported patch was generated by :hg:`export`, user and
4139 description from patch override values from message headers and
4139 description from patch override values from message headers and
4140 body. Values given on command line with -m/--message and -u/--user
4140 body. Values given on command line with -m/--message and -u/--user
4141 override these.
4141 override these.
4142
4142
4143 If --exact is specified, import will set the working directory to
4143 If --exact is specified, import will set the working directory to
4144 the parent of each patch before applying it, and will abort if the
4144 the parent of each patch before applying it, and will abort if the
4145 resulting changeset has a different ID than the one recorded in
4145 resulting changeset has a different ID than the one recorded in
4146 the patch. This will guard against various ways that portable
4146 the patch. This will guard against various ways that portable
4147 patch formats and mail systems might fail to transfer Mercurial
4147 patch formats and mail systems might fail to transfer Mercurial
4148 data or metadata. See :hg:`bundle` for lossless transmission.
4148 data or metadata. See :hg:`bundle` for lossless transmission.
4149
4149
4150 Use --partial to ensure a changeset will be created from the patch
4150 Use --partial to ensure a changeset will be created from the patch
4151 even if some hunks fail to apply. Hunks that fail to apply will be
4151 even if some hunks fail to apply. Hunks that fail to apply will be
4152 written to a <target-file>.rej file. Conflicts can then be resolved
4152 written to a <target-file>.rej file. Conflicts can then be resolved
4153 by hand before :hg:`commit --amend` is run to update the created
4153 by hand before :hg:`commit --amend` is run to update the created
4154 changeset. This flag exists to let people import patches that
4154 changeset. This flag exists to let people import patches that
4155 partially apply without losing the associated metadata (author,
4155 partially apply without losing the associated metadata (author,
4156 date, description, ...).
4156 date, description, ...).
4157
4157
4158 .. note::
4158 .. note::
4159
4159
4160 When no hunks apply cleanly, :hg:`import --partial` will create
4160 When no hunks apply cleanly, :hg:`import --partial` will create
4161 an empty changeset, importing only the patch metadata.
4161 an empty changeset, importing only the patch metadata.
4162
4162
4163 With -s/--similarity, hg will attempt to discover renames and
4163 With -s/--similarity, hg will attempt to discover renames and
4164 copies in the patch in the same way as :hg:`addremove`.
4164 copies in the patch in the same way as :hg:`addremove`.
4165
4165
4166 It is possible to use external patch programs to perform the patch
4166 It is possible to use external patch programs to perform the patch
4167 by setting the ``ui.patch`` configuration option. For the default
4167 by setting the ``ui.patch`` configuration option. For the default
4168 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4168 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4169 See :hg:`help config` for more information about configuration
4169 See :hg:`help config` for more information about configuration
4170 files and how to use these options.
4170 files and how to use these options.
4171
4171
4172 See :hg:`help dates` for a list of formats valid for -d/--date.
4172 See :hg:`help dates` for a list of formats valid for -d/--date.
4173
4173
4174 .. container:: verbose
4174 .. container:: verbose
4175
4175
4176 Examples:
4176 Examples:
4177
4177
4178 - import a traditional patch from a website and detect renames::
4178 - import a traditional patch from a website and detect renames::
4179
4179
4180 hg import -s 80 http://example.com/bugfix.patch
4180 hg import -s 80 http://example.com/bugfix.patch
4181
4181
4182 - import a changeset from an hgweb server::
4182 - import a changeset from an hgweb server::
4183
4183
4184 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
4184 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
4185
4185
4186 - import all the patches in an Unix-style mbox::
4186 - import all the patches in an Unix-style mbox::
4187
4187
4188 hg import incoming-patches.mbox
4188 hg import incoming-patches.mbox
4189
4189
4190 - import patches from stdin::
4190 - import patches from stdin::
4191
4191
4192 hg import -
4192 hg import -
4193
4193
4194 - attempt to exactly restore an exported changeset (not always
4194 - attempt to exactly restore an exported changeset (not always
4195 possible)::
4195 possible)::
4196
4196
4197 hg import --exact proposed-fix.patch
4197 hg import --exact proposed-fix.patch
4198
4198
4199 - use an external tool to apply a patch which is too fuzzy for
4199 - use an external tool to apply a patch which is too fuzzy for
4200 the default internal tool.
4200 the default internal tool.
4201
4201
4202 hg import --config ui.patch="patch --merge" fuzzy.patch
4202 hg import --config ui.patch="patch --merge" fuzzy.patch
4203
4203
4204 - change the default fuzzing from 2 to a less strict 7
4204 - change the default fuzzing from 2 to a less strict 7
4205
4205
4206 hg import --config ui.fuzz=7 fuzz.patch
4206 hg import --config ui.fuzz=7 fuzz.patch
4207
4207
4208 Returns 0 on success, 1 on partial success (see --partial).
4208 Returns 0 on success, 1 on partial success (see --partial).
4209 """
4209 """
4210
4210
4211 cmdutil.check_incompatible_arguments(
4211 cmdutil.check_incompatible_arguments(
4212 opts, 'no_commit', ['bypass', 'secret']
4212 opts, 'no_commit', ['bypass', 'secret']
4213 )
4213 )
4214 cmdutil.check_incompatible_arguments(opts, 'exact', ['edit', 'prefix'])
4214 cmdutil.check_incompatible_arguments(opts, 'exact', ['edit', 'prefix'])
4215
4215
4216 if not patch1:
4216 if not patch1:
4217 raise error.InputError(_(b'need at least one patch to import'))
4217 raise error.InputError(_(b'need at least one patch to import'))
4218
4218
4219 patches = (patch1,) + patches
4219 patches = (patch1,) + patches
4220
4220
4221 date = opts.get('date')
4221 date = opts.get('date')
4222 if date:
4222 if date:
4223 opts['date'] = dateutil.parsedate(date)
4223 opts['date'] = dateutil.parsedate(date)
4224
4224
4225 exact = opts.get('exact')
4225 exact = opts.get('exact')
4226 update = not opts.get('bypass')
4226 update = not opts.get('bypass')
4227 try:
4227 try:
4228 sim = float(opts.get('similarity') or 0)
4228 sim = float(opts.get('similarity') or 0)
4229 except ValueError:
4229 except ValueError:
4230 raise error.InputError(_(b'similarity must be a number'))
4230 raise error.InputError(_(b'similarity must be a number'))
4231 if sim < 0 or sim > 100:
4231 if sim < 0 or sim > 100:
4232 raise error.InputError(_(b'similarity must be between 0 and 100'))
4232 raise error.InputError(_(b'similarity must be between 0 and 100'))
4233 if sim and not update:
4233 if sim and not update:
4234 raise error.InputError(_(b'cannot use --similarity with --bypass'))
4234 raise error.InputError(_(b'cannot use --similarity with --bypass'))
4235
4235
4236 base = opts["base"]
4236 base = opts["base"]
4237 msgs = []
4237 msgs = []
4238 ret = 0
4238 ret = 0
4239
4239
4240 with repo.wlock():
4240 with repo.wlock():
4241 if update:
4241 if update:
4242 cmdutil.checkunfinished(repo)
4242 cmdutil.checkunfinished(repo)
4243 if exact or not opts.get('force'):
4243 if exact or not opts.get('force'):
4244 cmdutil.bailifchanged(repo)
4244 cmdutil.bailifchanged(repo)
4245
4245
4246 if not opts.get('no_commit'):
4246 if not opts.get('no_commit'):
4247 lock = repo.lock
4247 lock = repo.lock
4248 tr = lambda: repo.transaction(b'import')
4248 tr = lambda: repo.transaction(b'import')
4249 else:
4249 else:
4250 lock = util.nullcontextmanager
4250 lock = util.nullcontextmanager
4251 tr = util.nullcontextmanager
4251 tr = util.nullcontextmanager
4252 with lock(), tr():
4252 with lock(), tr():
4253 parents = repo[None].parents()
4253 parents = repo[None].parents()
4254 for patchurl in patches:
4254 for patchurl in patches:
4255 if patchurl == b'-':
4255 if patchurl == b'-':
4256 ui.status(_(b'applying patch from stdin\n'))
4256 ui.status(_(b'applying patch from stdin\n'))
4257 patchfile = ui.fin
4257 patchfile = ui.fin
4258 patchurl = b'stdin' # for error message
4258 patchurl = b'stdin' # for error message
4259 else:
4259 else:
4260 patchurl = os.path.join(base, patchurl)
4260 patchurl = os.path.join(base, patchurl)
4261 ui.status(_(b'applying %s\n') % patchurl)
4261 ui.status(_(b'applying %s\n') % patchurl)
4262 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
4262 patchfile = hg.openpath(ui, patchurl, sendaccept=False)
4263
4263
4264 haspatch = False
4264 haspatch = False
4265 for hunk in patch.split(patchfile):
4265 for hunk in patch.split(patchfile):
4266 with patch.extract(ui, hunk) as patchdata:
4266 with patch.extract(ui, hunk) as patchdata:
4267 msg, node, rej = cmdutil.tryimportone(
4267 msg, node, rej = cmdutil.tryimportone(
4268 ui,
4268 ui,
4269 repo,
4269 repo,
4270 patchdata,
4270 patchdata,
4271 parents,
4271 parents,
4272 pycompat.byteskwargs(opts),
4272 pycompat.byteskwargs(opts),
4273 msgs,
4273 msgs,
4274 hg.clean,
4274 hg.clean,
4275 )
4275 )
4276 if msg:
4276 if msg:
4277 haspatch = True
4277 haspatch = True
4278 ui.note(msg + b'\n')
4278 ui.note(msg + b'\n')
4279 if update or exact:
4279 if update or exact:
4280 parents = repo[None].parents()
4280 parents = repo[None].parents()
4281 else:
4281 else:
4282 parents = [repo[node]]
4282 parents = [repo[node]]
4283 if rej:
4283 if rej:
4284 ui.write_err(_(b"patch applied partially\n"))
4284 ui.write_err(_(b"patch applied partially\n"))
4285 ui.write_err(
4285 ui.write_err(
4286 _(
4286 _(
4287 b"(fix the .rej files and run "
4287 b"(fix the .rej files and run "
4288 b"`hg commit --amend`)\n"
4288 b"`hg commit --amend`)\n"
4289 )
4289 )
4290 )
4290 )
4291 ret = 1
4291 ret = 1
4292 break
4292 break
4293
4293
4294 if not haspatch:
4294 if not haspatch:
4295 raise error.InputError(_(b'%s: no diffs found') % patchurl)
4295 raise error.InputError(_(b'%s: no diffs found') % patchurl)
4296
4296
4297 if msgs:
4297 if msgs:
4298 repo.savecommitmessage(b'\n* * *\n'.join(msgs))
4298 repo.savecommitmessage(b'\n* * *\n'.join(msgs))
4299 return ret
4299 return ret
4300
4300
4301
4301
4302 @command(
4302 @command(
4303 b'incoming|in',
4303 b'incoming|in',
4304 [
4304 [
4305 (
4305 (
4306 b'f',
4306 b'f',
4307 b'force',
4307 b'force',
4308 None,
4308 None,
4309 _(b'run even if remote repository is unrelated'),
4309 _(b'run even if remote repository is unrelated'),
4310 ),
4310 ),
4311 (b'n', b'newest-first', None, _(b'show newest record first')),
4311 (b'n', b'newest-first', None, _(b'show newest record first')),
4312 (b'', b'bundle', b'', _(b'file to store the bundles into'), _(b'FILE')),
4312 (b'', b'bundle', b'', _(b'file to store the bundles into'), _(b'FILE')),
4313 (
4313 (
4314 b'r',
4314 b'r',
4315 b'rev',
4315 b'rev',
4316 [],
4316 [],
4317 _(b'a remote changeset intended to be added'),
4317 _(b'a remote changeset intended to be added'),
4318 _(b'REV'),
4318 _(b'REV'),
4319 ),
4319 ),
4320 (b'B', b'bookmarks', False, _(b"compare bookmarks")),
4320 (b'B', b'bookmarks', False, _(b"compare bookmarks")),
4321 (
4321 (
4322 b'b',
4322 b'b',
4323 b'branch',
4323 b'branch',
4324 [],
4324 [],
4325 _(b'a specific branch you would like to pull'),
4325 _(b'a specific branch you would like to pull'),
4326 _(b'BRANCH'),
4326 _(b'BRANCH'),
4327 ),
4327 ),
4328 ]
4328 ]
4329 + logopts
4329 + logopts
4330 + remoteopts
4330 + remoteopts
4331 + subrepoopts,
4331 + subrepoopts,
4332 _(b'[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
4332 _(b'[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
4333 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4333 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
4334 )
4334 )
4335 def incoming(ui, repo, source=b"default", **opts):
4335 def incoming(ui, repo, source=b"default", **opts):
4336 """show new changesets found in source
4336 """show new changesets found in source
4337
4337
4338 Show new changesets found in the specified path/URL or the default
4338 Show new changesets found in the specified path/URL or the default
4339 pull location. These are the changesets that would have been pulled
4339 pull location. These are the changesets that would have been pulled
4340 by :hg:`pull` at the time you issued this command.
4340 by :hg:`pull` at the time you issued this command.
4341
4341
4342 See pull for valid source format details.
4342 See pull for valid source format details.
4343
4343
4344 .. container:: verbose
4344 .. container:: verbose
4345
4345
4346 With -B/--bookmarks, the result of bookmark comparison between
4346 With -B/--bookmarks, the result of bookmark comparison between
4347 local and remote repositories is displayed. With -v/--verbose,
4347 local and remote repositories is displayed. With -v/--verbose,
4348 status is also displayed for each bookmark like below::
4348 status is also displayed for each bookmark like below::
4349
4349
4350 BM1 01234567890a added
4350 BM1 01234567890a added
4351 BM2 1234567890ab advanced
4351 BM2 1234567890ab advanced
4352 BM3 234567890abc diverged
4352 BM3 234567890abc diverged
4353 BM4 34567890abcd changed
4353 BM4 34567890abcd changed
4354
4354
4355 The action taken locally when pulling depends on the
4355 The action taken locally when pulling depends on the
4356 status of each bookmark:
4356 status of each bookmark:
4357
4357
4358 :``added``: pull will create it
4358 :``added``: pull will create it
4359 :``advanced``: pull will update it
4359 :``advanced``: pull will update it
4360 :``diverged``: pull will create a divergent bookmark
4360 :``diverged``: pull will create a divergent bookmark
4361 :``changed``: result depends on remote changesets
4361 :``changed``: result depends on remote changesets
4362
4362
4363 From the point of view of pulling behavior, bookmark
4363 From the point of view of pulling behavior, bookmark
4364 existing only in the remote repository are treated as ``added``,
4364 existing only in the remote repository are treated as ``added``,
4365 even if it is in fact locally deleted.
4365 even if it is in fact locally deleted.
4366
4366
4367 .. container:: verbose
4367 .. container:: verbose
4368
4368
4369 For remote repository, using --bundle avoids downloading the
4369 For remote repository, using --bundle avoids downloading the
4370 changesets twice if the incoming is followed by a pull.
4370 changesets twice if the incoming is followed by a pull.
4371
4371
4372 Examples:
4372 Examples:
4373
4373
4374 - show incoming changes with patches and full description::
4374 - show incoming changes with patches and full description::
4375
4375
4376 hg incoming -vp
4376 hg incoming -vp
4377
4377
4378 - show incoming changes excluding merges, store a bundle::
4378 - show incoming changes excluding merges, store a bundle::
4379
4379
4380 hg in -vpM --bundle incoming.hg
4380 hg in -vpM --bundle incoming.hg
4381 hg pull incoming.hg
4381 hg pull incoming.hg
4382
4382
4383 - briefly list changes inside a bundle::
4383 - briefly list changes inside a bundle::
4384
4384
4385 hg in changes.hg -T "{desc|firstline}\\n"
4385 hg in changes.hg -T "{desc|firstline}\\n"
4386
4386
4387 Returns 0 if there are incoming changes, 1 otherwise.
4387 Returns 0 if there are incoming changes, 1 otherwise.
4388 """
4388 """
4389 opts = pycompat.byteskwargs(opts)
4389 opts = pycompat.byteskwargs(opts)
4390 if opts.get(b'graph'):
4390 if opts.get(b'graph'):
4391 logcmdutil.checkunsupportedgraphflags([], opts)
4391 logcmdutil.checkunsupportedgraphflags([], opts)
4392
4392
4393 def display(other, chlist, displayer):
4393 def display(other, chlist, displayer):
4394 revdag = logcmdutil.graphrevs(other, chlist, opts)
4394 revdag = logcmdutil.graphrevs(other, chlist, opts)
4395 logcmdutil.displaygraph(
4395 logcmdutil.displaygraph(
4396 ui, repo, revdag, displayer, graphmod.asciiedges
4396 ui, repo, revdag, displayer, graphmod.asciiedges
4397 )
4397 )
4398
4398
4399 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4399 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4400 return 0
4400 return 0
4401
4401
4402 cmdutil.check_incompatible_arguments(opts, b'subrepos', [b'bundle'])
4402 cmdutil.check_incompatible_arguments(opts, b'subrepos', [b'bundle'])
4403
4403
4404 if opts.get(b'bookmarks'):
4404 if opts.get(b'bookmarks'):
4405 srcs = urlutil.get_pull_paths(repo, ui, [source])
4405 srcs = urlutil.get_pull_paths(repo, ui, [source])
4406 for path in srcs:
4406 for path in srcs:
4407 # XXX the "branches" options are not used. Should it be used?
4407 # XXX the "branches" options are not used. Should it be used?
4408 other = hg.peer(repo, opts, path)
4408 other = hg.peer(repo, opts, path)
4409 try:
4409 try:
4410 if b'bookmarks' not in other.listkeys(b'namespaces'):
4410 if b'bookmarks' not in other.listkeys(b'namespaces'):
4411 ui.warn(_(b"remote doesn't support bookmarks\n"))
4411 ui.warn(_(b"remote doesn't support bookmarks\n"))
4412 return 0
4412 return 0
4413 ui.pager(b'incoming')
4413 ui.pager(b'incoming')
4414 ui.status(
4414 ui.status(
4415 _(b'comparing with %s\n') % urlutil.hidepassword(path.loc)
4415 _(b'comparing with %s\n') % urlutil.hidepassword(path.loc)
4416 )
4416 )
4417 return bookmarks.incoming(
4417 return bookmarks.incoming(
4418 ui, repo, other, mode=path.bookmarks_mode
4418 ui, repo, other, mode=path.bookmarks_mode
4419 )
4419 )
4420 finally:
4420 finally:
4421 other.close()
4421 other.close()
4422
4422
4423 return hg.incoming(ui, repo, source, opts)
4423 return hg.incoming(ui, repo, source, opts)
4424
4424
4425
4425
4426 @command(
4426 @command(
4427 b'init',
4427 b'init',
4428 remoteopts,
4428 remoteopts,
4429 _(b'[-e CMD] [--remotecmd CMD] [DEST]'),
4429 _(b'[-e CMD] [--remotecmd CMD] [DEST]'),
4430 helpcategory=command.CATEGORY_REPO_CREATION,
4430 helpcategory=command.CATEGORY_REPO_CREATION,
4431 helpbasic=True,
4431 helpbasic=True,
4432 norepo=True,
4432 norepo=True,
4433 )
4433 )
4434 def init(ui, dest=b".", **opts):
4434 def init(ui, dest=b".", **opts):
4435 """create a new repository in the given directory
4435 """create a new repository in the given directory
4436
4436
4437 Initialize a new repository in the given directory. If the given
4437 Initialize a new repository in the given directory. If the given
4438 directory does not exist, it will be created.
4438 directory does not exist, it will be created.
4439
4439
4440 If no directory is given, the current directory is used.
4440 If no directory is given, the current directory is used.
4441
4441
4442 It is possible to specify an ``ssh://`` URL as the destination.
4442 It is possible to specify an ``ssh://`` URL as the destination.
4443 See :hg:`help urls` for more information.
4443 See :hg:`help urls` for more information.
4444
4444
4445 Returns 0 on success.
4445 Returns 0 on success.
4446 """
4446 """
4447 opts = pycompat.byteskwargs(opts)
4447 opts = pycompat.byteskwargs(opts)
4448 path = urlutil.get_clone_path_obj(ui, dest)
4448 path = urlutil.get_clone_path_obj(ui, dest)
4449 peer = hg.peer(ui, opts, path, create=True)
4449 peer = hg.peer(ui, opts, path, create=True)
4450 peer.close()
4450 peer.close()
4451
4451
4452
4452
4453 @command(
4453 @command(
4454 b'locate',
4454 b'locate',
4455 [
4455 [
4456 (
4456 (
4457 b'r',
4457 b'r',
4458 b'rev',
4458 b'rev',
4459 b'',
4459 b'',
4460 _(b'search the repository as it is in REV'),
4460 _(b'search the repository as it is in REV'),
4461 _(b'REV'),
4461 _(b'REV'),
4462 ),
4462 ),
4463 (
4463 (
4464 b'0',
4464 b'0',
4465 b'print0',
4465 b'print0',
4466 None,
4466 None,
4467 _(b'end filenames with NUL, for use with xargs'),
4467 _(b'end filenames with NUL, for use with xargs'),
4468 ),
4468 ),
4469 (
4469 (
4470 b'f',
4470 b'f',
4471 b'fullpath',
4471 b'fullpath',
4472 None,
4472 None,
4473 _(b'print complete paths from the filesystem root'),
4473 _(b'print complete paths from the filesystem root'),
4474 ),
4474 ),
4475 ]
4475 ]
4476 + walkopts,
4476 + walkopts,
4477 _(b'[OPTION]... [PATTERN]...'),
4477 _(b'[OPTION]... [PATTERN]...'),
4478 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4478 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
4479 )
4479 )
4480 def locate(ui, repo, *pats, **opts):
4480 def locate(ui, repo, *pats, **opts):
4481 """locate files matching specific patterns (DEPRECATED)
4481 """locate files matching specific patterns (DEPRECATED)
4482
4482
4483 Print files under Mercurial control in the working directory whose
4483 Print files under Mercurial control in the working directory whose
4484 names match the given patterns.
4484 names match the given patterns.
4485
4485
4486 By default, this command searches all directories in the working
4486 By default, this command searches all directories in the working
4487 directory. To search just the current directory and its
4487 directory. To search just the current directory and its
4488 subdirectories, use "--include .".
4488 subdirectories, use "--include .".
4489
4489
4490 If no patterns are given to match, this command prints the names
4490 If no patterns are given to match, this command prints the names
4491 of all files under Mercurial control in the working directory.
4491 of all files under Mercurial control in the working directory.
4492
4492
4493 If you want to feed the output of this command into the "xargs"
4493 If you want to feed the output of this command into the "xargs"
4494 command, use the -0 option to both this command and "xargs". This
4494 command, use the -0 option to both this command and "xargs". This
4495 will avoid the problem of "xargs" treating single filenames that
4495 will avoid the problem of "xargs" treating single filenames that
4496 contain whitespace as multiple filenames.
4496 contain whitespace as multiple filenames.
4497
4497
4498 See :hg:`help files` for a more versatile command.
4498 See :hg:`help files` for a more versatile command.
4499
4499
4500 Returns 0 if a match is found, 1 otherwise.
4500 Returns 0 if a match is found, 1 otherwise.
4501 """
4501 """
4502 if opts.get('print0'):
4502 if opts.get('print0'):
4503 end = b'\0'
4503 end = b'\0'
4504 else:
4504 else:
4505 end = b'\n'
4505 end = b'\n'
4506 ctx = logcmdutil.revsingle(repo, opts.get('rev'), None)
4506 ctx = logcmdutil.revsingle(repo, opts.get('rev'), None)
4507
4507
4508 ret = 1
4508 ret = 1
4509 m = scmutil.match(
4509 m = scmutil.match(
4510 ctx,
4510 ctx,
4511 pats,
4511 pats,
4512 pycompat.byteskwargs(opts),
4512 pycompat.byteskwargs(opts),
4513 default=b'relglob',
4513 default=b'relglob',
4514 badfn=lambda x, y: False,
4514 badfn=lambda x, y: False,
4515 )
4515 )
4516
4516
4517 ui.pager(b'locate')
4517 ui.pager(b'locate')
4518 if ctx.rev() is None:
4518 if ctx.rev() is None:
4519 # When run on the working copy, "locate" includes removed files, so
4519 # When run on the working copy, "locate" includes removed files, so
4520 # we get the list of files from the dirstate.
4520 # we get the list of files from the dirstate.
4521 filesgen = sorted(repo.dirstate.matches(m))
4521 filesgen = sorted(repo.dirstate.matches(m))
4522 else:
4522 else:
4523 filesgen = ctx.matches(m)
4523 filesgen = ctx.matches(m)
4524 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
4524 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
4525 for abs in filesgen:
4525 for abs in filesgen:
4526 if opts.get('fullpath'):
4526 if opts.get('fullpath'):
4527 ui.write(repo.wjoin(abs), end)
4527 ui.write(repo.wjoin(abs), end)
4528 else:
4528 else:
4529 ui.write(uipathfn(abs), end)
4529 ui.write(uipathfn(abs), end)
4530 ret = 0
4530 ret = 0
4531
4531
4532 return ret
4532 return ret
4533
4533
4534
4534
4535 @command(
4535 @command(
4536 b'log|history',
4536 b'log|history',
4537 [
4537 [
4538 (
4538 (
4539 b'f',
4539 b'f',
4540 b'follow',
4540 b'follow',
4541 None,
4541 None,
4542 _(
4542 _(
4543 b'follow changeset history, or file history across copies and renames'
4543 b'follow changeset history, or file history across copies and renames'
4544 ),
4544 ),
4545 ),
4545 ),
4546 (
4546 (
4547 b'',
4547 b'',
4548 b'follow-first',
4548 b'follow-first',
4549 None,
4549 None,
4550 _(b'only follow the first parent of merge changesets (DEPRECATED)'),
4550 _(b'only follow the first parent of merge changesets (DEPRECATED)'),
4551 ),
4551 ),
4552 (
4552 (
4553 b'd',
4553 b'd',
4554 b'date',
4554 b'date',
4555 b'',
4555 b'',
4556 _(b'show revisions matching date spec'),
4556 _(b'show revisions matching date spec'),
4557 _(b'DATE'),
4557 _(b'DATE'),
4558 ),
4558 ),
4559 (b'C', b'copies', None, _(b'show copied files')),
4559 (b'C', b'copies', None, _(b'show copied files')),
4560 (
4560 (
4561 b'k',
4561 b'k',
4562 b'keyword',
4562 b'keyword',
4563 [],
4563 [],
4564 _(b'do case-insensitive search for a given text'),
4564 _(b'do case-insensitive search for a given text'),
4565 _(b'TEXT'),
4565 _(b'TEXT'),
4566 ),
4566 ),
4567 (
4567 (
4568 b'r',
4568 b'r',
4569 b'rev',
4569 b'rev',
4570 [],
4570 [],
4571 _(b'revisions to select or follow from'),
4571 _(b'revisions to select or follow from'),
4572 _(b'REV'),
4572 _(b'REV'),
4573 ),
4573 ),
4574 (
4574 (
4575 b'L',
4575 b'L',
4576 b'line-range',
4576 b'line-range',
4577 [],
4577 [],
4578 _(b'follow line range of specified file (EXPERIMENTAL)'),
4578 _(b'follow line range of specified file (EXPERIMENTAL)'),
4579 _(b'FILE,RANGE'),
4579 _(b'FILE,RANGE'),
4580 ),
4580 ),
4581 (
4581 (
4582 b'',
4582 b'',
4583 b'removed',
4583 b'removed',
4584 None,
4584 None,
4585 _(b'include revisions where files were removed'),
4585 _(b'include revisions where files were removed'),
4586 ),
4586 ),
4587 (
4587 (
4588 b'm',
4588 b'm',
4589 b'only-merges',
4589 b'only-merges',
4590 None,
4590 None,
4591 _(b'show only merges (DEPRECATED) (use -r "merge()" instead)'),
4591 _(b'show only merges (DEPRECATED) (use -r "merge()" instead)'),
4592 ),
4592 ),
4593 (b'u', b'user', [], _(b'revisions committed by user'), _(b'USER')),
4593 (b'u', b'user', [], _(b'revisions committed by user'), _(b'USER')),
4594 (
4594 (
4595 b'',
4595 b'',
4596 b'only-branch',
4596 b'only-branch',
4597 [],
4597 [],
4598 _(
4598 _(
4599 b'show only changesets within the given named branch (DEPRECATED)'
4599 b'show only changesets within the given named branch (DEPRECATED)'
4600 ),
4600 ),
4601 _(b'BRANCH'),
4601 _(b'BRANCH'),
4602 ),
4602 ),
4603 (
4603 (
4604 b'b',
4604 b'b',
4605 b'branch',
4605 b'branch',
4606 [],
4606 [],
4607 _(b'show changesets within the given named branch'),
4607 _(b'show changesets within the given named branch'),
4608 _(b'BRANCH'),
4608 _(b'BRANCH'),
4609 ),
4609 ),
4610 (
4610 (
4611 b'B',
4611 b'B',
4612 b'bookmark',
4612 b'bookmark',
4613 [],
4613 [],
4614 _(b"show changesets within the given bookmark"),
4614 _(b"show changesets within the given bookmark"),
4615 _(b'BOOKMARK'),
4615 _(b'BOOKMARK'),
4616 ),
4616 ),
4617 (
4617 (
4618 b'P',
4618 b'P',
4619 b'prune',
4619 b'prune',
4620 [],
4620 [],
4621 _(b'do not display revision or any of its ancestors'),
4621 _(b'do not display revision or any of its ancestors'),
4622 _(b'REV'),
4622 _(b'REV'),
4623 ),
4623 ),
4624 ]
4624 ]
4625 + logopts
4625 + logopts
4626 + walkopts,
4626 + walkopts,
4627 _(b'[OPTION]... [FILE]'),
4627 _(b'[OPTION]... [FILE]'),
4628 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4628 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
4629 helpbasic=True,
4629 helpbasic=True,
4630 inferrepo=True,
4630 inferrepo=True,
4631 intents={INTENT_READONLY},
4631 intents={INTENT_READONLY},
4632 )
4632 )
4633 def log(ui, repo, *pats, **opts):
4633 def log(ui, repo, *pats, **opts):
4634 """show revision history of entire repository or files
4634 """show revision history of entire repository or files
4635
4635
4636 Print the revision history of the specified files or the entire
4636 Print the revision history of the specified files or the entire
4637 project.
4637 project.
4638
4638
4639 If no revision range is specified, the default is ``tip:0`` unless
4639 If no revision range is specified, the default is ``tip:0`` unless
4640 --follow is set.
4640 --follow is set.
4641
4641
4642 File history is shown without following rename or copy history of
4642 File history is shown without following rename or copy history of
4643 files. Use -f/--follow with a filename to follow history across
4643 files. Use -f/--follow with a filename to follow history across
4644 renames and copies. --follow without a filename will only show
4644 renames and copies. --follow without a filename will only show
4645 ancestors of the starting revisions. The starting revisions can be
4645 ancestors of the starting revisions. The starting revisions can be
4646 specified by -r/--rev, which default to the working directory parent.
4646 specified by -r/--rev, which default to the working directory parent.
4647
4647
4648 By default this command prints revision number and changeset id,
4648 By default this command prints revision number and changeset id,
4649 tags, non-trivial parents, user, date and time, and a summary for
4649 tags, non-trivial parents, user, date and time, and a summary for
4650 each commit. When the -v/--verbose switch is used, the list of
4650 each commit. When the -v/--verbose switch is used, the list of
4651 changed files and full commit message are shown.
4651 changed files and full commit message are shown.
4652
4652
4653 With --graph the revisions are shown as an ASCII art DAG with the most
4653 With --graph the revisions are shown as an ASCII art DAG with the most
4654 recent changeset at the top.
4654 recent changeset at the top.
4655 'o' is a changeset, '@' is a working directory parent, '%' is a changeset
4655 'o' is a changeset, '@' is a working directory parent, '%' is a changeset
4656 involved in an unresolved merge conflict, '_' closes a branch,
4656 involved in an unresolved merge conflict, '_' closes a branch,
4657 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
4657 'x' is obsolete, '*' is unstable, and '+' represents a fork where the
4658 changeset from the lines below is a parent of the 'o' merge on the same
4658 changeset from the lines below is a parent of the 'o' merge on the same
4659 line.
4659 line.
4660 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
4660 Paths in the DAG are represented with '|', '/' and so forth. ':' in place
4661 of a '|' indicates one or more revisions in a path are omitted.
4661 of a '|' indicates one or more revisions in a path are omitted.
4662
4662
4663 .. container:: verbose
4663 .. container:: verbose
4664
4664
4665 Use -L/--line-range FILE,M:N options to follow the history of lines
4665 Use -L/--line-range FILE,M:N options to follow the history of lines
4666 from M to N in FILE. With -p/--patch only diff hunks affecting
4666 from M to N in FILE. With -p/--patch only diff hunks affecting
4667 specified line range will be shown. This option requires --follow;
4667 specified line range will be shown. This option requires --follow;
4668 it can be specified multiple times. Currently, this option is not
4668 it can be specified multiple times. Currently, this option is not
4669 compatible with --graph. This option is experimental.
4669 compatible with --graph. This option is experimental.
4670
4670
4671 .. note::
4671 .. note::
4672
4672
4673 :hg:`log --patch` may generate unexpected diff output for merge
4673 :hg:`log --patch` may generate unexpected diff output for merge
4674 changesets, as it will only compare the merge changeset against
4674 changesets, as it will only compare the merge changeset against
4675 its first parent. Also, only files different from BOTH parents
4675 its first parent. Also, only files different from BOTH parents
4676 will appear in files:.
4676 will appear in files:.
4677
4677
4678 .. note::
4678 .. note::
4679
4679
4680 For performance reasons, :hg:`log FILE` may omit duplicate changes
4680 For performance reasons, :hg:`log FILE` may omit duplicate changes
4681 made on branches and will not show removals or mode changes. To
4681 made on branches and will not show removals or mode changes. To
4682 see all such changes, use the --removed switch.
4682 see all such changes, use the --removed switch.
4683
4683
4684 .. container:: verbose
4684 .. container:: verbose
4685
4685
4686 .. note::
4686 .. note::
4687
4687
4688 The history resulting from -L/--line-range options depends on diff
4688 The history resulting from -L/--line-range options depends on diff
4689 options; for instance if white-spaces are ignored, respective changes
4689 options; for instance if white-spaces are ignored, respective changes
4690 with only white-spaces in specified line range will not be listed.
4690 with only white-spaces in specified line range will not be listed.
4691
4691
4692 .. container:: verbose
4692 .. container:: verbose
4693
4693
4694 Some examples:
4694 Some examples:
4695
4695
4696 - changesets with full descriptions and file lists::
4696 - changesets with full descriptions and file lists::
4697
4697
4698 hg log -v
4698 hg log -v
4699
4699
4700 - changesets ancestral to the working directory::
4700 - changesets ancestral to the working directory::
4701
4701
4702 hg log -f
4702 hg log -f
4703
4703
4704 - last 10 commits on the current branch::
4704 - last 10 commits on the current branch::
4705
4705
4706 hg log -l 10 -b .
4706 hg log -l 10 -b .
4707
4707
4708 - changesets showing all modifications of a file, including removals::
4708 - changesets showing all modifications of a file, including removals::
4709
4709
4710 hg log --removed file.c
4710 hg log --removed file.c
4711
4711
4712 - all changesets that touch a directory, with diffs, excluding merges::
4712 - all changesets that touch a directory, with diffs, excluding merges::
4713
4713
4714 hg log -Mp lib/
4714 hg log -Mp lib/
4715
4715
4716 - all revision numbers that match a keyword::
4716 - all revision numbers that match a keyword::
4717
4717
4718 hg log -k bug --template "{rev}\\n"
4718 hg log -k bug --template "{rev}\\n"
4719
4719
4720 - the full hash identifier of the working directory parent::
4720 - the full hash identifier of the working directory parent::
4721
4721
4722 hg log -r . --template "{node}\\n"
4722 hg log -r . --template "{node}\\n"
4723
4723
4724 - list available log templates::
4724 - list available log templates::
4725
4725
4726 hg log -T list
4726 hg log -T list
4727
4727
4728 - check if a given changeset is included in a tagged release::
4728 - check if a given changeset is included in a tagged release::
4729
4729
4730 hg log -r "a21ccf and ancestor(1.9)"
4730 hg log -r "a21ccf and ancestor(1.9)"
4731
4731
4732 - find all changesets by some user in a date range::
4732 - find all changesets by some user in a date range::
4733
4733
4734 hg log -k alice -d "may 2008 to jul 2008"
4734 hg log -k alice -d "may 2008 to jul 2008"
4735
4735
4736 - summary of all changesets after the last tag::
4736 - summary of all changesets after the last tag::
4737
4737
4738 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4738 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4739
4739
4740 - changesets touching lines 13 to 23 for file.c::
4740 - changesets touching lines 13 to 23 for file.c::
4741
4741
4742 hg log -L file.c,13:23
4742 hg log -L file.c,13:23
4743
4743
4744 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
4744 - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
4745 main.c with patch::
4745 main.c with patch::
4746
4746
4747 hg log -L file.c,13:23 -L main.c,2:6 -p
4747 hg log -L file.c,13:23 -L main.c,2:6 -p
4748
4748
4749 See :hg:`help dates` for a list of formats valid for -d/--date.
4749 See :hg:`help dates` for a list of formats valid for -d/--date.
4750
4750
4751 See :hg:`help revisions` for more about specifying and ordering
4751 See :hg:`help revisions` for more about specifying and ordering
4752 revisions.
4752 revisions.
4753
4753
4754 See :hg:`help templates` for more about pre-packaged styles and
4754 See :hg:`help templates` for more about pre-packaged styles and
4755 specifying custom templates. The default template used by the log
4755 specifying custom templates. The default template used by the log
4756 command can be customized via the ``command-templates.log`` configuration
4756 command can be customized via the ``command-templates.log`` configuration
4757 setting.
4757 setting.
4758
4758
4759 Returns 0 on success.
4759 Returns 0 on success.
4760
4760
4761 """
4761 """
4762 opts = pycompat.byteskwargs(opts)
4762 opts = pycompat.byteskwargs(opts)
4763 linerange = opts.get(b'line_range')
4763 linerange = opts.get(b'line_range')
4764
4764
4765 if linerange and not opts.get(b'follow'):
4765 if linerange and not opts.get(b'follow'):
4766 raise error.InputError(_(b'--line-range requires --follow'))
4766 raise error.InputError(_(b'--line-range requires --follow'))
4767
4767
4768 if linerange and pats:
4768 if linerange and pats:
4769 # TODO: take pats as patterns with no line-range filter
4769 # TODO: take pats as patterns with no line-range filter
4770 raise error.InputError(
4770 raise error.InputError(
4771 _(b'FILE arguments are not compatible with --line-range option')
4771 _(b'FILE arguments are not compatible with --line-range option')
4772 )
4772 )
4773
4773
4774 repo = scmutil.unhidehashlikerevs(repo, opts.get(b'rev'), b'nowarn')
4774 repo = scmutil.unhidehashlikerevs(repo, opts.get(b'rev'), b'nowarn')
4775 walk_opts = logcmdutil.parseopts(ui, pats, opts)
4775 walk_opts = logcmdutil.parseopts(ui, pats, opts)
4776 revs, differ = logcmdutil.getrevs(repo, walk_opts)
4776 revs, differ = logcmdutil.getrevs(repo, walk_opts)
4777 if linerange:
4777 if linerange:
4778 # TODO: should follow file history from logcmdutil._initialrevs(),
4778 # TODO: should follow file history from logcmdutil._initialrevs(),
4779 # then filter the result by logcmdutil._makerevset() and --limit
4779 # then filter the result by logcmdutil._makerevset() and --limit
4780 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
4780 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
4781
4781
4782 getcopies = None
4782 getcopies = None
4783 if opts.get(b'copies'):
4783 if opts.get(b'copies'):
4784 endrev = None
4784 endrev = None
4785 if revs:
4785 if revs:
4786 endrev = revs.max() + 1
4786 endrev = revs.max() + 1
4787 getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
4787 getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
4788
4788
4789 ui.pager(b'log')
4789 ui.pager(b'log')
4790 displayer = logcmdutil.changesetdisplayer(
4790 displayer = logcmdutil.changesetdisplayer(
4791 ui, repo, opts, differ, buffered=True
4791 ui, repo, opts, differ, buffered=True
4792 )
4792 )
4793 if opts.get(b'graph'):
4793 if opts.get(b'graph'):
4794 displayfn = logcmdutil.displaygraphrevs
4794 displayfn = logcmdutil.displaygraphrevs
4795 else:
4795 else:
4796 displayfn = logcmdutil.displayrevs
4796 displayfn = logcmdutil.displayrevs
4797 displayfn(ui, repo, revs, displayer, getcopies)
4797 displayfn(ui, repo, revs, displayer, getcopies)
4798
4798
4799
4799
4800 @command(
4800 @command(
4801 b'manifest',
4801 b'manifest',
4802 [
4802 [
4803 (b'r', b'rev', b'', _(b'revision to display'), _(b'REV')),
4803 (b'r', b'rev', b'', _(b'revision to display'), _(b'REV')),
4804 (b'', b'all', False, _(b"list files from all revisions")),
4804 (b'', b'all', False, _(b"list files from all revisions")),
4805 ]
4805 ]
4806 + formatteropts,
4806 + formatteropts,
4807 _(b'[-r REV]'),
4807 _(b'[-r REV]'),
4808 helpcategory=command.CATEGORY_MAINTENANCE,
4808 helpcategory=command.CATEGORY_MAINTENANCE,
4809 intents={INTENT_READONLY},
4809 intents={INTENT_READONLY},
4810 )
4810 )
4811 def manifest(ui, repo, node=None, rev=None, **opts):
4811 def manifest(ui, repo, node=None, rev=None, **opts):
4812 """output the current or given revision of the project manifest
4812 """output the current or given revision of the project manifest
4813
4813
4814 Print a list of version controlled files for the given revision.
4814 Print a list of version controlled files for the given revision.
4815 If no revision is given, the first parent of the working directory
4815 If no revision is given, the first parent of the working directory
4816 is used, or the null revision if no revision is checked out.
4816 is used, or the null revision if no revision is checked out.
4817
4817
4818 With -v, print file permissions, symlink and executable bits.
4818 With -v, print file permissions, symlink and executable bits.
4819 With --debug, print file revision hashes.
4819 With --debug, print file revision hashes.
4820
4820
4821 If option --all is specified, the list of all files from all revisions
4821 If option --all is specified, the list of all files from all revisions
4822 is printed. This includes deleted and renamed files.
4822 is printed. This includes deleted and renamed files.
4823
4823
4824 Returns 0 on success.
4824 Returns 0 on success.
4825 """
4825 """
4826 fm = ui.formatter(b'manifest', pycompat.byteskwargs(opts))
4826 fm = ui.formatter(b'manifest', pycompat.byteskwargs(opts))
4827
4827
4828 if opts.get('all'):
4828 if opts.get('all'):
4829 if rev or node:
4829 if rev or node:
4830 raise error.InputError(_(b"can't specify a revision with --all"))
4830 raise error.InputError(_(b"can't specify a revision with --all"))
4831
4831
4832 res = set()
4832 res = set()
4833 for rev in repo:
4833 for rev in repo:
4834 ctx = repo[rev]
4834 ctx = repo[rev]
4835 res |= set(ctx.files())
4835 res |= set(ctx.files())
4836
4836
4837 ui.pager(b'manifest')
4837 ui.pager(b'manifest')
4838 for f in sorted(res):
4838 for f in sorted(res):
4839 fm.startitem()
4839 fm.startitem()
4840 fm.write(b"path", b'%s\n', f)
4840 fm.write(b"path", b'%s\n', f)
4841 fm.end()
4841 fm.end()
4842 return
4842 return
4843
4843
4844 if rev and node:
4844 if rev and node:
4845 raise error.InputError(_(b"please specify just one revision"))
4845 raise error.InputError(_(b"please specify just one revision"))
4846
4846
4847 if not node:
4847 if not node:
4848 node = rev
4848 node = rev
4849
4849
4850 char = {b'l': b'@', b'x': b'*', b'': b'', b't': b'd'}
4850 char = {b'l': b'@', b'x': b'*', b'': b'', b't': b'd'}
4851 mode = {b'l': b'644', b'x': b'755', b'': b'644', b't': b'755'}
4851 mode = {b'l': b'644', b'x': b'755', b'': b'644', b't': b'755'}
4852 if node:
4852 if node:
4853 repo = scmutil.unhidehashlikerevs(repo, [node], b'nowarn')
4853 repo = scmutil.unhidehashlikerevs(repo, [node], b'nowarn')
4854 ctx = logcmdutil.revsingle(repo, node)
4854 ctx = logcmdutil.revsingle(repo, node)
4855 mf = ctx.manifest()
4855 mf = ctx.manifest()
4856 ui.pager(b'manifest')
4856 ui.pager(b'manifest')
4857 for f in ctx:
4857 for f in ctx:
4858 fm.startitem()
4858 fm.startitem()
4859 fm.context(ctx=ctx)
4859 fm.context(ctx=ctx)
4860 fl = ctx[f].flags()
4860 fl = ctx[f].flags()
4861 fm.condwrite(ui.debugflag, b'hash', b'%s ', hex(mf[f]))
4861 fm.condwrite(ui.debugflag, b'hash', b'%s ', hex(mf[f]))
4862 fm.condwrite(ui.verbose, b'mode type', b'%s %1s ', mode[fl], char[fl])
4862 fm.condwrite(ui.verbose, b'mode type', b'%s %1s ', mode[fl], char[fl])
4863 fm.write(b'path', b'%s\n', f)
4863 fm.write(b'path', b'%s\n', f)
4864 fm.end()
4864 fm.end()
4865
4865
4866
4866
4867 @command(
4867 @command(
4868 b'merge',
4868 b'merge',
4869 [
4869 [
4870 (
4870 (
4871 b'f',
4871 b'f',
4872 b'force',
4872 b'force',
4873 None,
4873 None,
4874 _(b'force a merge including outstanding changes (DEPRECATED)'),
4874 _(b'force a merge including outstanding changes (DEPRECATED)'),
4875 ),
4875 ),
4876 (b'r', b'rev', b'', _(b'revision to merge'), _(b'REV')),
4876 (b'r', b'rev', b'', _(b'revision to merge'), _(b'REV')),
4877 (
4877 (
4878 b'P',
4878 b'P',
4879 b'preview',
4879 b'preview',
4880 None,
4880 None,
4881 _(b'review revisions to merge (no merge is performed)'),
4881 _(b'review revisions to merge (no merge is performed)'),
4882 ),
4882 ),
4883 (b'', b'abort', None, _(b'abort the ongoing merge')),
4883 (b'', b'abort', None, _(b'abort the ongoing merge')),
4884 ]
4884 ]
4885 + mergetoolopts,
4885 + mergetoolopts,
4886 _(b'[-P] [[-r] REV]'),
4886 _(b'[-P] [[-r] REV]'),
4887 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
4887 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
4888 helpbasic=True,
4888 helpbasic=True,
4889 )
4889 )
4890 def merge(ui, repo, node=None, **opts):
4890 def merge(ui, repo, node=None, **opts):
4891 """merge another revision into working directory
4891 """merge another revision into working directory
4892
4892
4893 The current working directory is updated with all changes made in
4893 The current working directory is updated with all changes made in
4894 the requested revision since the last common predecessor revision.
4894 the requested revision since the last common predecessor revision.
4895
4895
4896 Files that changed between either parent are marked as changed for
4896 Files that changed between either parent are marked as changed for
4897 the next commit and a commit must be performed before any further
4897 the next commit and a commit must be performed before any further
4898 updates to the repository are allowed. The next commit will have
4898 updates to the repository are allowed. The next commit will have
4899 two parents.
4899 two parents.
4900
4900
4901 ``--tool`` can be used to specify the merge tool used for file
4901 ``--tool`` can be used to specify the merge tool used for file
4902 merges. It overrides the HGMERGE environment variable and your
4902 merges. It overrides the HGMERGE environment variable and your
4903 configuration files. See :hg:`help merge-tools` for options.
4903 configuration files. See :hg:`help merge-tools` for options.
4904
4904
4905 If no revision is specified, the working directory's parent is a
4905 If no revision is specified, the working directory's parent is a
4906 head revision, and the current branch contains exactly one other
4906 head revision, and the current branch contains exactly one other
4907 head, the other head is merged with by default. Otherwise, an
4907 head, the other head is merged with by default. Otherwise, an
4908 explicit revision with which to merge must be provided.
4908 explicit revision with which to merge must be provided.
4909
4909
4910 See :hg:`help resolve` for information on handling file conflicts.
4910 See :hg:`help resolve` for information on handling file conflicts.
4911
4911
4912 To undo an uncommitted merge, use :hg:`merge --abort` which
4912 To undo an uncommitted merge, use :hg:`merge --abort` which
4913 will check out a clean copy of the original merge parent, losing
4913 will check out a clean copy of the original merge parent, losing
4914 all changes.
4914 all changes.
4915
4915
4916 Returns 0 on success, 1 if there are unresolved files.
4916 Returns 0 on success, 1 if there are unresolved files.
4917 """
4917 """
4918
4918
4919 abort = opts.get('abort')
4919 abort = opts.get('abort')
4920 if abort and repo.dirstate.p2() == repo.nullid:
4920 if abort and repo.dirstate.p2() == repo.nullid:
4921 cmdutil.wrongtooltocontinue(repo, _(b'merge'))
4921 cmdutil.wrongtooltocontinue(repo, _(b'merge'))
4922 cmdutil.check_incompatible_arguments(opts, 'abort', ['rev', 'preview'])
4922 cmdutil.check_incompatible_arguments(opts, 'abort', ['rev', 'preview'])
4923 if abort:
4923 if abort:
4924 state = cmdutil.getunfinishedstate(repo)
4924 state = cmdutil.getunfinishedstate(repo)
4925 if state and state._opname != b'merge':
4925 if state and state._opname != b'merge':
4926 raise error.StateError(
4926 raise error.StateError(
4927 _(b'cannot abort merge with %s in progress') % (state._opname),
4927 _(b'cannot abort merge with %s in progress') % (state._opname),
4928 hint=state.hint(),
4928 hint=state.hint(),
4929 )
4929 )
4930 if node:
4930 if node:
4931 raise error.InputError(_(b"cannot specify a node with --abort"))
4931 raise error.InputError(_(b"cannot specify a node with --abort"))
4932 return hg.abortmerge(repo.ui, repo)
4932 return hg.abortmerge(repo.ui, repo)
4933
4933
4934 if opts.get('rev') and node:
4934 if opts.get('rev') and node:
4935 raise error.InputError(_(b"please specify just one revision"))
4935 raise error.InputError(_(b"please specify just one revision"))
4936 if not node:
4936 if not node:
4937 node = opts.get('rev')
4937 node = opts.get('rev')
4938
4938
4939 if node:
4939 if node:
4940 ctx = logcmdutil.revsingle(repo, node)
4940 ctx = logcmdutil.revsingle(repo, node)
4941 else:
4941 else:
4942 if ui.configbool(b'commands', b'merge.require-rev'):
4942 if ui.configbool(b'commands', b'merge.require-rev'):
4943 raise error.InputError(
4943 raise error.InputError(
4944 _(
4944 _(
4945 b'configuration requires specifying revision to merge '
4945 b'configuration requires specifying revision to merge '
4946 b'with'
4946 b'with'
4947 )
4947 )
4948 )
4948 )
4949 ctx = repo[destutil.destmerge(repo)]
4949 ctx = repo[destutil.destmerge(repo)]
4950
4950
4951 if ctx.node() is None:
4951 if ctx.node() is None:
4952 raise error.InputError(
4952 raise error.InputError(
4953 _(b'merging with the working copy has no effect')
4953 _(b'merging with the working copy has no effect')
4954 )
4954 )
4955
4955
4956 if opts.get('preview'):
4956 if opts.get('preview'):
4957 # find nodes that are ancestors of p2 but not of p1
4957 # find nodes that are ancestors of p2 but not of p1
4958 p1 = repo[b'.'].node()
4958 p1 = repo[b'.'].node()
4959 p2 = ctx.node()
4959 p2 = ctx.node()
4960 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4960 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4961
4961
4962 displayer = logcmdutil.changesetdisplayer(
4962 displayer = logcmdutil.changesetdisplayer(
4963 ui, repo, pycompat.byteskwargs(opts)
4963 ui, repo, pycompat.byteskwargs(opts)
4964 )
4964 )
4965 for node in nodes:
4965 for node in nodes:
4966 displayer.show(repo[node])
4966 displayer.show(repo[node])
4967 displayer.close()
4967 displayer.close()
4968 return 0
4968 return 0
4969
4969
4970 # ui.forcemerge is an internal variable, do not document
4970 # ui.forcemerge is an internal variable, do not document
4971 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
4971 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
4972 with ui.configoverride(overrides, b'merge'):
4972 with ui.configoverride(overrides, b'merge'):
4973 force = opts.get('force')
4973 force = opts.get('force')
4974 labels = [b'working copy', b'merge rev', b'common ancestor']
4974 labels = [b'working copy', b'merge rev', b'common ancestor']
4975 return hg.merge(ctx, force=force, labels=labels)
4975 return hg.merge(ctx, force=force, labels=labels)
4976
4976
4977
4977
4978 statemod.addunfinished(
4978 statemod.addunfinished(
4979 b'merge',
4979 b'merge',
4980 fname=None,
4980 fname=None,
4981 clearable=True,
4981 clearable=True,
4982 allowcommit=True,
4982 allowcommit=True,
4983 cmdmsg=_(b'outstanding uncommitted merge'),
4983 cmdmsg=_(b'outstanding uncommitted merge'),
4984 abortfunc=hg.abortmerge,
4984 abortfunc=hg.abortmerge,
4985 statushint=_(
4985 statushint=_(
4986 b'To continue: hg commit\nTo abort: hg merge --abort'
4986 b'To continue: hg commit\nTo abort: hg merge --abort'
4987 ),
4987 ),
4988 cmdhint=_(b"use 'hg commit' or 'hg merge --abort'"),
4988 cmdhint=_(b"use 'hg commit' or 'hg merge --abort'"),
4989 )
4989 )
4990
4990
4991
4991
4992 @command(
4992 @command(
4993 b'outgoing|out',
4993 b'outgoing|out',
4994 [
4994 [
4995 (
4995 (
4996 b'f',
4996 b'f',
4997 b'force',
4997 b'force',
4998 None,
4998 None,
4999 _(b'run even when the destination is unrelated'),
4999 _(b'run even when the destination is unrelated'),
5000 ),
5000 ),
5001 (
5001 (
5002 b'r',
5002 b'r',
5003 b'rev',
5003 b'rev',
5004 [],
5004 [],
5005 _(b'a changeset intended to be included in the destination'),
5005 _(b'a changeset intended to be included in the destination'),
5006 _(b'REV'),
5006 _(b'REV'),
5007 ),
5007 ),
5008 (b'n', b'newest-first', None, _(b'show newest record first')),
5008 (b'n', b'newest-first', None, _(b'show newest record first')),
5009 (b'B', b'bookmarks', False, _(b'compare bookmarks')),
5009 (b'B', b'bookmarks', False, _(b'compare bookmarks')),
5010 (
5010 (
5011 b'b',
5011 b'b',
5012 b'branch',
5012 b'branch',
5013 [],
5013 [],
5014 _(b'a specific branch you would like to push'),
5014 _(b'a specific branch you would like to push'),
5015 _(b'BRANCH'),
5015 _(b'BRANCH'),
5016 ),
5016 ),
5017 ]
5017 ]
5018 + logopts
5018 + logopts
5019 + remoteopts
5019 + remoteopts
5020 + subrepoopts,
5020 + subrepoopts,
5021 _(b'[-M] [-p] [-n] [-f] [-r REV]... [DEST]...'),
5021 _(b'[-M] [-p] [-n] [-f] [-r REV]... [DEST]...'),
5022 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5022 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5023 )
5023 )
5024 def outgoing(ui, repo, *dests, **opts):
5024 def outgoing(ui, repo, *dests, **opts):
5025 """show changesets not found in the destination
5025 """show changesets not found in the destination
5026
5026
5027 Show changesets not found in the specified destination repository
5027 Show changesets not found in the specified destination repository
5028 or the default push location. These are the changesets that would
5028 or the default push location. These are the changesets that would
5029 be pushed if a push was requested.
5029 be pushed if a push was requested.
5030
5030
5031 See pull for details of valid destination formats.
5031 See pull for details of valid destination formats.
5032
5032
5033 .. container:: verbose
5033 .. container:: verbose
5034
5034
5035 With -B/--bookmarks, the result of bookmark comparison between
5035 With -B/--bookmarks, the result of bookmark comparison between
5036 local and remote repositories is displayed. With -v/--verbose,
5036 local and remote repositories is displayed. With -v/--verbose,
5037 status is also displayed for each bookmark like below::
5037 status is also displayed for each bookmark like below::
5038
5038
5039 BM1 01234567890a added
5039 BM1 01234567890a added
5040 BM2 deleted
5040 BM2 deleted
5041 BM3 234567890abc advanced
5041 BM3 234567890abc advanced
5042 BM4 34567890abcd diverged
5042 BM4 34567890abcd diverged
5043 BM5 4567890abcde changed
5043 BM5 4567890abcde changed
5044
5044
5045 The action taken when pushing depends on the
5045 The action taken when pushing depends on the
5046 status of each bookmark:
5046 status of each bookmark:
5047
5047
5048 :``added``: push with ``-B`` will create it
5048 :``added``: push with ``-B`` will create it
5049 :``deleted``: push with ``-B`` will delete it
5049 :``deleted``: push with ``-B`` will delete it
5050 :``advanced``: push will update it
5050 :``advanced``: push will update it
5051 :``diverged``: push with ``-B`` will update it
5051 :``diverged``: push with ``-B`` will update it
5052 :``changed``: push with ``-B`` will update it
5052 :``changed``: push with ``-B`` will update it
5053
5053
5054 From the point of view of pushing behavior, bookmarks
5054 From the point of view of pushing behavior, bookmarks
5055 existing only in the remote repository are treated as
5055 existing only in the remote repository are treated as
5056 ``deleted``, even if it is in fact added remotely.
5056 ``deleted``, even if it is in fact added remotely.
5057
5057
5058 Returns 0 if there are outgoing changes, 1 otherwise.
5058 Returns 0 if there are outgoing changes, 1 otherwise.
5059 """
5059 """
5060 opts = pycompat.byteskwargs(opts)
5060 opts = pycompat.byteskwargs(opts)
5061 if opts.get(b'bookmarks'):
5061 if opts.get(b'bookmarks'):
5062 for path in urlutil.get_push_paths(repo, ui, dests):
5062 for path in urlutil.get_push_paths(repo, ui, dests):
5063 other = hg.peer(repo, opts, path)
5063 other = hg.peer(repo, opts, path)
5064 try:
5064 try:
5065 if b'bookmarks' not in other.listkeys(b'namespaces'):
5065 if b'bookmarks' not in other.listkeys(b'namespaces'):
5066 ui.warn(_(b"remote doesn't support bookmarks\n"))
5066 ui.warn(_(b"remote doesn't support bookmarks\n"))
5067 return 0
5067 return 0
5068 ui.status(
5068 ui.status(
5069 _(b'comparing with %s\n') % urlutil.hidepassword(path.loc)
5069 _(b'comparing with %s\n') % urlutil.hidepassword(path.loc)
5070 )
5070 )
5071 ui.pager(b'outgoing')
5071 ui.pager(b'outgoing')
5072 return bookmarks.outgoing(ui, repo, other)
5072 return bookmarks.outgoing(ui, repo, other)
5073 finally:
5073 finally:
5074 other.close()
5074 other.close()
5075
5075
5076 return hg.outgoing(ui, repo, dests, opts)
5076 return hg.outgoing(ui, repo, dests, opts)
5077
5077
5078
5078
5079 @command(
5079 @command(
5080 b'parents',
5080 b'parents',
5081 [
5081 [
5082 (
5082 (
5083 b'r',
5083 b'r',
5084 b'rev',
5084 b'rev',
5085 b'',
5085 b'',
5086 _(b'show parents of the specified revision'),
5086 _(b'show parents of the specified revision'),
5087 _(b'REV'),
5087 _(b'REV'),
5088 ),
5088 ),
5089 ]
5089 ]
5090 + templateopts,
5090 + templateopts,
5091 _(b'[-r REV] [FILE]'),
5091 _(b'[-r REV] [FILE]'),
5092 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
5092 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
5093 inferrepo=True,
5093 inferrepo=True,
5094 )
5094 )
5095 def parents(ui, repo, file_=None, **opts):
5095 def parents(ui, repo, file_=None, **opts):
5096 """show the parents of the working directory or revision (DEPRECATED)
5096 """show the parents of the working directory or revision (DEPRECATED)
5097
5097
5098 Print the working directory's parent revisions. If a revision is
5098 Print the working directory's parent revisions. If a revision is
5099 given via -r/--rev, the parent of that revision will be printed.
5099 given via -r/--rev, the parent of that revision will be printed.
5100 If a file argument is given, the revision in which the file was
5100 If a file argument is given, the revision in which the file was
5101 last changed (before the working directory revision or the
5101 last changed (before the working directory revision or the
5102 argument to --rev if given) is printed.
5102 argument to --rev if given) is printed.
5103
5103
5104 This command is equivalent to::
5104 This command is equivalent to::
5105
5105
5106 hg log -r "p1()+p2()" or
5106 hg log -r "p1()+p2()" or
5107 hg log -r "p1(REV)+p2(REV)" or
5107 hg log -r "p1(REV)+p2(REV)" or
5108 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
5108 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
5109 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
5109 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
5110
5110
5111 See :hg:`summary` and :hg:`help revsets` for related information.
5111 See :hg:`summary` and :hg:`help revsets` for related information.
5112
5112
5113 Returns 0 on success.
5113 Returns 0 on success.
5114 """
5114 """
5115
5115
5116 opts = pycompat.byteskwargs(opts)
5116 opts = pycompat.byteskwargs(opts)
5117 rev = opts.get(b'rev')
5117 rev = opts.get(b'rev')
5118 if rev:
5118 if rev:
5119 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
5119 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
5120 ctx = logcmdutil.revsingle(repo, rev, None)
5120 ctx = logcmdutil.revsingle(repo, rev, None)
5121
5121
5122 if file_:
5122 if file_:
5123 m = scmutil.match(ctx, (file_,), opts)
5123 m = scmutil.match(ctx, (file_,), opts)
5124 if m.anypats() or len(m.files()) != 1:
5124 if m.anypats() or len(m.files()) != 1:
5125 raise error.InputError(_(b'can only specify an explicit filename'))
5125 raise error.InputError(_(b'can only specify an explicit filename'))
5126 file_ = m.files()[0]
5126 file_ = m.files()[0]
5127 filenodes = []
5127 filenodes = []
5128 for cp in ctx.parents():
5128 for cp in ctx.parents():
5129 if not cp:
5129 if not cp:
5130 continue
5130 continue
5131 try:
5131 try:
5132 filenodes.append(cp.filenode(file_))
5132 filenodes.append(cp.filenode(file_))
5133 except error.LookupError:
5133 except error.LookupError:
5134 pass
5134 pass
5135 if not filenodes:
5135 if not filenodes:
5136 raise error.InputError(_(b"'%s' not found in manifest") % file_)
5136 raise error.InputError(_(b"'%s' not found in manifest") % file_)
5137 p = []
5137 p = []
5138 for fn in filenodes:
5138 for fn in filenodes:
5139 fctx = repo.filectx(file_, fileid=fn)
5139 fctx = repo.filectx(file_, fileid=fn)
5140 p.append(fctx.node())
5140 p.append(fctx.node())
5141 else:
5141 else:
5142 p = [cp.node() for cp in ctx.parents()]
5142 p = [cp.node() for cp in ctx.parents()]
5143
5143
5144 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
5144 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
5145 for n in p:
5145 for n in p:
5146 if n != repo.nullid:
5146 if n != repo.nullid:
5147 displayer.show(repo[n])
5147 displayer.show(repo[n])
5148 displayer.close()
5148 displayer.close()
5149
5149
5150
5150
5151 @command(
5151 @command(
5152 b'paths',
5152 b'paths',
5153 formatteropts,
5153 formatteropts,
5154 _(b'[NAME]'),
5154 _(b'[NAME]'),
5155 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5155 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5156 optionalrepo=True,
5156 optionalrepo=True,
5157 intents={INTENT_READONLY},
5157 intents={INTENT_READONLY},
5158 )
5158 )
5159 def paths(ui, repo, search=None, **opts):
5159 def paths(ui, repo, search=None, **opts):
5160 """show aliases for remote repositories
5160 """show aliases for remote repositories
5161
5161
5162 Show definition of symbolic path name NAME. If no name is given,
5162 Show definition of symbolic path name NAME. If no name is given,
5163 show definition of all available names.
5163 show definition of all available names.
5164
5164
5165 Option -q/--quiet suppresses all output when searching for NAME
5165 Option -q/--quiet suppresses all output when searching for NAME
5166 and shows only the path names when listing all definitions.
5166 and shows only the path names when listing all definitions.
5167
5167
5168 Path names are defined in the [paths] section of your
5168 Path names are defined in the [paths] section of your
5169 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
5169 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
5170 repository, ``.hg/hgrc`` is used, too.
5170 repository, ``.hg/hgrc`` is used, too.
5171
5171
5172 The path names ``default`` and ``default-push`` have a special
5172 The path names ``default`` and ``default-push`` have a special
5173 meaning. When performing a push or pull operation, they are used
5173 meaning. When performing a push or pull operation, they are used
5174 as fallbacks if no location is specified on the command-line.
5174 as fallbacks if no location is specified on the command-line.
5175 When ``default-push`` is set, it will be used for push and
5175 When ``default-push`` is set, it will be used for push and
5176 ``default`` will be used for pull; otherwise ``default`` is used
5176 ``default`` will be used for pull; otherwise ``default`` is used
5177 as the fallback for both. When cloning a repository, the clone
5177 as the fallback for both. When cloning a repository, the clone
5178 source is written as ``default`` in ``.hg/hgrc``.
5178 source is written as ``default`` in ``.hg/hgrc``.
5179
5179
5180 .. note::
5180 .. note::
5181
5181
5182 ``default`` and ``default-push`` apply to all inbound (e.g.
5182 ``default`` and ``default-push`` apply to all inbound (e.g.
5183 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
5183 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
5184 and :hg:`bundle`) operations.
5184 and :hg:`bundle`) operations.
5185
5185
5186 See :hg:`help urls` for more information.
5186 See :hg:`help urls` for more information.
5187
5187
5188 .. container:: verbose
5188 .. container:: verbose
5189
5189
5190 Template:
5190 Template:
5191
5191
5192 The following keywords are supported. See also :hg:`help templates`.
5192 The following keywords are supported. See also :hg:`help templates`.
5193
5193
5194 :name: String. Symbolic name of the path alias.
5194 :name: String. Symbolic name of the path alias.
5195 :pushurl: String. URL for push operations.
5195 :pushurl: String. URL for push operations.
5196 :url: String. URL or directory path for the other operations.
5196 :url: String. URL or directory path for the other operations.
5197
5197
5198 Returns 0 on success.
5198 Returns 0 on success.
5199 """
5199 """
5200
5200
5201 pathitems = urlutil.list_paths(ui, search)
5201 pathitems = urlutil.list_paths(ui, search)
5202 ui.pager(b'paths')
5202 ui.pager(b'paths')
5203
5203
5204 fm = ui.formatter(b'paths', pycompat.byteskwargs(opts))
5204 fm = ui.formatter(b'paths', pycompat.byteskwargs(opts))
5205 if fm.isplain():
5205 if fm.isplain():
5206 hidepassword = urlutil.hidepassword
5206 hidepassword = urlutil.hidepassword
5207 else:
5207 else:
5208 hidepassword = bytes
5208 hidepassword = bytes
5209 if ui.quiet:
5209 if ui.quiet:
5210 namefmt = b'%s\n'
5210 namefmt = b'%s\n'
5211 else:
5211 else:
5212 namefmt = b'%s = '
5212 namefmt = b'%s = '
5213 showsubopts = not search and not ui.quiet
5213 showsubopts = not search and not ui.quiet
5214
5214
5215 for name, path in pathitems:
5215 for name, path in pathitems:
5216 fm.startitem()
5216 fm.startitem()
5217 fm.condwrite(not search, b'name', namefmt, name)
5217 fm.condwrite(not search, b'name', namefmt, name)
5218 fm.condwrite(not ui.quiet, b'url', b'%s\n', hidepassword(path.rawloc))
5218 fm.condwrite(not ui.quiet, b'url', b'%s\n', hidepassword(path.rawloc))
5219 for subopt, value in sorted(path.suboptions.items()):
5219 for subopt, value in sorted(path.suboptions.items()):
5220 assert subopt not in (b'name', b'url')
5220 assert subopt not in (b'name', b'url')
5221 if showsubopts:
5221 if showsubopts:
5222 fm.plain(b'%s:%s = ' % (name, subopt))
5222 fm.plain(b'%s:%s = ' % (name, subopt))
5223 display = urlutil.path_suboptions_display[subopt]
5223 display = urlutil.path_suboptions_display[subopt]
5224 value = display(value)
5224 value = display(value)
5225 fm.condwrite(showsubopts, subopt, b'%s\n', value)
5225 fm.condwrite(showsubopts, subopt, b'%s\n', value)
5226
5226
5227 fm.end()
5227 fm.end()
5228
5228
5229 if search and not pathitems:
5229 if search and not pathitems:
5230 if not ui.quiet:
5230 if not ui.quiet:
5231 ui.warn(_(b"not found!\n"))
5231 ui.warn(_(b"not found!\n"))
5232 return 1
5232 return 1
5233 else:
5233 else:
5234 return 0
5234 return 0
5235
5235
5236
5236
5237 @command(
5237 @command(
5238 b'phase',
5238 b'phase',
5239 [
5239 [
5240 (b'p', b'public', False, _(b'set changeset phase to public')),
5240 (b'p', b'public', False, _(b'set changeset phase to public')),
5241 (b'd', b'draft', False, _(b'set changeset phase to draft')),
5241 (b'd', b'draft', False, _(b'set changeset phase to draft')),
5242 (b's', b'secret', False, _(b'set changeset phase to secret')),
5242 (b's', b'secret', False, _(b'set changeset phase to secret')),
5243 (b'f', b'force', False, _(b'allow to move boundary backward')),
5243 (b'f', b'force', False, _(b'allow to move boundary backward')),
5244 (b'r', b'rev', [], _(b'target revision'), _(b'REV')),
5244 (b'r', b'rev', [], _(b'target revision'), _(b'REV')),
5245 ],
5245 ],
5246 _(b'[-p|-d|-s] [-f] [-r] [REV...]'),
5246 _(b'[-p|-d|-s] [-f] [-r] [REV...]'),
5247 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
5247 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
5248 )
5248 )
5249 def phase(ui, repo, *revs, **opts):
5249 def phase(ui, repo, *revs, **opts):
5250 """set or show the current phase name
5250 """set or show the current phase name
5251
5251
5252 With no argument, show the phase name of the current revision(s).
5252 With no argument, show the phase name of the current revision(s).
5253
5253
5254 With one of -p/--public, -d/--draft or -s/--secret, change the
5254 With one of -p/--public, -d/--draft or -s/--secret, change the
5255 phase value of the specified revisions.
5255 phase value of the specified revisions.
5256
5256
5257 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
5257 Unless -f/--force is specified, :hg:`phase` won't move changesets from a
5258 lower phase to a higher phase. Phases are ordered as follows::
5258 lower phase to a higher phase. Phases are ordered as follows::
5259
5259
5260 public < draft < secret
5260 public < draft < secret
5261
5261
5262 Returns 0 on success, 1 if some phases could not be changed.
5262 Returns 0 on success, 1 if some phases could not be changed.
5263
5263
5264 (For more information about the phases concept, see :hg:`help phases`.)
5264 (For more information about the phases concept, see :hg:`help phases`.)
5265 """
5265 """
5266 opts = pycompat.byteskwargs(opts)
5266 opts = pycompat.byteskwargs(opts)
5267 # search for a unique phase argument
5267 # search for a unique phase argument
5268 targetphase = None
5268 targetphase = None
5269 for idx, name in enumerate(phases.cmdphasenames):
5269 for idx, name in enumerate(phases.cmdphasenames):
5270 if opts[name]:
5270 if opts[name]:
5271 if targetphase is not None:
5271 if targetphase is not None:
5272 raise error.InputError(_(b'only one phase can be specified'))
5272 raise error.InputError(_(b'only one phase can be specified'))
5273 targetphase = idx
5273 targetphase = idx
5274
5274
5275 # look for specified revision
5275 # look for specified revision
5276 revs = list(revs)
5276 revs = list(revs)
5277 revs.extend(opts[b'rev'])
5277 revs.extend(opts[b'rev'])
5278 if revs:
5278 if revs:
5279 revs = logcmdutil.revrange(repo, revs)
5279 revs = logcmdutil.revrange(repo, revs)
5280 else:
5280 else:
5281 # display both parents as the second parent phase can influence
5281 # display both parents as the second parent phase can influence
5282 # the phase of a merge commit
5282 # the phase of a merge commit
5283 revs = [c.rev() for c in repo[None].parents()]
5283 revs = [c.rev() for c in repo[None].parents()]
5284
5284
5285 ret = 0
5285 ret = 0
5286 if targetphase is None:
5286 if targetphase is None:
5287 # display
5287 # display
5288 for r in revs:
5288 for r in revs:
5289 ctx = repo[r]
5289 ctx = repo[r]
5290 ui.write(b'%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5290 ui.write(b'%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5291 else:
5291 else:
5292 with repo.lock(), repo.transaction(b"phase") as tr:
5292 with repo.lock(), repo.transaction(b"phase") as tr:
5293 # set phase
5293 # set phase
5294 if not revs:
5294 if not revs:
5295 raise error.InputError(_(b'empty revision set'))
5295 raise error.InputError(_(b'empty revision set'))
5296 nodes = [repo[r].node() for r in revs]
5296 nodes = [repo[r].node() for r in revs]
5297 # moving revision from public to draft may hide them
5297 # moving revision from public to draft may hide them
5298 # We have to check result on an unfiltered repository
5298 # We have to check result on an unfiltered repository
5299 unfi = repo.unfiltered()
5299 unfi = repo.unfiltered()
5300 getphase = unfi._phasecache.phase
5300 getphase = unfi._phasecache.phase
5301 olddata = [getphase(unfi, r) for r in unfi]
5301 olddata = [getphase(unfi, r) for r in unfi]
5302 phases.advanceboundary(repo, tr, targetphase, nodes)
5302 phases.advanceboundary(repo, tr, targetphase, nodes)
5303 if opts[b'force']:
5303 if opts[b'force']:
5304 phases.retractboundary(repo, tr, targetphase, nodes)
5304 phases.retractboundary(repo, tr, targetphase, nodes)
5305 getphase = unfi._phasecache.phase
5305 getphase = unfi._phasecache.phase
5306 newdata = [getphase(unfi, r) for r in unfi]
5306 newdata = [getphase(unfi, r) for r in unfi]
5307 changes = sum(newdata[r] != olddata[r] for r in unfi)
5307 changes = sum(newdata[r] != olddata[r] for r in unfi)
5308 cl = unfi.changelog
5308 cl = unfi.changelog
5309 rejected = [n for n in nodes if newdata[cl.rev(n)] < targetphase]
5309 rejected = [n for n in nodes if newdata[cl.rev(n)] < targetphase]
5310 if rejected:
5310 if rejected:
5311 ui.warn(
5311 ui.warn(
5312 _(
5312 _(
5313 b'cannot move %i changesets to a higher '
5313 b'cannot move %i changesets to a higher '
5314 b'phase, use --force\n'
5314 b'phase, use --force\n'
5315 )
5315 )
5316 % len(rejected)
5316 % len(rejected)
5317 )
5317 )
5318 ret = 1
5318 ret = 1
5319 if changes:
5319 if changes:
5320 msg = _(b'phase changed for %i changesets\n') % changes
5320 msg = _(b'phase changed for %i changesets\n') % changes
5321 if ret:
5321 if ret:
5322 ui.status(msg)
5322 ui.status(msg)
5323 else:
5323 else:
5324 ui.note(msg)
5324 ui.note(msg)
5325 else:
5325 else:
5326 ui.warn(_(b'no phases changed\n'))
5326 ui.warn(_(b'no phases changed\n'))
5327 return ret
5327 return ret
5328
5328
5329
5329
5330 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
5330 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
5331 """Run after a changegroup has been added via pull/unbundle
5331 """Run after a changegroup has been added via pull/unbundle
5332
5332
5333 This takes arguments below:
5333 This takes arguments below:
5334
5334
5335 :modheads: change of heads by pull/unbundle
5335 :modheads: change of heads by pull/unbundle
5336 :optupdate: updating working directory is needed or not
5336 :optupdate: updating working directory is needed or not
5337 :checkout: update destination revision (or None to default destination)
5337 :checkout: update destination revision (or None to default destination)
5338 :brev: a name, which might be a bookmark to be activated after updating
5338 :brev: a name, which might be a bookmark to be activated after updating
5339
5339
5340 return True if update raise any conflict, False otherwise.
5340 return True if update raise any conflict, False otherwise.
5341 """
5341 """
5342 if modheads == 0:
5342 if modheads == 0:
5343 return False
5343 return False
5344 if optupdate:
5344 if optupdate:
5345 try:
5345 try:
5346 return hg.updatetotally(ui, repo, checkout, brev)
5346 return hg.updatetotally(ui, repo, checkout, brev)
5347 except error.UpdateAbort as inst:
5347 except error.UpdateAbort as inst:
5348 msg = _(b"not updating: %s") % stringutil.forcebytestr(inst)
5348 msg = _(b"not updating: %s") % stringutil.forcebytestr(inst)
5349 hint = inst.hint
5349 hint = inst.hint
5350 raise error.UpdateAbort(msg, hint=hint)
5350 raise error.UpdateAbort(msg, hint=hint)
5351 if modheads is not None and modheads > 1:
5351 if modheads is not None and modheads > 1:
5352 currentbranchheads = len(repo.branchheads())
5352 currentbranchheads = len(repo.branchheads())
5353 if currentbranchheads == modheads:
5353 if currentbranchheads == modheads:
5354 ui.status(
5354 ui.status(
5355 _(b"(run 'hg heads' to see heads, 'hg merge' to merge)\n")
5355 _(b"(run 'hg heads' to see heads, 'hg merge' to merge)\n")
5356 )
5356 )
5357 elif currentbranchheads > 1:
5357 elif currentbranchheads > 1:
5358 ui.status(
5358 ui.status(
5359 _(b"(run 'hg heads .' to see heads, 'hg merge' to merge)\n")
5359 _(b"(run 'hg heads .' to see heads, 'hg merge' to merge)\n")
5360 )
5360 )
5361 else:
5361 else:
5362 ui.status(_(b"(run 'hg heads' to see heads)\n"))
5362 ui.status(_(b"(run 'hg heads' to see heads)\n"))
5363 elif not ui.configbool(b'commands', b'update.requiredest'):
5363 elif not ui.configbool(b'commands', b'update.requiredest'):
5364 ui.status(_(b"(run 'hg update' to get a working copy)\n"))
5364 ui.status(_(b"(run 'hg update' to get a working copy)\n"))
5365 return False
5365 return False
5366
5366
5367
5367
5368 @command(
5368 @command(
5369 b'pull',
5369 b'pull',
5370 [
5370 [
5371 (
5371 (
5372 b'u',
5372 b'u',
5373 b'update',
5373 b'update',
5374 None,
5374 None,
5375 _(b'update to new branch head if new descendants were pulled'),
5375 _(b'update to new branch head if new descendants were pulled'),
5376 ),
5376 ),
5377 (
5377 (
5378 b'f',
5378 b'f',
5379 b'force',
5379 b'force',
5380 None,
5380 None,
5381 _(b'run even when remote repository is unrelated'),
5381 _(b'run even when remote repository is unrelated'),
5382 ),
5382 ),
5383 (
5383 (
5384 b'',
5384 b'',
5385 b'confirm',
5385 b'confirm',
5386 None,
5386 None,
5387 _(b'confirm pull before applying changes'),
5387 _(b'confirm pull before applying changes'),
5388 ),
5388 ),
5389 (
5389 (
5390 b'r',
5390 b'r',
5391 b'rev',
5391 b'rev',
5392 [],
5392 [],
5393 _(b'a remote changeset intended to be added'),
5393 _(b'a remote changeset intended to be added'),
5394 _(b'REV'),
5394 _(b'REV'),
5395 ),
5395 ),
5396 (b'B', b'bookmark', [], _(b"bookmark to pull"), _(b'BOOKMARK')),
5396 (b'B', b'bookmark', [], _(b"bookmark to pull"), _(b'BOOKMARK')),
5397 (
5397 (
5398 b'b',
5398 b'b',
5399 b'branch',
5399 b'branch',
5400 [],
5400 [],
5401 _(b'a specific branch you would like to pull'),
5401 _(b'a specific branch you would like to pull'),
5402 _(b'BRANCH'),
5402 _(b'BRANCH'),
5403 ),
5403 ),
5404 (
5404 (
5405 b'',
5405 b'',
5406 b'remote-hidden',
5406 b'remote-hidden',
5407 False,
5407 False,
5408 _(b"include changesets hidden on the remote (EXPERIMENTAL)"),
5408 _(b"include changesets hidden on the remote (EXPERIMENTAL)"),
5409 ),
5409 ),
5410 ]
5410 ]
5411 + remoteopts,
5411 + remoteopts,
5412 _(b'[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]...'),
5412 _(b'[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]...'),
5413 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5413 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5414 helpbasic=True,
5414 helpbasic=True,
5415 )
5415 )
5416 def pull(ui, repo, *sources, **opts):
5416 def pull(ui, repo, *sources, **opts):
5417 """pull changes from the specified source
5417 """pull changes from the specified source
5418
5418
5419 Pull changes from a remote repository to a local one.
5419 Pull changes from a remote repository to a local one.
5420
5420
5421 This finds all changes from the repository at the specified path
5421 This finds all changes from the repository at the specified path
5422 or URL and adds them to a local repository (the current one unless
5422 or URL and adds them to a local repository (the current one unless
5423 -R is specified). By default, this does not update the copy of the
5423 -R is specified). By default, this does not update the copy of the
5424 project in the working directory.
5424 project in the working directory.
5425
5425
5426 When cloning from servers that support it, Mercurial may fetch
5426 When cloning from servers that support it, Mercurial may fetch
5427 pre-generated data. When this is done, hooks operating on incoming
5427 pre-generated data. When this is done, hooks operating on incoming
5428 changesets and changegroups may fire more than once, once for each
5428 changesets and changegroups may fire more than once, once for each
5429 pre-generated bundle and as well as for any additional remaining
5429 pre-generated bundle and as well as for any additional remaining
5430 data. See :hg:`help -e clonebundles` for more.
5430 data. See :hg:`help -e clonebundles` for more.
5431
5431
5432 Use :hg:`incoming` if you want to see what would have been added
5432 Use :hg:`incoming` if you want to see what would have been added
5433 by a pull at the time you issued this command. If you then decide
5433 by a pull at the time you issued this command. If you then decide
5434 to add those changes to the repository, you should use :hg:`pull
5434 to add those changes to the repository, you should use :hg:`pull
5435 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5435 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5436
5436
5437 If SOURCE is omitted, the 'default' path will be used.
5437 If SOURCE is omitted, the 'default' path will be used.
5438 See :hg:`help urls` for more information.
5438 See :hg:`help urls` for more information.
5439
5439
5440 If multiple sources are specified, they will be pulled sequentially as if
5440 If multiple sources are specified, they will be pulled sequentially as if
5441 the command was run multiple time. If --update is specify and the command
5441 the command was run multiple time. If --update is specify and the command
5442 will stop at the first failed --update.
5442 will stop at the first failed --update.
5443
5443
5444 Specifying bookmark as ``.`` is equivalent to specifying the active
5444 Specifying bookmark as ``.`` is equivalent to specifying the active
5445 bookmark's name.
5445 bookmark's name.
5446
5446
5447 .. container:: verbose
5447 .. container:: verbose
5448
5448
5449 One can use the `--remote-hidden` flag to pull changesets
5449 One can use the `--remote-hidden` flag to pull changesets
5450 hidden on the remote. This flag is "best effort", and will only
5450 hidden on the remote. This flag is "best effort", and will only
5451 work if the server supports the feature and is configured to
5451 work if the server supports the feature and is configured to
5452 allow the user to access hidden changesets. This option is
5452 allow the user to access hidden changesets. This option is
5453 experimental and backwards compatibility is not garanteed.
5453 experimental and backwards compatibility is not garanteed.
5454
5454
5455 Returns 0 on success, 1 if an update had unresolved files.
5455 Returns 0 on success, 1 if an update had unresolved files.
5456 """
5456 """
5457
5457
5458 if ui.configbool(b'commands', b'update.requiredest') and opts.get('update'):
5458 if ui.configbool(b'commands', b'update.requiredest') and opts.get('update'):
5459 msg = _(b'update destination required by configuration')
5459 msg = _(b'update destination required by configuration')
5460 hint = _(b'use hg pull followed by hg update DEST')
5460 hint = _(b'use hg pull followed by hg update DEST')
5461 raise error.InputError(msg, hint=hint)
5461 raise error.InputError(msg, hint=hint)
5462
5462
5463 update_conflict = None
5463 update_conflict = None
5464
5464
5465 for path in urlutil.get_pull_paths(repo, ui, sources):
5465 for path in urlutil.get_pull_paths(repo, ui, sources):
5466 ui.status(_(b'pulling from %s\n') % urlutil.hidepassword(path.loc))
5466 ui.status(_(b'pulling from %s\n') % urlutil.hidepassword(path.loc))
5467 ui.flush()
5467 ui.flush()
5468 other = hg.peer(
5468 other = hg.peer(
5469 repo,
5469 repo,
5470 pycompat.byteskwargs(opts),
5470 pycompat.byteskwargs(opts),
5471 path,
5471 path,
5472 remotehidden=opts['remote_hidden'],
5472 remotehidden=opts['remote_hidden'],
5473 )
5473 )
5474 update_conflict = None
5474 update_conflict = None
5475 try:
5475 try:
5476 branches = (path.branch, opts.get('branch', []))
5476 branches = (path.branch, opts.get('branch', []))
5477 revs, checkout = hg.addbranchrevs(
5477 revs, checkout = hg.addbranchrevs(
5478 repo,
5478 repo,
5479 other,
5479 other,
5480 branches,
5480 branches,
5481 opts.get('rev'),
5481 opts.get('rev'),
5482 remotehidden=opts['remote_hidden'],
5482 remotehidden=opts['remote_hidden'],
5483 )
5483 )
5484
5484
5485 pullopargs = {}
5485 pullopargs = {}
5486
5486
5487 nodes = None
5487 nodes = None
5488 if opts.get('bookmark') or revs:
5488 if opts.get('bookmark') or revs:
5489 # The list of bookmark used here is the same used to actually update
5489 # The list of bookmark used here is the same used to actually update
5490 # the bookmark names, to avoid the race from issue 4689 and we do
5490 # the bookmark names, to avoid the race from issue 4689 and we do
5491 # all lookup and bookmark queries in one go so they see the same
5491 # all lookup and bookmark queries in one go so they see the same
5492 # version of the server state (issue 4700).
5492 # version of the server state (issue 4700).
5493 nodes = []
5493 nodes = []
5494 fnodes = []
5494 fnodes = []
5495 revs = revs or []
5495 revs = revs or []
5496 if revs and not other.capable(b'lookup'):
5496 if revs and not other.capable(b'lookup'):
5497 err = _(
5497 err = _(
5498 b"other repository doesn't support revision lookup, "
5498 b"other repository doesn't support revision lookup, "
5499 b"so a rev cannot be specified."
5499 b"so a rev cannot be specified."
5500 )
5500 )
5501 raise error.Abort(err)
5501 raise error.Abort(err)
5502 with other.commandexecutor() as e:
5502 with other.commandexecutor() as e:
5503 fremotebookmarks = e.callcommand(
5503 fremotebookmarks = e.callcommand(
5504 b'listkeys', {b'namespace': b'bookmarks'}
5504 b'listkeys', {b'namespace': b'bookmarks'}
5505 )
5505 )
5506 for r in revs:
5506 for r in revs:
5507 fnodes.append(e.callcommand(b'lookup', {b'key': r}))
5507 fnodes.append(e.callcommand(b'lookup', {b'key': r}))
5508 remotebookmarks = fremotebookmarks.result()
5508 remotebookmarks = fremotebookmarks.result()
5509 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
5509 remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
5510 pullopargs[b'remotebookmarks'] = remotebookmarks
5510 pullopargs[b'remotebookmarks'] = remotebookmarks
5511 for b in opts.get('bookmark', []):
5511 for b in opts.get('bookmark', []):
5512 b = repo._bookmarks.expandname(b)
5512 b = repo._bookmarks.expandname(b)
5513 if b not in remotebookmarks:
5513 if b not in remotebookmarks:
5514 raise error.InputError(
5514 raise error.InputError(
5515 _(b'remote bookmark %s not found!') % b
5515 _(b'remote bookmark %s not found!') % b
5516 )
5516 )
5517 nodes.append(remotebookmarks[b])
5517 nodes.append(remotebookmarks[b])
5518 for i, rev in enumerate(revs):
5518 for i, rev in enumerate(revs):
5519 node = fnodes[i].result()
5519 node = fnodes[i].result()
5520 nodes.append(node)
5520 nodes.append(node)
5521 if rev == checkout:
5521 if rev == checkout:
5522 checkout = node
5522 checkout = node
5523
5523
5524 wlock = util.nullcontextmanager()
5524 wlock = util.nullcontextmanager()
5525 if opts.get('update'):
5525 if opts.get('update'):
5526 wlock = repo.wlock()
5526 wlock = repo.wlock()
5527 with wlock:
5527 with wlock:
5528 pullopargs.update(opts.get('opargs', {}))
5528 pullopargs.update(opts.get('opargs', {}))
5529 modheads = exchange.pull(
5529 modheads = exchange.pull(
5530 repo,
5530 repo,
5531 other,
5531 other,
5532 path=path,
5532 path=path,
5533 heads=nodes,
5533 heads=nodes,
5534 force=opts.get('force'),
5534 force=opts.get('force'),
5535 bookmarks=opts.get('bookmark', ()),
5535 bookmarks=opts.get('bookmark', ()),
5536 opargs=pullopargs,
5536 opargs=pullopargs,
5537 confirm=opts.get('confirm'),
5537 confirm=opts.get('confirm'),
5538 ).cgresult
5538 ).cgresult
5539
5539
5540 # brev is a name, which might be a bookmark to be activated at
5540 # brev is a name, which might be a bookmark to be activated at
5541 # the end of the update. In other words, it is an explicit
5541 # the end of the update. In other words, it is an explicit
5542 # destination of the update
5542 # destination of the update
5543 brev = None
5543 brev = None
5544
5544
5545 if checkout:
5545 if checkout:
5546 checkout = repo.unfiltered().changelog.rev(checkout)
5546 checkout = repo.unfiltered().changelog.rev(checkout)
5547
5547
5548 # order below depends on implementation of
5548 # order below depends on implementation of
5549 # hg.addbranchrevs(). opts['bookmark'] is ignored,
5549 # hg.addbranchrevs(). opts['bookmark'] is ignored,
5550 # because 'checkout' is determined without it.
5550 # because 'checkout' is determined without it.
5551 if opts.get('rev'):
5551 if opts.get('rev'):
5552 brev = opts['rev'][0]
5552 brev = opts['rev'][0]
5553 elif opts.get('branch'):
5553 elif opts.get('branch'):
5554 brev = opts['branch'][0]
5554 brev = opts['branch'][0]
5555 else:
5555 else:
5556 brev = path.branch
5556 brev = path.branch
5557
5557
5558 # XXX path: we are losing the `path` object here. Keeping it
5558 # XXX path: we are losing the `path` object here. Keeping it
5559 # would be valuable. For example as a "variant" as we do
5559 # would be valuable. For example as a "variant" as we do
5560 # for pushes.
5560 # for pushes.
5561 repo._subtoppath = path.loc
5561 repo._subtoppath = path.loc
5562 try:
5562 try:
5563 update_conflict = postincoming(
5563 update_conflict = postincoming(
5564 ui, repo, modheads, opts.get('update'), checkout, brev
5564 ui, repo, modheads, opts.get('update'), checkout, brev
5565 )
5565 )
5566 except error.FilteredRepoLookupError as exc:
5566 except error.FilteredRepoLookupError as exc:
5567 msg = _(b'cannot update to target: %s') % exc.args[0]
5567 msg = _(b'cannot update to target: %s') % exc.args[0]
5568 exc.args = (msg,) + exc.args[1:]
5568 exc.args = (msg,) + exc.args[1:]
5569 raise
5569 raise
5570 finally:
5570 finally:
5571 del repo._subtoppath
5571 del repo._subtoppath
5572
5572
5573 finally:
5573 finally:
5574 other.close()
5574 other.close()
5575 # skip the remaining pull source if they are some conflict.
5575 # skip the remaining pull source if they are some conflict.
5576 if update_conflict:
5576 if update_conflict:
5577 break
5577 break
5578 if update_conflict:
5578 if update_conflict:
5579 return 1
5579 return 1
5580 else:
5580 else:
5581 return 0
5581 return 0
5582
5582
5583
5583
5584 @command(
5584 @command(
5585 b'purge|clean',
5585 b'purge|clean',
5586 [
5586 [
5587 (b'a', b'abort-on-err', None, _(b'abort if an error occurs')),
5587 (b'a', b'abort-on-err', None, _(b'abort if an error occurs')),
5588 (b'', b'all', None, _(b'purge ignored files too')),
5588 (b'', b'all', None, _(b'purge ignored files too')),
5589 (b'i', b'ignored', None, _(b'purge only ignored files')),
5589 (b'i', b'ignored', None, _(b'purge only ignored files')),
5590 (b'', b'dirs', None, _(b'purge empty directories')),
5590 (b'', b'dirs', None, _(b'purge empty directories')),
5591 (b'', b'files', None, _(b'purge files')),
5591 (b'', b'files', None, _(b'purge files')),
5592 (b'p', b'print', None, _(b'print filenames instead of deleting them')),
5592 (b'p', b'print', None, _(b'print filenames instead of deleting them')),
5593 (
5593 (
5594 b'0',
5594 b'0',
5595 b'print0',
5595 b'print0',
5596 None,
5596 None,
5597 _(
5597 _(
5598 b'end filenames with NUL, for use with xargs'
5598 b'end filenames with NUL, for use with xargs'
5599 b' (implies -p/--print)'
5599 b' (implies -p/--print)'
5600 ),
5600 ),
5601 ),
5601 ),
5602 (b'', b'confirm', None, _(b'ask before permanently deleting files')),
5602 (b'', b'confirm', None, _(b'ask before permanently deleting files')),
5603 ]
5603 ]
5604 + cmdutil.walkopts,
5604 + cmdutil.walkopts,
5605 _(b'hg purge [OPTION]... [DIR]...'),
5605 _(b'hg purge [OPTION]... [DIR]...'),
5606 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5606 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5607 )
5607 )
5608 def purge(ui, repo, *dirs, **opts):
5608 def purge(ui, repo, *dirs, **opts):
5609 """removes files not tracked by Mercurial
5609 """removes files not tracked by Mercurial
5610
5610
5611 Delete files not known to Mercurial. This is useful to test local
5611 Delete files not known to Mercurial. This is useful to test local
5612 and uncommitted changes in an otherwise-clean source tree.
5612 and uncommitted changes in an otherwise-clean source tree.
5613
5613
5614 This means that purge will delete the following by default:
5614 This means that purge will delete the following by default:
5615
5615
5616 - Unknown files: files marked with "?" by :hg:`status`
5616 - Unknown files: files marked with "?" by :hg:`status`
5617 - Empty directories: in fact Mercurial ignores directories unless
5617 - Empty directories: in fact Mercurial ignores directories unless
5618 they contain files under source control management
5618 they contain files under source control management
5619
5619
5620 But it will leave untouched:
5620 But it will leave untouched:
5621
5621
5622 - Modified and unmodified tracked files
5622 - Modified and unmodified tracked files
5623 - Ignored files (unless -i or --all is specified)
5623 - Ignored files (unless -i or --all is specified)
5624 - New files added to the repository (with :hg:`add`)
5624 - New files added to the repository (with :hg:`add`)
5625
5625
5626 The --files and --dirs options can be used to direct purge to delete
5626 The --files and --dirs options can be used to direct purge to delete
5627 only files, only directories, or both. If neither option is given,
5627 only files, only directories, or both. If neither option is given,
5628 both will be deleted.
5628 both will be deleted.
5629
5629
5630 If directories are given on the command line, only files in these
5630 If directories are given on the command line, only files in these
5631 directories are considered.
5631 directories are considered.
5632
5632
5633 Be careful with purge, as you could irreversibly delete some files
5633 Be careful with purge, as you could irreversibly delete some files
5634 you forgot to add to the repository. If you only want to print the
5634 you forgot to add to the repository. If you only want to print the
5635 list of files that this program would delete, use the --print
5635 list of files that this program would delete, use the --print
5636 option.
5636 option.
5637 """
5637 """
5638 cmdutil.check_at_most_one_arg(opts, 'all', 'ignored')
5638 cmdutil.check_at_most_one_arg(opts, 'all', 'ignored')
5639
5639
5640 act = not opts.get('print')
5640 act = not opts.get('print')
5641 eol = b'\n'
5641 eol = b'\n'
5642 if opts.get('print0'):
5642 if opts.get('print0'):
5643 eol = b'\0'
5643 eol = b'\0'
5644 act = False # --print0 implies --print
5644 act = False # --print0 implies --print
5645 if opts.get('all', False):
5645 if opts.get('all', False):
5646 ignored = True
5646 ignored = True
5647 unknown = True
5647 unknown = True
5648 else:
5648 else:
5649 ignored = opts.get('ignored', False)
5649 ignored = opts.get('ignored', False)
5650 unknown = not ignored
5650 unknown = not ignored
5651
5651
5652 removefiles = opts.get('files')
5652 removefiles = opts.get('files')
5653 removedirs = opts.get('dirs')
5653 removedirs = opts.get('dirs')
5654 confirm = opts.get('confirm')
5654 confirm = opts.get('confirm')
5655 if confirm is None:
5655 if confirm is None:
5656 try:
5656 try:
5657 extensions.find(b'purge')
5657 extensions.find(b'purge')
5658 confirm = False
5658 confirm = False
5659 except KeyError:
5659 except KeyError:
5660 confirm = True
5660 confirm = True
5661
5661
5662 if not removefiles and not removedirs:
5662 if not removefiles and not removedirs:
5663 removefiles = True
5663 removefiles = True
5664 removedirs = True
5664 removedirs = True
5665
5665
5666 match = scmutil.match(repo[None], dirs, pycompat.byteskwargs(opts))
5666 match = scmutil.match(repo[None], dirs, pycompat.byteskwargs(opts))
5667
5667
5668 paths = mergemod.purge(
5668 paths = mergemod.purge(
5669 repo,
5669 repo,
5670 match,
5670 match,
5671 unknown=unknown,
5671 unknown=unknown,
5672 ignored=ignored,
5672 ignored=ignored,
5673 removeemptydirs=removedirs,
5673 removeemptydirs=removedirs,
5674 removefiles=removefiles,
5674 removefiles=removefiles,
5675 abortonerror=opts.get('abort_on_err'),
5675 abortonerror=opts.get('abort_on_err'),
5676 noop=not act,
5676 noop=not act,
5677 confirm=confirm,
5677 confirm=confirm,
5678 )
5678 )
5679
5679
5680 for path in paths:
5680 for path in paths:
5681 if not act:
5681 if not act:
5682 ui.write(b'%s%s' % (path, eol))
5682 ui.write(b'%s%s' % (path, eol))
5683
5683
5684
5684
5685 @command(
5685 @command(
5686 b'push',
5686 b'push',
5687 [
5687 [
5688 (b'f', b'force', None, _(b'force push')),
5688 (b'f', b'force', None, _(b'force push')),
5689 (
5689 (
5690 b'r',
5690 b'r',
5691 b'rev',
5691 b'rev',
5692 [],
5692 [],
5693 _(b'a changeset intended to be included in the destination'),
5693 _(b'a changeset intended to be included in the destination'),
5694 _(b'REV'),
5694 _(b'REV'),
5695 ),
5695 ),
5696 (b'B', b'bookmark', [], _(b"bookmark to push"), _(b'BOOKMARK')),
5696 (b'B', b'bookmark', [], _(b"bookmark to push"), _(b'BOOKMARK')),
5697 (b'', b'all-bookmarks', None, _(b"push all bookmarks (EXPERIMENTAL)")),
5697 (b'', b'all-bookmarks', None, _(b"push all bookmarks (EXPERIMENTAL)")),
5698 (
5698 (
5699 b'b',
5699 b'b',
5700 b'branch',
5700 b'branch',
5701 [],
5701 [],
5702 _(b'a specific branch you would like to push'),
5702 _(b'a specific branch you would like to push'),
5703 _(b'BRANCH'),
5703 _(b'BRANCH'),
5704 ),
5704 ),
5705 (b'', b'new-branch', False, _(b'allow pushing a new branch')),
5705 (b'', b'new-branch', False, _(b'allow pushing a new branch')),
5706 (
5706 (
5707 b'',
5707 b'',
5708 b'pushvars',
5708 b'pushvars',
5709 [],
5709 [],
5710 _(b'variables that can be sent to server (ADVANCED)'),
5710 _(b'variables that can be sent to server (ADVANCED)'),
5711 ),
5711 ),
5712 (
5712 (
5713 b'',
5713 b'',
5714 b'publish',
5714 b'publish',
5715 False,
5715 False,
5716 _(b'push the changeset as public (EXPERIMENTAL)'),
5716 _(b'push the changeset as public (EXPERIMENTAL)'),
5717 ),
5717 ),
5718 ]
5718 ]
5719 + remoteopts,
5719 + remoteopts,
5720 _(b'[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]...'),
5720 _(b'[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]...'),
5721 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5721 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
5722 helpbasic=True,
5722 helpbasic=True,
5723 )
5723 )
5724 def push(ui, repo, *dests, **opts):
5724 def push(ui, repo, *dests, **opts):
5725 """push changes to the specified destination
5725 """push changes to the specified destination
5726
5726
5727 Push changesets from the local repository to the specified
5727 Push changesets from the local repository to the specified
5728 destination.
5728 destination.
5729
5729
5730 This operation is symmetrical to pull: it is identical to a pull
5730 This operation is symmetrical to pull: it is identical to a pull
5731 in the destination repository from the current one.
5731 in the destination repository from the current one.
5732
5732
5733 By default, push will not allow creation of new heads at the
5733 By default, push will not allow creation of new heads at the
5734 destination, since multiple heads would make it unclear which head
5734 destination, since multiple heads would make it unclear which head
5735 to use. In this situation, it is recommended to pull and merge
5735 to use. In this situation, it is recommended to pull and merge
5736 before pushing.
5736 before pushing.
5737
5737
5738 Use --new-branch if you want to allow push to create a new named
5738 Use --new-branch if you want to allow push to create a new named
5739 branch that is not present at the destination. This allows you to
5739 branch that is not present at the destination. This allows you to
5740 only create a new branch without forcing other changes.
5740 only create a new branch without forcing other changes.
5741
5741
5742 .. note::
5742 .. note::
5743
5743
5744 Extra care should be taken with the -f/--force option,
5744 Extra care should be taken with the -f/--force option,
5745 which will push all new heads on all branches, an action which will
5745 which will push all new heads on all branches, an action which will
5746 almost always cause confusion for collaborators.
5746 almost always cause confusion for collaborators.
5747
5747
5748 If -r/--rev is used, the specified revision and all its ancestors
5748 If -r/--rev is used, the specified revision and all its ancestors
5749 will be pushed to the remote repository.
5749 will be pushed to the remote repository.
5750
5750
5751 If -B/--bookmark is used, the specified bookmarked revision, its
5751 If -B/--bookmark is used, the specified bookmarked revision, its
5752 ancestors, and the bookmark will be pushed to the remote
5752 ancestors, and the bookmark will be pushed to the remote
5753 repository. Specifying ``.`` is equivalent to specifying the active
5753 repository. Specifying ``.`` is equivalent to specifying the active
5754 bookmark's name. Use the --all-bookmarks option for pushing all
5754 bookmark's name. Use the --all-bookmarks option for pushing all
5755 current bookmarks.
5755 current bookmarks.
5756
5756
5757 Please see :hg:`help urls` for important details about ``ssh://``
5757 Please see :hg:`help urls` for important details about ``ssh://``
5758 URLs. If DESTINATION is omitted, a default path will be used.
5758 URLs. If DESTINATION is omitted, a default path will be used.
5759
5759
5760 When passed multiple destinations, push will process them one after the
5760 When passed multiple destinations, push will process them one after the
5761 other, but stop should an error occur.
5761 other, but stop should an error occur.
5762
5762
5763 .. container:: verbose
5763 .. container:: verbose
5764
5764
5765 The --pushvars option sends strings to the server that become
5765 The --pushvars option sends strings to the server that become
5766 environment variables prepended with ``HG_USERVAR_``. For example,
5766 environment variables prepended with ``HG_USERVAR_``. For example,
5767 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
5767 ``--pushvars ENABLE_FEATURE=true``, provides the server side hooks with
5768 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
5768 ``HG_USERVAR_ENABLE_FEATURE=true`` as part of their environment.
5769
5769
5770 pushvars can provide for user-overridable hooks as well as set debug
5770 pushvars can provide for user-overridable hooks as well as set debug
5771 levels. One example is having a hook that blocks commits containing
5771 levels. One example is having a hook that blocks commits containing
5772 conflict markers, but enables the user to override the hook if the file
5772 conflict markers, but enables the user to override the hook if the file
5773 is using conflict markers for testing purposes or the file format has
5773 is using conflict markers for testing purposes or the file format has
5774 strings that look like conflict markers.
5774 strings that look like conflict markers.
5775
5775
5776 By default, servers will ignore `--pushvars`. To enable it add the
5776 By default, servers will ignore `--pushvars`. To enable it add the
5777 following to your configuration file::
5777 following to your configuration file::
5778
5778
5779 [push]
5779 [push]
5780 pushvars.server = true
5780 pushvars.server = true
5781
5781
5782 Returns 0 if push was successful, 1 if nothing to push.
5782 Returns 0 if push was successful, 1 if nothing to push.
5783 """
5783 """
5784
5784
5785 opts = pycompat.byteskwargs(opts)
5785 opts = pycompat.byteskwargs(opts)
5786
5786
5787 if opts.get(b'all_bookmarks'):
5787 if opts.get(b'all_bookmarks'):
5788 cmdutil.check_incompatible_arguments(
5788 cmdutil.check_incompatible_arguments(
5789 opts,
5789 opts,
5790 b'all_bookmarks',
5790 b'all_bookmarks',
5791 [b'bookmark', b'rev'],
5791 [b'bookmark', b'rev'],
5792 )
5792 )
5793 opts[b'bookmark'] = list(repo._bookmarks)
5793 opts[b'bookmark'] = list(repo._bookmarks)
5794
5794
5795 if opts.get(b'bookmark'):
5795 if opts.get(b'bookmark'):
5796 ui.setconfig(b'bookmarks', b'pushing', opts[b'bookmark'], b'push')
5796 ui.setconfig(b'bookmarks', b'pushing', opts[b'bookmark'], b'push')
5797 for b in opts[b'bookmark']:
5797 for b in opts[b'bookmark']:
5798 # translate -B options to -r so changesets get pushed
5798 # translate -B options to -r so changesets get pushed
5799 b = repo._bookmarks.expandname(b)
5799 b = repo._bookmarks.expandname(b)
5800 if b in repo._bookmarks:
5800 if b in repo._bookmarks:
5801 opts.setdefault(b'rev', []).append(b)
5801 opts.setdefault(b'rev', []).append(b)
5802 else:
5802 else:
5803 # if we try to push a deleted bookmark, translate it to null
5803 # if we try to push a deleted bookmark, translate it to null
5804 # this lets simultaneous -r, -b options continue working
5804 # this lets simultaneous -r, -b options continue working
5805 opts.setdefault(b'rev', []).append(b"null")
5805 opts.setdefault(b'rev', []).append(b"null")
5806
5806
5807 some_pushed = False
5807 some_pushed = False
5808 result = 0
5808 result = 0
5809 for path in urlutil.get_push_paths(repo, ui, dests):
5809 for path in urlutil.get_push_paths(repo, ui, dests):
5810 dest = path.loc
5810 dest = path.loc
5811 branches = (path.branch, opts.get(b'branch') or [])
5811 branches = (path.branch, opts.get(b'branch') or [])
5812 ui.status(_(b'pushing to %s\n') % urlutil.hidepassword(dest))
5812 ui.status(_(b'pushing to %s\n') % urlutil.hidepassword(dest))
5813 revs, checkout = hg.addbranchrevs(
5813 revs, checkout = hg.addbranchrevs(
5814 repo, repo, branches, opts.get(b'rev')
5814 repo, repo, branches, opts.get(b'rev')
5815 )
5815 )
5816 other = hg.peer(repo, opts, dest)
5816 other = hg.peer(repo, opts, dest)
5817
5817
5818 try:
5818 try:
5819 if revs:
5819 if revs:
5820 revs = [repo[r].node() for r in logcmdutil.revrange(repo, revs)]
5820 revs = [repo[r].node() for r in logcmdutil.revrange(repo, revs)]
5821 if not revs:
5821 if not revs:
5822 raise error.InputError(
5822 raise error.InputError(
5823 _(b"specified revisions evaluate to an empty set"),
5823 _(b"specified revisions evaluate to an empty set"),
5824 hint=_(b"use different revision arguments"),
5824 hint=_(b"use different revision arguments"),
5825 )
5825 )
5826 elif path.pushrev:
5826 elif path.pushrev:
5827 # It doesn't make any sense to specify ancestor revisions. So limit
5827 # It doesn't make any sense to specify ancestor revisions. So limit
5828 # to DAG heads to make discovery simpler.
5828 # to DAG heads to make discovery simpler.
5829 expr = revsetlang.formatspec(b'heads(%r)', path.pushrev)
5829 expr = revsetlang.formatspec(b'heads(%r)', path.pushrev)
5830 revs = scmutil.revrange(repo, [expr])
5830 revs = scmutil.revrange(repo, [expr])
5831 revs = [repo[rev].node() for rev in revs]
5831 revs = [repo[rev].node() for rev in revs]
5832 if not revs:
5832 if not revs:
5833 raise error.InputError(
5833 raise error.InputError(
5834 _(
5834 _(
5835 b'default push revset for path evaluates to an empty set'
5835 b'default push revset for path evaluates to an empty set'
5836 )
5836 )
5837 )
5837 )
5838 elif ui.configbool(b'commands', b'push.require-revs'):
5838 elif ui.configbool(b'commands', b'push.require-revs'):
5839 raise error.InputError(
5839 raise error.InputError(
5840 _(b'no revisions specified to push'),
5840 _(b'no revisions specified to push'),
5841 hint=_(b'did you mean "hg push -r ."?'),
5841 hint=_(b'did you mean "hg push -r ."?'),
5842 )
5842 )
5843
5843
5844 repo._subtoppath = dest
5844 repo._subtoppath = dest
5845 try:
5845 try:
5846 # push subrepos depth-first for coherent ordering
5846 # push subrepos depth-first for coherent ordering
5847 c = repo[b'.']
5847 c = repo[b'.']
5848 subs = c.substate # only repos that are committed
5848 subs = c.substate # only repos that are committed
5849 for s in sorted(subs):
5849 for s in sorted(subs):
5850 sub_result = c.sub(s).push(opts)
5850 sub_result = c.sub(s).push(opts)
5851 if sub_result == 0:
5851 if sub_result == 0:
5852 return 1
5852 return 1
5853 finally:
5853 finally:
5854 del repo._subtoppath
5854 del repo._subtoppath
5855
5855
5856 opargs = dict(
5856 opargs = dict(
5857 opts.get(b'opargs', {})
5857 opts.get(b'opargs', {})
5858 ) # copy opargs since we may mutate it
5858 ) # copy opargs since we may mutate it
5859 opargs.setdefault(b'pushvars', []).extend(opts.get(b'pushvars', []))
5859 opargs.setdefault(b'pushvars', []).extend(opts.get(b'pushvars', []))
5860
5860
5861 pushop = exchange.push(
5861 pushop = exchange.push(
5862 repo,
5862 repo,
5863 other,
5863 other,
5864 opts.get(b'force'),
5864 opts.get(b'force'),
5865 revs=revs,
5865 revs=revs,
5866 newbranch=opts.get(b'new_branch'),
5866 newbranch=opts.get(b'new_branch'),
5867 bookmarks=opts.get(b'bookmark', ()),
5867 bookmarks=opts.get(b'bookmark', ()),
5868 publish=opts.get(b'publish'),
5868 publish=opts.get(b'publish'),
5869 opargs=opargs,
5869 opargs=opargs,
5870 )
5870 )
5871
5871
5872 if pushop.cgresult == 0:
5872 if pushop.cgresult == 0:
5873 result = 1
5873 result = 1
5874 elif pushop.cgresult is not None:
5874 elif pushop.cgresult is not None:
5875 some_pushed = True
5875 some_pushed = True
5876
5876
5877 if pushop.bkresult is not None:
5877 if pushop.bkresult is not None:
5878 if pushop.bkresult == 2:
5878 if pushop.bkresult == 2:
5879 result = 2
5879 result = 2
5880 elif not result and pushop.bkresult:
5880 elif not result and pushop.bkresult:
5881 result = 2
5881 result = 2
5882
5882
5883 if result:
5883 if result:
5884 break
5884 break
5885
5885
5886 finally:
5886 finally:
5887 other.close()
5887 other.close()
5888 if result == 0 and not some_pushed:
5888 if result == 0 and not some_pushed:
5889 result = 1
5889 result = 1
5890 return result
5890 return result
5891
5891
5892
5892
5893 @command(
5893 @command(
5894 b'recover',
5894 b'recover',
5895 [
5895 [
5896 (b'', b'verify', False, b"run `hg verify` after successful recover"),
5896 (b'', b'verify', False, b"run `hg verify` after successful recover"),
5897 ],
5897 ],
5898 helpcategory=command.CATEGORY_MAINTENANCE,
5898 helpcategory=command.CATEGORY_MAINTENANCE,
5899 )
5899 )
5900 def recover(ui, repo, **opts):
5900 def recover(ui, repo, **opts):
5901 """roll back an interrupted transaction
5901 """roll back an interrupted transaction
5902
5902
5903 Recover from an interrupted commit or pull.
5903 Recover from an interrupted commit or pull.
5904
5904
5905 This command tries to fix the repository status after an
5905 This command tries to fix the repository status after an
5906 interrupted operation. It should only be necessary when Mercurial
5906 interrupted operation. It should only be necessary when Mercurial
5907 suggests it.
5907 suggests it.
5908
5908
5909 Returns 0 if successful, 1 if nothing to recover or verify fails.
5909 Returns 0 if successful, 1 if nothing to recover or verify fails.
5910 """
5910 """
5911 ret = repo.recover()
5911 ret = repo.recover()
5912 if ret:
5912 if ret:
5913 if opts['verify']:
5913 if opts['verify']:
5914 return hg.verify(repo)
5914 return hg.verify(repo)
5915 else:
5915 else:
5916 msg = _(
5916 msg = _(
5917 b"(verify step skipped, run `hg verify` to check your "
5917 b"(verify step skipped, run `hg verify` to check your "
5918 b"repository content)\n"
5918 b"repository content)\n"
5919 )
5919 )
5920 ui.warn(msg)
5920 ui.warn(msg)
5921 return 0
5921 return 0
5922 return 1
5922 return 1
5923
5923
5924
5924
5925 @command(
5925 @command(
5926 b'remove|rm',
5926 b'remove|rm',
5927 [
5927 [
5928 (b'A', b'after', None, _(b'record delete for missing files')),
5928 (b'A', b'after', None, _(b'record delete for missing files')),
5929 (b'f', b'force', None, _(b'forget added files, delete modified files')),
5929 (b'f', b'force', None, _(b'forget added files, delete modified files')),
5930 ]
5930 ]
5931 + subrepoopts
5931 + subrepoopts
5932 + walkopts
5932 + walkopts
5933 + dryrunopts,
5933 + dryrunopts,
5934 _(b'[OPTION]... FILE...'),
5934 _(b'[OPTION]... FILE...'),
5935 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5935 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
5936 helpbasic=True,
5936 helpbasic=True,
5937 inferrepo=True,
5937 inferrepo=True,
5938 )
5938 )
5939 def remove(ui, repo, *pats, **opts):
5939 def remove(ui, repo, *pats, **opts):
5940 """remove the specified files on the next commit
5940 """remove the specified files on the next commit
5941
5941
5942 Schedule the indicated files for removal from the current branch.
5942 Schedule the indicated files for removal from the current branch.
5943
5943
5944 This command schedules the files to be removed at the next commit.
5944 This command schedules the files to be removed at the next commit.
5945 To undo a remove before that, see :hg:`revert`. To undo added
5945 To undo a remove before that, see :hg:`revert`. To undo added
5946 files, see :hg:`forget`.
5946 files, see :hg:`forget`.
5947
5947
5948 .. container:: verbose
5948 .. container:: verbose
5949
5949
5950 -A/--after can be used to remove only files that have already
5950 -A/--after can be used to remove only files that have already
5951 been deleted, -f/--force can be used to force deletion, and -Af
5951 been deleted, -f/--force can be used to force deletion, and -Af
5952 can be used to remove files from the next revision without
5952 can be used to remove files from the next revision without
5953 deleting them from the working directory.
5953 deleting them from the working directory.
5954
5954
5955 The following table details the behavior of remove for different
5955 The following table details the behavior of remove for different
5956 file states (columns) and option combinations (rows). The file
5956 file states (columns) and option combinations (rows). The file
5957 states are Added [A], Clean [C], Modified [M] and Missing [!]
5957 states are Added [A], Clean [C], Modified [M] and Missing [!]
5958 (as reported by :hg:`status`). The actions are Warn, Remove
5958 (as reported by :hg:`status`). The actions are Warn, Remove
5959 (from branch) and Delete (from disk):
5959 (from branch) and Delete (from disk):
5960
5960
5961 ========= == == == ==
5961 ========= == == == ==
5962 opt/state A C M !
5962 opt/state A C M !
5963 ========= == == == ==
5963 ========= == == == ==
5964 none W RD W R
5964 none W RD W R
5965 -f R RD RD R
5965 -f R RD RD R
5966 -A W W W R
5966 -A W W W R
5967 -Af R R R R
5967 -Af R R R R
5968 ========= == == == ==
5968 ========= == == == ==
5969
5969
5970 .. note::
5970 .. note::
5971
5971
5972 :hg:`remove` never deletes files in Added [A] state from the
5972 :hg:`remove` never deletes files in Added [A] state from the
5973 working directory, not even if ``--force`` is specified.
5973 working directory, not even if ``--force`` is specified.
5974
5974
5975 Returns 0 on success, 1 if any warnings encountered.
5975 Returns 0 on success, 1 if any warnings encountered.
5976 """
5976 """
5977
5977
5978 after, force = opts.get('after'), opts.get('force')
5978 after, force = opts.get('after'), opts.get('force')
5979 dryrun = opts.get('dry_run')
5979 dryrun = opts.get('dry_run')
5980 if not pats and not after:
5980 if not pats and not after:
5981 raise error.InputError(_(b'no files specified'))
5981 raise error.InputError(_(b'no files specified'))
5982
5982
5983 with repo.wlock(), repo.dirstate.changing_files(repo):
5983 with repo.wlock(), repo.dirstate.changing_files(repo):
5984 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
5984 m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
5985 subrepos = opts.get('subrepos')
5985 subrepos = opts.get('subrepos')
5986 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
5986 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
5987 return cmdutil.remove(
5987 return cmdutil.remove(
5988 ui, repo, m, b"", uipathfn, after, force, subrepos, dryrun=dryrun
5988 ui, repo, m, b"", uipathfn, after, force, subrepos, dryrun=dryrun
5989 )
5989 )
5990
5990
5991
5991
5992 @command(
5992 @command(
5993 b'rename|move|mv',
5993 b'rename|move|mv',
5994 [
5994 [
5995 (b'', b'forget', None, _(b'unmark a destination file as renamed')),
5995 (b'', b'forget', None, _(b'unmark a destination file as renamed')),
5996 (b'A', b'after', None, _(b'record a rename that has already occurred')),
5996 (b'A', b'after', None, _(b'record a rename that has already occurred')),
5997 (
5997 (
5998 b'',
5998 b'',
5999 b'at-rev',
5999 b'at-rev',
6000 b'',
6000 b'',
6001 _(b'(un)mark renames in the given revision (EXPERIMENTAL)'),
6001 _(b'(un)mark renames in the given revision (EXPERIMENTAL)'),
6002 _(b'REV'),
6002 _(b'REV'),
6003 ),
6003 ),
6004 (
6004 (
6005 b'f',
6005 b'f',
6006 b'force',
6006 b'force',
6007 None,
6007 None,
6008 _(b'forcibly move over an existing managed file'),
6008 _(b'forcibly move over an existing managed file'),
6009 ),
6009 ),
6010 ]
6010 ]
6011 + walkopts
6011 + walkopts
6012 + dryrunopts,
6012 + dryrunopts,
6013 _(b'[OPTION]... SOURCE... DEST'),
6013 _(b'[OPTION]... SOURCE... DEST'),
6014 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6014 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6015 )
6015 )
6016 def rename(ui, repo, *pats, **opts):
6016 def rename(ui, repo, *pats, **opts):
6017 """rename files; equivalent of copy + remove
6017 """rename files; equivalent of copy + remove
6018
6018
6019 Mark dest as copies of sources; mark sources for deletion. If dest
6019 Mark dest as copies of sources; mark sources for deletion. If dest
6020 is a directory, copies are put in that directory. If dest is a
6020 is a directory, copies are put in that directory. If dest is a
6021 file, there can only be one source.
6021 file, there can only be one source.
6022
6022
6023 By default, this command copies the contents of files as they
6023 By default, this command copies the contents of files as they
6024 exist in the working directory. If invoked with -A/--after, the
6024 exist in the working directory. If invoked with -A/--after, the
6025 operation is recorded, but no copying is performed.
6025 operation is recorded, but no copying is performed.
6026
6026
6027 To undo marking a destination file as renamed, use --forget. With that
6027 To undo marking a destination file as renamed, use --forget. With that
6028 option, all given (positional) arguments are unmarked as renames. The
6028 option, all given (positional) arguments are unmarked as renames. The
6029 destination file(s) will be left in place (still tracked). The source
6029 destination file(s) will be left in place (still tracked). The source
6030 file(s) will not be restored. Note that :hg:`rename --forget` behaves
6030 file(s) will not be restored. Note that :hg:`rename --forget` behaves
6031 the same way as :hg:`copy --forget`.
6031 the same way as :hg:`copy --forget`.
6032
6032
6033 This command takes effect with the next commit by default.
6033 This command takes effect with the next commit by default.
6034
6034
6035 Returns 0 on success, 1 if errors are encountered.
6035 Returns 0 on success, 1 if errors are encountered.
6036 """
6036 """
6037 context = lambda repo: repo.dirstate.changing_files(repo)
6037 context = lambda repo: repo.dirstate.changing_files(repo)
6038 rev = opts.get('at_rev')
6038 rev = opts.get('at_rev')
6039
6039
6040 if rev:
6040 if rev:
6041 ctx = logcmdutil.revsingle(repo, rev)
6041 ctx = logcmdutil.revsingle(repo, rev)
6042 if ctx.rev() is not None:
6042 if ctx.rev() is not None:
6043
6043
6044 def context(repo):
6044 def context(repo):
6045 return util.nullcontextmanager()
6045 return util.nullcontextmanager()
6046
6046
6047 opts['at_rev'] = ctx.rev()
6047 opts['at_rev'] = ctx.rev()
6048 with repo.wlock(), context(repo):
6048 with repo.wlock(), context(repo):
6049 return cmdutil.copy(
6049 return cmdutil.copy(
6050 ui, repo, pats, pycompat.byteskwargs(opts), rename=True
6050 ui, repo, pats, pycompat.byteskwargs(opts), rename=True
6051 )
6051 )
6052
6052
6053
6053
6054 @command(
6054 @command(
6055 b'resolve',
6055 b'resolve',
6056 [
6056 [
6057 (b'a', b'all', None, _(b'select all unresolved files')),
6057 (b'a', b'all', None, _(b'select all unresolved files')),
6058 (b'l', b'list', None, _(b'list state of files needing merge')),
6058 (b'l', b'list', None, _(b'list state of files needing merge')),
6059 (b'm', b'mark', None, _(b'mark files as resolved')),
6059 (b'm', b'mark', None, _(b'mark files as resolved')),
6060 (b'u', b'unmark', None, _(b'mark files as unresolved')),
6060 (b'u', b'unmark', None, _(b'mark files as unresolved')),
6061 (b'n', b'no-status', None, _(b'hide status prefix')),
6061 (b'n', b'no-status', None, _(b'hide status prefix')),
6062 (b'', b're-merge', None, _(b're-merge files')),
6062 (b'', b're-merge', None, _(b're-merge files')),
6063 ]
6063 ]
6064 + mergetoolopts
6064 + mergetoolopts
6065 + walkopts
6065 + walkopts
6066 + formatteropts,
6066 + formatteropts,
6067 _(b'[OPTION]... [FILE]...'),
6067 _(b'[OPTION]... [FILE]...'),
6068 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6068 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6069 inferrepo=True,
6069 inferrepo=True,
6070 )
6070 )
6071 def resolve(ui, repo, *pats, **opts):
6071 def resolve(ui, repo, *pats, **opts):
6072 """redo merges or set/view the merge status of files
6072 """redo merges or set/view the merge status of files
6073
6073
6074 Merges with unresolved conflicts are often the result of
6074 Merges with unresolved conflicts are often the result of
6075 non-interactive merging using the ``internal:merge`` configuration
6075 non-interactive merging using the ``internal:merge`` configuration
6076 setting, or a command-line merge tool like ``diff3``. The resolve
6076 setting, or a command-line merge tool like ``diff3``. The resolve
6077 command is used to manage the files involved in a merge, after
6077 command is used to manage the files involved in a merge, after
6078 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
6078 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
6079 working directory must have two parents). See :hg:`help
6079 working directory must have two parents). See :hg:`help
6080 merge-tools` for information on configuring merge tools.
6080 merge-tools` for information on configuring merge tools.
6081
6081
6082 The resolve command can be used in the following ways:
6082 The resolve command can be used in the following ways:
6083
6083
6084 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
6084 - :hg:`resolve [--re-merge] [--tool TOOL] FILE...`: attempt to re-merge
6085 the specified files, discarding any previous merge attempts. Re-merging
6085 the specified files, discarding any previous merge attempts. Re-merging
6086 is not performed for files already marked as resolved. Use ``--all/-a``
6086 is not performed for files already marked as resolved. Use ``--all/-a``
6087 to select all unresolved files. ``--tool`` can be used to specify
6087 to select all unresolved files. ``--tool`` can be used to specify
6088 the merge tool used for the given files. It overrides the HGMERGE
6088 the merge tool used for the given files. It overrides the HGMERGE
6089 environment variable and your configuration files. Previous file
6089 environment variable and your configuration files. Previous file
6090 contents are saved with a ``.orig`` suffix.
6090 contents are saved with a ``.orig`` suffix.
6091
6091
6092 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
6092 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
6093 (e.g. after having manually fixed-up the files). The default is
6093 (e.g. after having manually fixed-up the files). The default is
6094 to mark all unresolved files.
6094 to mark all unresolved files.
6095
6095
6096 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
6096 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
6097 default is to mark all resolved files.
6097 default is to mark all resolved files.
6098
6098
6099 - :hg:`resolve -l`: list files which had or still have conflicts.
6099 - :hg:`resolve -l`: list files which had or still have conflicts.
6100 In the printed list, ``U`` = unresolved and ``R`` = resolved.
6100 In the printed list, ``U`` = unresolved and ``R`` = resolved.
6101 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
6101 You can use ``set:unresolved()`` or ``set:resolved()`` to filter
6102 the list. See :hg:`help filesets` for details.
6102 the list. See :hg:`help filesets` for details.
6103
6103
6104 .. note::
6104 .. note::
6105
6105
6106 Mercurial will not let you commit files with unresolved merge
6106 Mercurial will not let you commit files with unresolved merge
6107 conflicts. You must use :hg:`resolve -m ...` before you can
6107 conflicts. You must use :hg:`resolve -m ...` before you can
6108 commit after a conflicting merge.
6108 commit after a conflicting merge.
6109
6109
6110 .. container:: verbose
6110 .. container:: verbose
6111
6111
6112 Template:
6112 Template:
6113
6113
6114 The following keywords are supported in addition to the common template
6114 The following keywords are supported in addition to the common template
6115 keywords and functions. See also :hg:`help templates`.
6115 keywords and functions. See also :hg:`help templates`.
6116
6116
6117 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
6117 :mergestatus: String. Character denoting merge conflicts, ``U`` or ``R``.
6118 :path: String. Repository-absolute path of the file.
6118 :path: String. Repository-absolute path of the file.
6119
6119
6120 Returns 0 on success, 1 if any files fail a resolve attempt.
6120 Returns 0 on success, 1 if any files fail a resolve attempt.
6121 """
6121 """
6122
6122
6123 opts = pycompat.byteskwargs(opts)
6123 opts = pycompat.byteskwargs(opts)
6124 confirm = ui.configbool(b'commands', b'resolve.confirm')
6124 confirm = ui.configbool(b'commands', b'resolve.confirm')
6125 flaglist = b'all mark unmark list no_status re_merge'.split()
6125 flaglist = b'all mark unmark list no_status re_merge'.split()
6126 all, mark, unmark, show, nostatus, remerge = [opts.get(o) for o in flaglist]
6126 all, mark, unmark, show, nostatus, remerge = [opts.get(o) for o in flaglist]
6127
6127
6128 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
6128 actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
6129 if actioncount > 1:
6129 if actioncount > 1:
6130 raise error.InputError(_(b"too many actions specified"))
6130 raise error.InputError(_(b"too many actions specified"))
6131 elif actioncount == 0 and ui.configbool(
6131 elif actioncount == 0 and ui.configbool(
6132 b'commands', b'resolve.explicit-re-merge'
6132 b'commands', b'resolve.explicit-re-merge'
6133 ):
6133 ):
6134 hint = _(b'use --mark, --unmark, --list or --re-merge')
6134 hint = _(b'use --mark, --unmark, --list or --re-merge')
6135 raise error.InputError(_(b'no action specified'), hint=hint)
6135 raise error.InputError(_(b'no action specified'), hint=hint)
6136 if pats and all:
6136 if pats and all:
6137 raise error.InputError(_(b"can't specify --all and patterns"))
6137 raise error.InputError(_(b"can't specify --all and patterns"))
6138 if not (all or pats or show or mark or unmark):
6138 if not (all or pats or show or mark or unmark):
6139 raise error.InputError(
6139 raise error.InputError(
6140 _(b'no files or directories specified'),
6140 _(b'no files or directories specified'),
6141 hint=b'use --all to re-merge all unresolved files',
6141 hint=b'use --all to re-merge all unresolved files',
6142 )
6142 )
6143
6143
6144 if confirm:
6144 if confirm:
6145 if all:
6145 if all:
6146 if ui.promptchoice(
6146 if ui.promptchoice(
6147 _(b're-merge all unresolved files (yn)?$$ &Yes $$ &No')
6147 _(b're-merge all unresolved files (yn)?$$ &Yes $$ &No')
6148 ):
6148 ):
6149 raise error.CanceledError(_(b'user quit'))
6149 raise error.CanceledError(_(b'user quit'))
6150 if mark and not pats:
6150 if mark and not pats:
6151 if ui.promptchoice(
6151 if ui.promptchoice(
6152 _(
6152 _(
6153 b'mark all unresolved files as resolved (yn)?'
6153 b'mark all unresolved files as resolved (yn)?'
6154 b'$$ &Yes $$ &No'
6154 b'$$ &Yes $$ &No'
6155 )
6155 )
6156 ):
6156 ):
6157 raise error.CanceledError(_(b'user quit'))
6157 raise error.CanceledError(_(b'user quit'))
6158 if unmark and not pats:
6158 if unmark and not pats:
6159 if ui.promptchoice(
6159 if ui.promptchoice(
6160 _(
6160 _(
6161 b'mark all resolved files as unresolved (yn)?'
6161 b'mark all resolved files as unresolved (yn)?'
6162 b'$$ &Yes $$ &No'
6162 b'$$ &Yes $$ &No'
6163 )
6163 )
6164 ):
6164 ):
6165 raise error.CanceledError(_(b'user quit'))
6165 raise error.CanceledError(_(b'user quit'))
6166
6166
6167 uipathfn = scmutil.getuipathfn(repo)
6167 uipathfn = scmutil.getuipathfn(repo)
6168
6168
6169 if show:
6169 if show:
6170 ui.pager(b'resolve')
6170 ui.pager(b'resolve')
6171 fm = ui.formatter(b'resolve', opts)
6171 fm = ui.formatter(b'resolve', opts)
6172 ms = mergestatemod.mergestate.read(repo)
6172 ms = mergestatemod.mergestate.read(repo)
6173 wctx = repo[None]
6173 wctx = repo[None]
6174 m = scmutil.match(wctx, pats, opts)
6174 m = scmutil.match(wctx, pats, opts)
6175
6175
6176 # Labels and keys based on merge state. Unresolved path conflicts show
6176 # Labels and keys based on merge state. Unresolved path conflicts show
6177 # as 'P'. Resolved path conflicts show as 'R', the same as normal
6177 # as 'P'. Resolved path conflicts show as 'R', the same as normal
6178 # resolved conflicts.
6178 # resolved conflicts.
6179 mergestateinfo = {
6179 mergestateinfo = {
6180 mergestatemod.MERGE_RECORD_UNRESOLVED: (
6180 mergestatemod.MERGE_RECORD_UNRESOLVED: (
6181 b'resolve.unresolved',
6181 b'resolve.unresolved',
6182 b'U',
6182 b'U',
6183 ),
6183 ),
6184 mergestatemod.MERGE_RECORD_RESOLVED: (b'resolve.resolved', b'R'),
6184 mergestatemod.MERGE_RECORD_RESOLVED: (b'resolve.resolved', b'R'),
6185 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH: (
6185 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH: (
6186 b'resolve.unresolved',
6186 b'resolve.unresolved',
6187 b'P',
6187 b'P',
6188 ),
6188 ),
6189 mergestatemod.MERGE_RECORD_RESOLVED_PATH: (
6189 mergestatemod.MERGE_RECORD_RESOLVED_PATH: (
6190 b'resolve.resolved',
6190 b'resolve.resolved',
6191 b'R',
6191 b'R',
6192 ),
6192 ),
6193 }
6193 }
6194
6194
6195 for f in ms:
6195 for f in ms:
6196 if not m(f):
6196 if not m(f):
6197 continue
6197 continue
6198
6198
6199 label, key = mergestateinfo[ms[f]]
6199 label, key = mergestateinfo[ms[f]]
6200 fm.startitem()
6200 fm.startitem()
6201 fm.context(ctx=wctx)
6201 fm.context(ctx=wctx)
6202 fm.condwrite(not nostatus, b'mergestatus', b'%s ', key, label=label)
6202 fm.condwrite(not nostatus, b'mergestatus', b'%s ', key, label=label)
6203 fm.data(path=f)
6203 fm.data(path=f)
6204 fm.plain(b'%s\n' % uipathfn(f), label=label)
6204 fm.plain(b'%s\n' % uipathfn(f), label=label)
6205 fm.end()
6205 fm.end()
6206 return 0
6206 return 0
6207
6207
6208 with repo.wlock():
6208 with repo.wlock():
6209 ms = mergestatemod.mergestate.read(repo)
6209 ms = mergestatemod.mergestate.read(repo)
6210
6210
6211 if not (ms.active() or repo.dirstate.p2() != repo.nullid):
6211 if not (ms.active() or repo.dirstate.p2() != repo.nullid):
6212 raise error.StateError(
6212 raise error.StateError(
6213 _(b'resolve command not applicable when not merging')
6213 _(b'resolve command not applicable when not merging')
6214 )
6214 )
6215
6215
6216 wctx = repo[None]
6216 wctx = repo[None]
6217 m = scmutil.match(wctx, pats, opts)
6217 m = scmutil.match(wctx, pats, opts)
6218 ret = 0
6218 ret = 0
6219 didwork = False
6219 didwork = False
6220
6220
6221 hasconflictmarkers = []
6221 hasconflictmarkers = []
6222 if mark:
6222 if mark:
6223 markcheck = ui.config(b'commands', b'resolve.mark-check')
6223 markcheck = ui.config(b'commands', b'resolve.mark-check')
6224 if markcheck not in [b'warn', b'abort']:
6224 if markcheck not in [b'warn', b'abort']:
6225 # Treat all invalid / unrecognized values as 'none'.
6225 # Treat all invalid / unrecognized values as 'none'.
6226 markcheck = False
6226 markcheck = False
6227 for f in ms:
6227 for f in ms:
6228 if not m(f):
6228 if not m(f):
6229 continue
6229 continue
6230
6230
6231 didwork = True
6231 didwork = True
6232
6232
6233 # path conflicts must be resolved manually
6233 # path conflicts must be resolved manually
6234 if ms[f] in (
6234 if ms[f] in (
6235 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH,
6235 mergestatemod.MERGE_RECORD_UNRESOLVED_PATH,
6236 mergestatemod.MERGE_RECORD_RESOLVED_PATH,
6236 mergestatemod.MERGE_RECORD_RESOLVED_PATH,
6237 ):
6237 ):
6238 if mark:
6238 if mark:
6239 ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED_PATH)
6239 ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED_PATH)
6240 elif unmark:
6240 elif unmark:
6241 ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED_PATH)
6241 ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED_PATH)
6242 elif ms[f] == mergestatemod.MERGE_RECORD_UNRESOLVED_PATH:
6242 elif ms[f] == mergestatemod.MERGE_RECORD_UNRESOLVED_PATH:
6243 ui.warn(
6243 ui.warn(
6244 _(b'%s: path conflict must be resolved manually\n')
6244 _(b'%s: path conflict must be resolved manually\n')
6245 % uipathfn(f)
6245 % uipathfn(f)
6246 )
6246 )
6247 continue
6247 continue
6248
6248
6249 if mark:
6249 if mark:
6250 if markcheck:
6250 if markcheck:
6251 fdata = repo.wvfs.tryread(f)
6251 fdata = repo.wvfs.tryread(f)
6252 if (
6252 if (
6253 filemerge.hasconflictmarkers(fdata)
6253 filemerge.hasconflictmarkers(fdata)
6254 and ms[f] != mergestatemod.MERGE_RECORD_RESOLVED
6254 and ms[f] != mergestatemod.MERGE_RECORD_RESOLVED
6255 ):
6255 ):
6256 hasconflictmarkers.append(f)
6256 hasconflictmarkers.append(f)
6257 ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED)
6257 ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED)
6258 elif unmark:
6258 elif unmark:
6259 ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED)
6259 ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED)
6260 else:
6260 else:
6261 # backup pre-resolve (merge uses .orig for its own purposes)
6261 # backup pre-resolve (merge uses .orig for its own purposes)
6262 a = repo.wjoin(f)
6262 a = repo.wjoin(f)
6263 try:
6263 try:
6264 util.copyfile(a, a + b".resolve")
6264 util.copyfile(a, a + b".resolve")
6265 except FileNotFoundError:
6265 except FileNotFoundError:
6266 pass
6266 pass
6267
6267
6268 try:
6268 try:
6269 # preresolve file
6269 # preresolve file
6270 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
6270 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
6271 with ui.configoverride(overrides, b'resolve'):
6271 with ui.configoverride(overrides, b'resolve'):
6272 r = ms.resolve(f, wctx)
6272 r = ms.resolve(f, wctx)
6273 if r:
6273 if r:
6274 ret = 1
6274 ret = 1
6275 finally:
6275 finally:
6276 ms.commit()
6276 ms.commit()
6277
6277
6278 # replace filemerge's .orig file with our resolve file
6278 # replace filemerge's .orig file with our resolve file
6279 try:
6279 try:
6280 util.rename(
6280 util.rename(
6281 a + b".resolve", scmutil.backuppath(ui, repo, f)
6281 a + b".resolve", scmutil.backuppath(ui, repo, f)
6282 )
6282 )
6283 except FileNotFoundError:
6283 except FileNotFoundError:
6284 pass
6284 pass
6285
6285
6286 if hasconflictmarkers:
6286 if hasconflictmarkers:
6287 ui.warn(
6287 ui.warn(
6288 _(
6288 _(
6289 b'warning: the following files still have conflict '
6289 b'warning: the following files still have conflict '
6290 b'markers:\n'
6290 b'markers:\n'
6291 )
6291 )
6292 + b''.join(
6292 + b''.join(
6293 b' ' + uipathfn(f) + b'\n' for f in hasconflictmarkers
6293 b' ' + uipathfn(f) + b'\n' for f in hasconflictmarkers
6294 )
6294 )
6295 )
6295 )
6296 if markcheck == b'abort' and not all and not pats:
6296 if markcheck == b'abort' and not all and not pats:
6297 raise error.StateError(
6297 raise error.StateError(
6298 _(b'conflict markers detected'),
6298 _(b'conflict markers detected'),
6299 hint=_(b'use --all to mark anyway'),
6299 hint=_(b'use --all to mark anyway'),
6300 )
6300 )
6301
6301
6302 ms.commit()
6302 ms.commit()
6303 branchmerge = repo.dirstate.p2() != repo.nullid
6303 branchmerge = repo.dirstate.p2() != repo.nullid
6304 # resolve is not doing a parent change here, however, `record updates`
6304 # resolve is not doing a parent change here, however, `record updates`
6305 # will call some dirstate API that at intended for parent changes call.
6305 # will call some dirstate API that at intended for parent changes call.
6306 # Ideally we would not need this and could implement a lighter version
6306 # Ideally we would not need this and could implement a lighter version
6307 # of the recordupdateslogic that will not have to deal with the part
6307 # of the recordupdateslogic that will not have to deal with the part
6308 # related to parent changes. However this would requires that:
6308 # related to parent changes. However this would requires that:
6309 # - we are sure we passed around enough information at update/merge
6309 # - we are sure we passed around enough information at update/merge
6310 # time to no longer needs it at `hg resolve time`
6310 # time to no longer needs it at `hg resolve time`
6311 # - we are sure we store that information well enough to be able to reuse it
6311 # - we are sure we store that information well enough to be able to reuse it
6312 # - we are the necessary logic to reuse it right.
6312 # - we are the necessary logic to reuse it right.
6313 #
6313 #
6314 # All this should eventually happens, but in the mean time, we use this
6314 # All this should eventually happens, but in the mean time, we use this
6315 # context manager slightly out of the context it should be.
6315 # context manager slightly out of the context it should be.
6316 with repo.dirstate.changing_parents(repo):
6316 with repo.dirstate.changing_parents(repo):
6317 mergestatemod.recordupdates(repo, ms.actions(), branchmerge, None)
6317 mergestatemod.recordupdates(repo, ms.actions(), branchmerge, None)
6318
6318
6319 if not didwork and pats:
6319 if not didwork and pats:
6320 hint = None
6320 hint = None
6321 if not any([p for p in pats if p.find(b':') >= 0]):
6321 if not any([p for p in pats if p.find(b':') >= 0]):
6322 pats = [b'path:%s' % p for p in pats]
6322 pats = [b'path:%s' % p for p in pats]
6323 m = scmutil.match(wctx, pats, opts)
6323 m = scmutil.match(wctx, pats, opts)
6324 for f in ms:
6324 for f in ms:
6325 if not m(f):
6325 if not m(f):
6326 continue
6326 continue
6327
6327
6328 def flag(o):
6328 def flag(o):
6329 if o == b're_merge':
6329 if o == b're_merge':
6330 return b'--re-merge '
6330 return b'--re-merge '
6331 return b'-%s ' % o[0:1]
6331 return b'-%s ' % o[0:1]
6332
6332
6333 flags = b''.join([flag(o) for o in flaglist if opts.get(o)])
6333 flags = b''.join([flag(o) for o in flaglist if opts.get(o)])
6334 hint = _(b"(try: hg resolve %s%s)\n") % (
6334 hint = _(b"(try: hg resolve %s%s)\n") % (
6335 flags,
6335 flags,
6336 b' '.join(pats),
6336 b' '.join(pats),
6337 )
6337 )
6338 break
6338 break
6339 ui.warn(_(b"arguments do not match paths that need resolving\n"))
6339 ui.warn(_(b"arguments do not match paths that need resolving\n"))
6340 if hint:
6340 if hint:
6341 ui.warn(hint)
6341 ui.warn(hint)
6342
6342
6343 unresolvedf = ms.unresolvedcount()
6343 unresolvedf = ms.unresolvedcount()
6344 if not unresolvedf:
6344 if not unresolvedf:
6345 ui.status(_(b'(no more unresolved files)\n'))
6345 ui.status(_(b'(no more unresolved files)\n'))
6346 cmdutil.checkafterresolved(repo)
6346 cmdutil.checkafterresolved(repo)
6347
6347
6348 return ret
6348 return ret
6349
6349
6350
6350
6351 @command(
6351 @command(
6352 b'revert',
6352 b'revert',
6353 [
6353 [
6354 (b'a', b'all', None, _(b'revert all changes when no arguments given')),
6354 (b'a', b'all', None, _(b'revert all changes when no arguments given')),
6355 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
6355 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
6356 (b'r', b'rev', b'', _(b'revert to the specified revision'), _(b'REV')),
6356 (b'r', b'rev', b'', _(b'revert to the specified revision'), _(b'REV')),
6357 (b'C', b'no-backup', None, _(b'do not save backup copies of files')),
6357 (b'C', b'no-backup', None, _(b'do not save backup copies of files')),
6358 (b'i', b'interactive', None, _(b'interactively select the changes')),
6358 (b'i', b'interactive', None, _(b'interactively select the changes')),
6359 ]
6359 ]
6360 + walkopts
6360 + walkopts
6361 + dryrunopts,
6361 + dryrunopts,
6362 _(b'[OPTION]... [-r REV] [NAME]...'),
6362 _(b'[OPTION]... [-r REV] [NAME]...'),
6363 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6363 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6364 )
6364 )
6365 def revert(ui, repo, *pats, **opts):
6365 def revert(ui, repo, *pats, **opts):
6366 """restore files to their checkout state
6366 """restore files to their checkout state
6367
6367
6368 .. note::
6368 .. note::
6369
6369
6370 To check out earlier revisions, you should use :hg:`update REV`.
6370 To check out earlier revisions, you should use :hg:`update REV`.
6371 To cancel an uncommitted merge (and lose your changes),
6371 To cancel an uncommitted merge (and lose your changes),
6372 use :hg:`merge --abort`.
6372 use :hg:`merge --abort`.
6373
6373
6374 With no revision specified, revert the specified files or directories
6374 With no revision specified, revert the specified files or directories
6375 to the contents they had in the parent of the working directory.
6375 to the contents they had in the parent of the working directory.
6376 This restores the contents of files to an unmodified
6376 This restores the contents of files to an unmodified
6377 state and unschedules adds, removes, copies, and renames. If the
6377 state and unschedules adds, removes, copies, and renames. If the
6378 working directory has two parents, you must explicitly specify a
6378 working directory has two parents, you must explicitly specify a
6379 revision.
6379 revision.
6380
6380
6381 Using the -r/--rev or -d/--date options, revert the given files or
6381 Using the -r/--rev or -d/--date options, revert the given files or
6382 directories to their states as of a specific revision. Because
6382 directories to their states as of a specific revision. Because
6383 revert does not change the working directory parents, this will
6383 revert does not change the working directory parents, this will
6384 cause these files to appear modified. This can be helpful to "back
6384 cause these files to appear modified. This can be helpful to "back
6385 out" some or all of an earlier change. See :hg:`backout` for a
6385 out" some or all of an earlier change. See :hg:`backout` for a
6386 related method.
6386 related method.
6387
6387
6388 Modified files are saved with a .orig suffix before reverting.
6388 Modified files are saved with a .orig suffix before reverting.
6389 To disable these backups, use --no-backup. It is possible to store
6389 To disable these backups, use --no-backup. It is possible to store
6390 the backup files in a custom directory relative to the root of the
6390 the backup files in a custom directory relative to the root of the
6391 repository by setting the ``ui.origbackuppath`` configuration
6391 repository by setting the ``ui.origbackuppath`` configuration
6392 option.
6392 option.
6393
6393
6394 See :hg:`help dates` for a list of formats valid for -d/--date.
6394 See :hg:`help dates` for a list of formats valid for -d/--date.
6395
6395
6396 See :hg:`help backout` for a way to reverse the effect of an
6396 See :hg:`help backout` for a way to reverse the effect of an
6397 earlier changeset.
6397 earlier changeset.
6398
6398
6399 Returns 0 on success.
6399 Returns 0 on success.
6400 """
6400 """
6401
6401
6402 if opts.get("date"):
6402 if opts.get("date"):
6403 cmdutil.check_incompatible_arguments(opts, 'date', ['rev'])
6403 cmdutil.check_incompatible_arguments(opts, 'date', ['rev'])
6404 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
6404 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
6405
6405
6406 parent, p2 = repo.dirstate.parents()
6406 parent, p2 = repo.dirstate.parents()
6407 if not opts.get('rev') and p2 != repo.nullid:
6407 if not opts.get('rev') and p2 != repo.nullid:
6408 # revert after merge is a trap for new users (issue2915)
6408 # revert after merge is a trap for new users (issue2915)
6409 raise error.InputError(
6409 raise error.InputError(
6410 _(b'uncommitted merge with no revision specified'),
6410 _(b'uncommitted merge with no revision specified'),
6411 hint=_(b"use 'hg update' or see 'hg help revert'"),
6411 hint=_(b"use 'hg update' or see 'hg help revert'"),
6412 )
6412 )
6413
6413
6414 rev = opts.get('rev')
6414 rev = opts.get('rev')
6415 if rev:
6415 if rev:
6416 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
6416 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
6417 ctx = logcmdutil.revsingle(repo, rev)
6417 ctx = logcmdutil.revsingle(repo, rev)
6418
6418
6419 if not (
6419 if not (
6420 pats
6420 pats
6421 or opts.get('include')
6421 or opts.get('include')
6422 or opts.get('exclude')
6422 or opts.get('exclude')
6423 or opts.get('all')
6423 or opts.get('all')
6424 or opts.get('interactive')
6424 or opts.get('interactive')
6425 ):
6425 ):
6426 msg = _(b"no files or directories specified")
6426 msg = _(b"no files or directories specified")
6427 if p2 != repo.nullid:
6427 if p2 != repo.nullid:
6428 hint = _(
6428 hint = _(
6429 b"uncommitted merge, use --all to discard all changes,"
6429 b"uncommitted merge, use --all to discard all changes,"
6430 b" or 'hg update -C .' to abort the merge"
6430 b" or 'hg update -C .' to abort the merge"
6431 )
6431 )
6432 raise error.InputError(msg, hint=hint)
6432 raise error.InputError(msg, hint=hint)
6433 dirty = any(repo.status())
6433 dirty = any(repo.status())
6434 node = ctx.node()
6434 node = ctx.node()
6435 if node != parent:
6435 if node != parent:
6436 if dirty:
6436 if dirty:
6437 hint = (
6437 hint = (
6438 _(
6438 _(
6439 b"uncommitted changes, use --all to discard all"
6439 b"uncommitted changes, use --all to discard all"
6440 b" changes, or 'hg update %d' to update"
6440 b" changes, or 'hg update %d' to update"
6441 )
6441 )
6442 % ctx.rev()
6442 % ctx.rev()
6443 )
6443 )
6444 else:
6444 else:
6445 hint = (
6445 hint = (
6446 _(
6446 _(
6447 b"use --all to revert all files,"
6447 b"use --all to revert all files,"
6448 b" or 'hg update %d' to update"
6448 b" or 'hg update %d' to update"
6449 )
6449 )
6450 % ctx.rev()
6450 % ctx.rev()
6451 )
6451 )
6452 elif dirty:
6452 elif dirty:
6453 hint = _(b"uncommitted changes, use --all to discard all changes")
6453 hint = _(b"uncommitted changes, use --all to discard all changes")
6454 else:
6454 else:
6455 hint = _(b"use --all to revert all files")
6455 hint = _(b"use --all to revert all files")
6456 raise error.InputError(msg, hint=hint)
6456 raise error.InputError(msg, hint=hint)
6457
6457
6458 return cmdutil.revert(ui, repo, ctx, *pats, **opts)
6458 return cmdutil.revert(ui, repo, ctx, *pats, **opts)
6459
6459
6460
6460
6461 @command(
6461 @command(
6462 b'rollback',
6462 b'rollback',
6463 dryrunopts + [(b'f', b'force', False, _(b'ignore safety measures'))],
6463 dryrunopts + [(b'f', b'force', False, _(b'ignore safety measures'))],
6464 helpcategory=command.CATEGORY_MAINTENANCE,
6464 helpcategory=command.CATEGORY_MAINTENANCE,
6465 )
6465 )
6466 def rollback(ui, repo, **opts):
6466 def rollback(ui, repo, **opts):
6467 """roll back the last transaction (DANGEROUS) (DEPRECATED)
6467 """roll back the last transaction (DANGEROUS) (DEPRECATED)
6468
6468
6469 Please use :hg:`commit --amend` instead of rollback to correct
6469 Please use :hg:`commit --amend` instead of rollback to correct
6470 mistakes in the last commit.
6470 mistakes in the last commit.
6471
6471
6472 This command should be used with care. There is only one level of
6472 This command should be used with care. There is only one level of
6473 rollback, and there is no way to undo a rollback. It will also
6473 rollback, and there is no way to undo a rollback. It will also
6474 restore the dirstate at the time of the last transaction, losing
6474 restore the dirstate at the time of the last transaction, losing
6475 any dirstate changes since that time. This command does not alter
6475 any dirstate changes since that time. This command does not alter
6476 the working directory.
6476 the working directory.
6477
6477
6478 Transactions are used to encapsulate the effects of all commands
6478 Transactions are used to encapsulate the effects of all commands
6479 that create new changesets or propagate existing changesets into a
6479 that create new changesets or propagate existing changesets into a
6480 repository.
6480 repository.
6481
6481
6482 .. container:: verbose
6482 .. container:: verbose
6483
6483
6484 For example, the following commands are transactional, and their
6484 For example, the following commands are transactional, and their
6485 effects can be rolled back:
6485 effects can be rolled back:
6486
6486
6487 - commit
6487 - commit
6488 - import
6488 - import
6489 - pull
6489 - pull
6490 - push (with this repository as the destination)
6490 - push (with this repository as the destination)
6491 - unbundle
6491 - unbundle
6492
6492
6493 To avoid permanent data loss, rollback will refuse to rollback a
6493 To avoid permanent data loss, rollback will refuse to rollback a
6494 commit transaction if it isn't checked out. Use --force to
6494 commit transaction if it isn't checked out. Use --force to
6495 override this protection.
6495 override this protection.
6496
6496
6497 The rollback command can be entirely disabled by setting the
6497 The rollback command can be entirely disabled by setting the
6498 ``ui.rollback`` configuration setting to false. If you're here
6498 ``ui.rollback`` configuration setting to false. If you're here
6499 because you want to use rollback and it's disabled, you can
6499 because you want to use rollback and it's disabled, you can
6500 re-enable the command by setting ``ui.rollback`` to true.
6500 re-enable the command by setting ``ui.rollback`` to true.
6501
6501
6502 This command is not intended for use on public repositories. Once
6502 This command is not intended for use on public repositories. Once
6503 changes are visible for pull by other users, rolling a transaction
6503 changes are visible for pull by other users, rolling a transaction
6504 back locally is ineffective (someone else may already have pulled
6504 back locally is ineffective (someone else may already have pulled
6505 the changes). Furthermore, a race is possible with readers of the
6505 the changes). Furthermore, a race is possible with readers of the
6506 repository; for example an in-progress pull from the repository
6506 repository; for example an in-progress pull from the repository
6507 may fail if a rollback is performed.
6507 may fail if a rollback is performed.
6508
6508
6509 Returns 0 on success, 1 if no rollback data is available.
6509 Returns 0 on success, 1 if no rollback data is available.
6510 """
6510 """
6511 if not ui.configbool(b'ui', b'rollback'):
6511 if not ui.configbool(b'ui', b'rollback'):
6512 raise error.Abort(
6512 raise error.Abort(
6513 _(b'rollback is disabled because it is unsafe'),
6513 _(b'rollback is disabled because it is unsafe'),
6514 hint=b'see `hg help -v rollback` for information',
6514 hint=b'see `hg help -v rollback` for information',
6515 )
6515 )
6516 return repo.rollback(dryrun=opts.get('dry_run'), force=opts.get('force'))
6516 return repo.rollback(dryrun=opts.get('dry_run'), force=opts.get('force'))
6517
6517
6518
6518
6519 @command(
6519 @command(
6520 b'root',
6520 b'root',
6521 [] + formatteropts,
6521 [] + formatteropts,
6522 intents={INTENT_READONLY},
6522 intents={INTENT_READONLY},
6523 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6523 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6524 )
6524 )
6525 def root(ui, repo, **opts):
6525 def root(ui, repo, **opts):
6526 """print the root (top) of the current working directory
6526 """print the root (top) of the current working directory
6527
6527
6528 Print the root directory of the current repository.
6528 Print the root directory of the current repository.
6529
6529
6530 .. container:: verbose
6530 .. container:: verbose
6531
6531
6532 Template:
6532 Template:
6533
6533
6534 The following keywords are supported in addition to the common template
6534 The following keywords are supported in addition to the common template
6535 keywords and functions. See also :hg:`help templates`.
6535 keywords and functions. See also :hg:`help templates`.
6536
6536
6537 :hgpath: String. Path to the .hg directory.
6537 :hgpath: String. Path to the .hg directory.
6538 :storepath: String. Path to the directory holding versioned data.
6538 :storepath: String. Path to the directory holding versioned data.
6539
6539
6540 Returns 0 on success.
6540 Returns 0 on success.
6541 """
6541 """
6542 opts = pycompat.byteskwargs(opts)
6542 opts = pycompat.byteskwargs(opts)
6543 with ui.formatter(b'root', opts) as fm:
6543 with ui.formatter(b'root', opts) as fm:
6544 fm.startitem()
6544 fm.startitem()
6545 fm.write(b'reporoot', b'%s\n', repo.root)
6545 fm.write(b'reporoot', b'%s\n', repo.root)
6546 fm.data(hgpath=repo.path, storepath=repo.spath)
6546 fm.data(hgpath=repo.path, storepath=repo.spath)
6547
6547
6548
6548
6549 @command(
6549 @command(
6550 b'serve',
6550 b'serve',
6551 [
6551 [
6552 (
6552 (
6553 b'A',
6553 b'A',
6554 b'accesslog',
6554 b'accesslog',
6555 b'',
6555 b'',
6556 _(b'name of access log file to write to'),
6556 _(b'name of access log file to write to'),
6557 _(b'FILE'),
6557 _(b'FILE'),
6558 ),
6558 ),
6559 (b'd', b'daemon', None, _(b'run server in background')),
6559 (b'd', b'daemon', None, _(b'run server in background')),
6560 (b'', b'daemon-postexec', [], _(b'used internally by daemon mode')),
6560 (b'', b'daemon-postexec', [], _(b'used internally by daemon mode')),
6561 (
6561 (
6562 b'E',
6562 b'E',
6563 b'errorlog',
6563 b'errorlog',
6564 b'',
6564 b'',
6565 _(b'name of error log file to write to'),
6565 _(b'name of error log file to write to'),
6566 _(b'FILE'),
6566 _(b'FILE'),
6567 ),
6567 ),
6568 # use string type, then we can check if something was passed
6568 # use string type, then we can check if something was passed
6569 (
6569 (
6570 b'p',
6570 b'p',
6571 b'port',
6571 b'port',
6572 b'',
6572 b'',
6573 _(b'port to listen on (default: 8000)'),
6573 _(b'port to listen on (default: 8000)'),
6574 _(b'PORT'),
6574 _(b'PORT'),
6575 ),
6575 ),
6576 (
6576 (
6577 b'a',
6577 b'a',
6578 b'address',
6578 b'address',
6579 b'',
6579 b'',
6580 _(b'address to listen on (default: all interfaces)'),
6580 _(b'address to listen on (default: all interfaces)'),
6581 _(b'ADDR'),
6581 _(b'ADDR'),
6582 ),
6582 ),
6583 (
6583 (
6584 b'',
6584 b'',
6585 b'prefix',
6585 b'prefix',
6586 b'',
6586 b'',
6587 _(b'prefix path to serve from (default: server root)'),
6587 _(b'prefix path to serve from (default: server root)'),
6588 _(b'PREFIX'),
6588 _(b'PREFIX'),
6589 ),
6589 ),
6590 (
6590 (
6591 b'n',
6591 b'n',
6592 b'name',
6592 b'name',
6593 b'',
6593 b'',
6594 _(b'name to show in web pages (default: working directory)'),
6594 _(b'name to show in web pages (default: working directory)'),
6595 _(b'NAME'),
6595 _(b'NAME'),
6596 ),
6596 ),
6597 (
6597 (
6598 b'',
6598 b'',
6599 b'web-conf',
6599 b'web-conf',
6600 b'',
6600 b'',
6601 _(b"name of the hgweb config file (see 'hg help hgweb')"),
6601 _(b"name of the hgweb config file (see 'hg help hgweb')"),
6602 _(b'FILE'),
6602 _(b'FILE'),
6603 ),
6603 ),
6604 (
6604 (
6605 b'',
6605 b'',
6606 b'webdir-conf',
6606 b'webdir-conf',
6607 b'',
6607 b'',
6608 _(b'name of the hgweb config file (DEPRECATED)'),
6608 _(b'name of the hgweb config file (DEPRECATED)'),
6609 _(b'FILE'),
6609 _(b'FILE'),
6610 ),
6610 ),
6611 (
6611 (
6612 b'',
6612 b'',
6613 b'pid-file',
6613 b'pid-file',
6614 b'',
6614 b'',
6615 _(b'name of file to write process ID to'),
6615 _(b'name of file to write process ID to'),
6616 _(b'FILE'),
6616 _(b'FILE'),
6617 ),
6617 ),
6618 (b'', b'stdio', None, _(b'for remote clients (ADVANCED)')),
6618 (b'', b'stdio', None, _(b'for remote clients (ADVANCED)')),
6619 (
6619 (
6620 b'',
6620 b'',
6621 b'cmdserver',
6621 b'cmdserver',
6622 b'',
6622 b'',
6623 _(b'for remote clients (ADVANCED)'),
6623 _(b'for remote clients (ADVANCED)'),
6624 _(b'MODE'),
6624 _(b'MODE'),
6625 ),
6625 ),
6626 (b't', b'templates', b'', _(b'web templates to use'), _(b'TEMPLATE')),
6626 (b't', b'templates', b'', _(b'web templates to use'), _(b'TEMPLATE')),
6627 (b'', b'style', b'', _(b'template style to use'), _(b'STYLE')),
6627 (b'', b'style', b'', _(b'template style to use'), _(b'STYLE')),
6628 (b'6', b'ipv6', None, _(b'use IPv6 instead of IPv4')),
6628 (b'6', b'ipv6', None, _(b'use IPv6 instead of IPv4')),
6629 (b'', b'certificate', b'', _(b'SSL certificate file'), _(b'FILE')),
6629 (b'', b'certificate', b'', _(b'SSL certificate file'), _(b'FILE')),
6630 (b'', b'print-url', None, _(b'start and print only the URL')),
6630 (b'', b'print-url', None, _(b'start and print only the URL')),
6631 ]
6631 ]
6632 + subrepoopts,
6632 + subrepoopts,
6633 _(b'[OPTION]...'),
6633 _(b'[OPTION]...'),
6634 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
6634 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
6635 helpbasic=True,
6635 helpbasic=True,
6636 optionalrepo=True,
6636 optionalrepo=True,
6637 )
6637 )
6638 def serve(ui, repo, **opts):
6638 def serve(ui, repo, **opts):
6639 """start stand-alone webserver
6639 """start stand-alone webserver
6640
6640
6641 Start a local HTTP repository browser and pull server. You can use
6641 Start a local HTTP repository browser and pull server. You can use
6642 this for ad-hoc sharing and browsing of repositories. It is
6642 this for ad-hoc sharing and browsing of repositories. It is
6643 recommended to use a real web server to serve a repository for
6643 recommended to use a real web server to serve a repository for
6644 longer periods of time.
6644 longer periods of time.
6645
6645
6646 Please note that the server does not implement access control.
6646 Please note that the server does not implement access control.
6647 This means that, by default, anybody can read from the server and
6647 This means that, by default, anybody can read from the server and
6648 nobody can write to it by default. Set the ``web.allow-push``
6648 nobody can write to it by default. Set the ``web.allow-push``
6649 option to ``*`` to allow everybody to push to the server. You
6649 option to ``*`` to allow everybody to push to the server. You
6650 should use a real web server if you need to authenticate users.
6650 should use a real web server if you need to authenticate users.
6651
6651
6652 By default, the server logs accesses to stdout and errors to
6652 By default, the server logs accesses to stdout and errors to
6653 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
6653 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
6654 files.
6654 files.
6655
6655
6656 To have the server choose a free port number to listen on, specify
6656 To have the server choose a free port number to listen on, specify
6657 a port number of 0; in this case, the server will print the port
6657 a port number of 0; in this case, the server will print the port
6658 number it uses.
6658 number it uses.
6659
6659
6660 Returns 0 on success.
6660 Returns 0 on success.
6661 """
6661 """
6662
6662
6663 cmdutil.check_incompatible_arguments(opts, 'stdio', ['cmdserver'])
6663 cmdutil.check_incompatible_arguments(opts, 'stdio', ['cmdserver'])
6664 opts = pycompat.byteskwargs(opts)
6664 opts = pycompat.byteskwargs(opts)
6665 if opts[b"print_url"] and ui.verbose:
6665 if opts[b"print_url"] and ui.verbose:
6666 raise error.InputError(_(b"cannot use --print-url with --verbose"))
6666 raise error.InputError(_(b"cannot use --print-url with --verbose"))
6667
6667
6668 if opts[b"stdio"]:
6668 if opts[b"stdio"]:
6669 if repo is None:
6669 if repo is None:
6670 raise error.RepoError(
6670 raise error.RepoError(
6671 _(b"there is no Mercurial repository here (.hg not found)")
6671 _(b"there is no Mercurial repository here (.hg not found)")
6672 )
6672 )
6673 accesshidden = False
6673 accesshidden = False
6674 if repo.filtername is None:
6674 if repo.filtername is None:
6675 allow = ui.configlist(
6675 allow = ui.configlist(
6676 b'experimental', b'server.allow-hidden-access'
6676 b'experimental', b'server.allow-hidden-access'
6677 )
6677 )
6678 user = procutil.getuser()
6678 user = procutil.getuser()
6679 if allow and scmutil.ismember(ui, user, allow):
6679 if allow and scmutil.ismember(ui, user, allow):
6680 accesshidden = True
6680 accesshidden = True
6681 else:
6681 else:
6682 msg = (
6682 msg = (
6683 _(
6683 _(
6684 b'ignoring request to access hidden changeset by '
6684 b'ignoring request to access hidden changeset by '
6685 b'unauthorized user: %s\n'
6685 b'unauthorized user: %s\n'
6686 )
6686 )
6687 % user
6687 % user
6688 )
6688 )
6689 ui.warn(msg)
6689 ui.warn(msg)
6690
6690
6691 s = wireprotoserver.sshserver(ui, repo, accesshidden=accesshidden)
6691 s = wireprotoserver.sshserver(ui, repo, accesshidden=accesshidden)
6692 s.serve_forever()
6692 s.serve_forever()
6693 return
6693 return
6694
6694
6695 service = server.createservice(ui, repo, opts)
6695 service = server.createservice(ui, repo, opts)
6696 return server.runservice(opts, initfn=service.init, runfn=service.run)
6696 return server.runservice(opts, initfn=service.init, runfn=service.run)
6697
6697
6698
6698
6699 @command(
6699 @command(
6700 b'shelve',
6700 b'shelve',
6701 [
6701 [
6702 (
6702 (
6703 b'A',
6703 b'A',
6704 b'addremove',
6704 b'addremove',
6705 None,
6705 None,
6706 _(b'mark new/missing files as added/removed before shelving'),
6706 _(b'mark new/missing files as added/removed before shelving'),
6707 ),
6707 ),
6708 (b'u', b'unknown', None, _(b'store unknown files in the shelve')),
6708 (b'u', b'unknown', None, _(b'store unknown files in the shelve')),
6709 (b'', b'cleanup', None, _(b'delete all shelved changes')),
6709 (b'', b'cleanup', None, _(b'delete all shelved changes')),
6710 (
6710 (
6711 b'',
6711 b'',
6712 b'date',
6712 b'date',
6713 b'',
6713 b'',
6714 _(b'shelve with the specified commit date'),
6714 _(b'shelve with the specified commit date'),
6715 _(b'DATE'),
6715 _(b'DATE'),
6716 ),
6716 ),
6717 (b'd', b'delete', None, _(b'delete the named shelved change(s)')),
6717 (b'd', b'delete', None, _(b'delete the named shelved change(s)')),
6718 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
6718 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
6719 (
6719 (
6720 b'k',
6720 b'k',
6721 b'keep',
6721 b'keep',
6722 False,
6722 False,
6723 _(b'shelve, but keep changes in the working directory'),
6723 _(b'shelve, but keep changes in the working directory'),
6724 ),
6724 ),
6725 (b'l', b'list', None, _(b'list current shelves')),
6725 (b'l', b'list', None, _(b'list current shelves')),
6726 (b'm', b'message', b'', _(b'use text as shelve message'), _(b'TEXT')),
6726 (b'm', b'message', b'', _(b'use text as shelve message'), _(b'TEXT')),
6727 (
6727 (
6728 b'n',
6728 b'n',
6729 b'name',
6729 b'name',
6730 b'',
6730 b'',
6731 _(b'use the given name for the shelved commit'),
6731 _(b'use the given name for the shelved commit'),
6732 _(b'NAME'),
6732 _(b'NAME'),
6733 ),
6733 ),
6734 (
6734 (
6735 b'p',
6735 b'p',
6736 b'patch',
6736 b'patch',
6737 None,
6737 None,
6738 _(
6738 _(
6739 b'output patches for changes (provide the names of the shelved '
6739 b'output patches for changes (provide the names of the shelved '
6740 b'changes as positional arguments)'
6740 b'changes as positional arguments)'
6741 ),
6741 ),
6742 ),
6742 ),
6743 (b'i', b'interactive', None, _(b'interactive mode')),
6743 (b'i', b'interactive', None, _(b'interactive mode')),
6744 (
6744 (
6745 b'',
6745 b'',
6746 b'stat',
6746 b'stat',
6747 None,
6747 None,
6748 _(
6748 _(
6749 b'output diffstat-style summary of changes (provide the names of '
6749 b'output diffstat-style summary of changes (provide the names of '
6750 b'the shelved changes as positional arguments)'
6750 b'the shelved changes as positional arguments)'
6751 ),
6751 ),
6752 ),
6752 ),
6753 ]
6753 ]
6754 + cmdutil.walkopts,
6754 + cmdutil.walkopts,
6755 _(b'hg shelve [OPTION]... [FILE]...'),
6755 _(b'hg shelve [OPTION]... [FILE]...'),
6756 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6756 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6757 )
6757 )
6758 def shelve(ui, repo, *pats, **opts):
6758 def shelve(ui, repo, *pats, **opts):
6759 """save and set aside changes from the working directory
6759 """save and set aside changes from the working directory
6760
6760
6761 Shelving takes files that "hg status" reports as not clean, saves
6761 Shelving takes files that "hg status" reports as not clean, saves
6762 the modifications to a bundle (a shelved change), and reverts the
6762 the modifications to a bundle (a shelved change), and reverts the
6763 files so that their state in the working directory becomes clean.
6763 files so that their state in the working directory becomes clean.
6764
6764
6765 To restore these changes to the working directory, using "hg
6765 To restore these changes to the working directory, using "hg
6766 unshelve"; this will work even if you switch to a different
6766 unshelve"; this will work even if you switch to a different
6767 commit.
6767 commit.
6768
6768
6769 When no files are specified, "hg shelve" saves all not-clean
6769 When no files are specified, "hg shelve" saves all not-clean
6770 files. If specific files or directories are named, only changes to
6770 files. If specific files or directories are named, only changes to
6771 those files are shelved.
6771 those files are shelved.
6772
6772
6773 In bare shelve (when no files are specified, without interactive,
6773 In bare shelve (when no files are specified, without interactive,
6774 include and exclude option), shelving remembers information if the
6774 include and exclude option), shelving remembers information if the
6775 working directory was on newly created branch, in other words working
6775 working directory was on newly created branch, in other words working
6776 directory was on different branch than its first parent. In this
6776 directory was on different branch than its first parent. In this
6777 situation unshelving restores branch information to the working directory.
6777 situation unshelving restores branch information to the working directory.
6778
6778
6779 Each shelved change has a name that makes it easier to find later.
6779 Each shelved change has a name that makes it easier to find later.
6780 The name of a shelved change defaults to being based on the active
6780 The name of a shelved change defaults to being based on the active
6781 bookmark, or if there is no active bookmark, the current named
6781 bookmark, or if there is no active bookmark, the current named
6782 branch. To specify a different name, use ``--name``.
6782 branch. To specify a different name, use ``--name``.
6783
6783
6784 To see a list of existing shelved changes, use the ``--list``
6784 To see a list of existing shelved changes, use the ``--list``
6785 option. For each shelved change, this will print its name, age,
6785 option. For each shelved change, this will print its name, age,
6786 and description; use ``--patch`` or ``--stat`` for more details.
6786 and description; use ``--patch`` or ``--stat`` for more details.
6787
6787
6788 To delete specific shelved changes, use ``--delete``. To delete
6788 To delete specific shelved changes, use ``--delete``. To delete
6789 all shelved changes, use ``--cleanup``.
6789 all shelved changes, use ``--cleanup``.
6790 """
6790 """
6791 opts = pycompat.byteskwargs(opts)
6791 opts = pycompat.byteskwargs(opts)
6792 allowables = [
6792 allowables = [
6793 (b'addremove', {b'create'}), # 'create' is pseudo action
6793 (b'addremove', {b'create'}), # 'create' is pseudo action
6794 (b'unknown', {b'create'}),
6794 (b'unknown', {b'create'}),
6795 (b'cleanup', {b'cleanup'}),
6795 (b'cleanup', {b'cleanup'}),
6796 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
6796 # ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
6797 (b'delete', {b'delete'}),
6797 (b'delete', {b'delete'}),
6798 (b'edit', {b'create'}),
6798 (b'edit', {b'create'}),
6799 (b'keep', {b'create'}),
6799 (b'keep', {b'create'}),
6800 (b'list', {b'list'}),
6800 (b'list', {b'list'}),
6801 (b'message', {b'create'}),
6801 (b'message', {b'create'}),
6802 (b'name', {b'create'}),
6802 (b'name', {b'create'}),
6803 (b'patch', {b'patch', b'list'}),
6803 (b'patch', {b'patch', b'list'}),
6804 (b'stat', {b'stat', b'list'}),
6804 (b'stat', {b'stat', b'list'}),
6805 ]
6805 ]
6806
6806
6807 def checkopt(opt):
6807 def checkopt(opt):
6808 if opts.get(opt):
6808 if opts.get(opt):
6809 for i, allowable in allowables:
6809 for i, allowable in allowables:
6810 if opts[i] and opt not in allowable:
6810 if opts[i] and opt not in allowable:
6811 raise error.InputError(
6811 raise error.InputError(
6812 _(
6812 _(
6813 b"options '--%s' and '--%s' may not be "
6813 b"options '--%s' and '--%s' may not be "
6814 b"used together"
6814 b"used together"
6815 )
6815 )
6816 % (opt, i)
6816 % (opt, i)
6817 )
6817 )
6818 return True
6818 return True
6819
6819
6820 if checkopt(b'cleanup'):
6820 if checkopt(b'cleanup'):
6821 if pats:
6821 if pats:
6822 raise error.InputError(
6822 raise error.InputError(
6823 _(b"cannot specify names when using '--cleanup'")
6823 _(b"cannot specify names when using '--cleanup'")
6824 )
6824 )
6825 return shelvemod.cleanupcmd(ui, repo)
6825 return shelvemod.cleanupcmd(ui, repo)
6826 elif checkopt(b'delete'):
6826 elif checkopt(b'delete'):
6827 return shelvemod.deletecmd(ui, repo, pats)
6827 return shelvemod.deletecmd(ui, repo, pats)
6828 elif checkopt(b'list'):
6828 elif checkopt(b'list'):
6829 return shelvemod.listcmd(ui, repo, pats, opts)
6829 return shelvemod.listcmd(ui, repo, pats, opts)
6830 elif checkopt(b'patch') or checkopt(b'stat'):
6830 elif checkopt(b'patch') or checkopt(b'stat'):
6831 return shelvemod.patchcmds(ui, repo, pats, opts)
6831 return shelvemod.patchcmds(ui, repo, pats, opts)
6832 else:
6832 else:
6833 return shelvemod.createcmd(ui, repo, pats, opts)
6833 return shelvemod.createcmd(ui, repo, pats, opts)
6834
6834
6835
6835
6836 _NOTTERSE = b'nothing'
6836 _NOTTERSE = b'nothing'
6837
6837
6838
6838
6839 @command(
6839 @command(
6840 b'status|st',
6840 b'status|st',
6841 [
6841 [
6842 (b'A', b'all', None, _(b'show status of all files')),
6842 (b'A', b'all', None, _(b'show status of all files')),
6843 (b'm', b'modified', None, _(b'show only modified files')),
6843 (b'm', b'modified', None, _(b'show only modified files')),
6844 (b'a', b'added', None, _(b'show only added files')),
6844 (b'a', b'added', None, _(b'show only added files')),
6845 (b'r', b'removed', None, _(b'show only removed files')),
6845 (b'r', b'removed', None, _(b'show only removed files')),
6846 (b'd', b'deleted', None, _(b'show only missing files')),
6846 (b'd', b'deleted', None, _(b'show only missing files')),
6847 (b'c', b'clean', None, _(b'show only files without changes')),
6847 (b'c', b'clean', None, _(b'show only files without changes')),
6848 (b'u', b'unknown', None, _(b'show only unknown (not tracked) files')),
6848 (b'u', b'unknown', None, _(b'show only unknown (not tracked) files')),
6849 (b'i', b'ignored', None, _(b'show only ignored files')),
6849 (b'i', b'ignored', None, _(b'show only ignored files')),
6850 (b'n', b'no-status', None, _(b'hide status prefix')),
6850 (b'n', b'no-status', None, _(b'hide status prefix')),
6851 (b't', b'terse', _NOTTERSE, _(b'show the terse output (EXPERIMENTAL)')),
6851 (b't', b'terse', _NOTTERSE, _(b'show the terse output (EXPERIMENTAL)')),
6852 (
6852 (
6853 b'C',
6853 b'C',
6854 b'copies',
6854 b'copies',
6855 None,
6855 None,
6856 _(b'show source of copied files (DEFAULT: ui.statuscopies)'),
6856 _(b'show source of copied files (DEFAULT: ui.statuscopies)'),
6857 ),
6857 ),
6858 (
6858 (
6859 b'0',
6859 b'0',
6860 b'print0',
6860 b'print0',
6861 None,
6861 None,
6862 _(b'end filenames with NUL, for use with xargs'),
6862 _(b'end filenames with NUL, for use with xargs'),
6863 ),
6863 ),
6864 (b'', b'rev', [], _(b'show difference from revision'), _(b'REV')),
6864 (b'', b'rev', [], _(b'show difference from revision'), _(b'REV')),
6865 (
6865 (
6866 b'',
6866 b'',
6867 b'change',
6867 b'change',
6868 b'',
6868 b'',
6869 _(b'list the changed files of a revision'),
6869 _(b'list the changed files of a revision'),
6870 _(b'REV'),
6870 _(b'REV'),
6871 ),
6871 ),
6872 ]
6872 ]
6873 + walkopts
6873 + walkopts
6874 + subrepoopts
6874 + subrepoopts
6875 + formatteropts,
6875 + formatteropts,
6876 _(b'[OPTION]... [FILE]...'),
6876 _(b'[OPTION]... [FILE]...'),
6877 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6877 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
6878 helpbasic=True,
6878 helpbasic=True,
6879 inferrepo=True,
6879 inferrepo=True,
6880 intents={INTENT_READONLY},
6880 intents={INTENT_READONLY},
6881 )
6881 )
6882 def status(ui, repo, *pats, **opts):
6882 def status(ui, repo, *pats, **opts):
6883 """show changed files in the working directory
6883 """show changed files in the working directory
6884
6884
6885 Show status of files in the repository. If names are given, only
6885 Show status of files in the repository. If names are given, only
6886 files that match are shown. Files that are clean or ignored or
6886 files that match are shown. Files that are clean or ignored or
6887 the source of a copy/move operation, are not listed unless
6887 the source of a copy/move operation, are not listed unless
6888 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
6888 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
6889 Unless options described with "show only ..." are given, the
6889 Unless options described with "show only ..." are given, the
6890 options -mardu are used.
6890 options -mardu are used.
6891
6891
6892 Option -q/--quiet hides untracked (unknown and ignored) files
6892 Option -q/--quiet hides untracked (unknown and ignored) files
6893 unless explicitly requested with -u/--unknown or -i/--ignored.
6893 unless explicitly requested with -u/--unknown or -i/--ignored.
6894
6894
6895 .. note::
6895 .. note::
6896
6896
6897 :hg:`status` may appear to disagree with diff if permissions have
6897 :hg:`status` may appear to disagree with diff if permissions have
6898 changed or a merge has occurred. The standard diff format does
6898 changed or a merge has occurred. The standard diff format does
6899 not report permission changes and diff only reports changes
6899 not report permission changes and diff only reports changes
6900 relative to one merge parent.
6900 relative to one merge parent.
6901
6901
6902 If one revision is given, it is used as the base revision.
6902 If one revision is given, it is used as the base revision.
6903 If two revisions are given, the differences between them are
6903 If two revisions are given, the differences between them are
6904 shown. The --change option can also be used as a shortcut to list
6904 shown. The --change option can also be used as a shortcut to list
6905 the changed files of a revision from its first parent.
6905 the changed files of a revision from its first parent.
6906
6906
6907 The codes used to show the status of files are::
6907 The codes used to show the status of files are::
6908
6908
6909 M = modified
6909 M = modified
6910 A = added
6910 A = added
6911 R = removed
6911 R = removed
6912 C = clean
6912 C = clean
6913 ! = missing (deleted by non-hg command, but still tracked)
6913 ! = missing (deleted by non-hg command, but still tracked)
6914 ? = not tracked
6914 ? = not tracked
6915 I = ignored
6915 I = ignored
6916 = origin of the previous file (with --copies)
6916 = origin of the previous file (with --copies)
6917
6917
6918 .. container:: verbose
6918 .. container:: verbose
6919
6919
6920 The -t/--terse option abbreviates the output by showing only the directory
6920 The -t/--terse option abbreviates the output by showing only the directory
6921 name if all the files in it share the same status. The option takes an
6921 name if all the files in it share the same status. The option takes an
6922 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
6922 argument indicating the statuses to abbreviate: 'm' for 'modified', 'a'
6923 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
6923 for 'added', 'r' for 'removed', 'd' for 'deleted', 'u' for 'unknown', 'i'
6924 for 'ignored' and 'c' for clean.
6924 for 'ignored' and 'c' for clean.
6925
6925
6926 It abbreviates only those statuses which are passed. Note that clean and
6926 It abbreviates only those statuses which are passed. Note that clean and
6927 ignored files are not displayed with '--terse ic' unless the -c/--clean
6927 ignored files are not displayed with '--terse ic' unless the -c/--clean
6928 and -i/--ignored options are also used.
6928 and -i/--ignored options are also used.
6929
6929
6930 The -v/--verbose option shows information when the repository is in an
6930 The -v/--verbose option shows information when the repository is in an
6931 unfinished merge, shelve, rebase state etc. You can have this behavior
6931 unfinished merge, shelve, rebase state etc. You can have this behavior
6932 turned on by default by enabling the ``commands.status.verbose`` option.
6932 turned on by default by enabling the ``commands.status.verbose`` option.
6933
6933
6934 You can skip displaying some of these states by setting
6934 You can skip displaying some of these states by setting
6935 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
6935 ``commands.status.skipstates`` to one or more of: 'bisect', 'graft',
6936 'histedit', 'merge', 'rebase', or 'unshelve'.
6936 'histedit', 'merge', 'rebase', or 'unshelve'.
6937
6937
6938 Template:
6938 Template:
6939
6939
6940 The following keywords are supported in addition to the common template
6940 The following keywords are supported in addition to the common template
6941 keywords and functions. See also :hg:`help templates`.
6941 keywords and functions. See also :hg:`help templates`.
6942
6942
6943 :path: String. Repository-absolute path of the file.
6943 :path: String. Repository-absolute path of the file.
6944 :source: String. Repository-absolute path of the file originated from.
6944 :source: String. Repository-absolute path of the file originated from.
6945 Available if ``--copies`` is specified.
6945 Available if ``--copies`` is specified.
6946 :status: String. Character denoting file's status.
6946 :status: String. Character denoting file's status.
6947
6947
6948 Examples:
6948 Examples:
6949
6949
6950 - show changes in the working directory relative to a
6950 - show changes in the working directory relative to a
6951 changeset::
6951 changeset::
6952
6952
6953 hg status --rev 9353
6953 hg status --rev 9353
6954
6954
6955 - show changes in the working directory relative to the
6955 - show changes in the working directory relative to the
6956 current directory (see :hg:`help patterns` for more information)::
6956 current directory (see :hg:`help patterns` for more information)::
6957
6957
6958 hg status re:
6958 hg status re:
6959
6959
6960 - show all changes including copies in an existing changeset::
6960 - show all changes including copies in an existing changeset::
6961
6961
6962 hg status --copies --change 9353
6962 hg status --copies --change 9353
6963
6963
6964 - get a NUL separated list of added files, suitable for xargs::
6964 - get a NUL separated list of added files, suitable for xargs::
6965
6965
6966 hg status -an0
6966 hg status -an0
6967
6967
6968 - show more information about the repository status, abbreviating
6968 - show more information about the repository status, abbreviating
6969 added, removed, modified, deleted, and untracked paths::
6969 added, removed, modified, deleted, and untracked paths::
6970
6970
6971 hg status -v -t mardu
6971 hg status -v -t mardu
6972
6972
6973 Returns 0 on success.
6973 Returns 0 on success.
6974
6974
6975 """
6975 """
6976
6976
6977 cmdutil.check_at_most_one_arg(opts, 'rev', 'change')
6977 cmdutil.check_at_most_one_arg(opts, 'rev', 'change')
6978 opts = pycompat.byteskwargs(opts)
6978 opts = pycompat.byteskwargs(opts)
6979 revs = opts.get(b'rev', [])
6979 revs = opts.get(b'rev', [])
6980 change = opts.get(b'change', b'')
6980 change = opts.get(b'change', b'')
6981 terse = opts.get(b'terse', _NOTTERSE)
6981 terse = opts.get(b'terse', _NOTTERSE)
6982 if terse is _NOTTERSE:
6982 if terse is _NOTTERSE:
6983 if revs:
6983 if revs:
6984 terse = b''
6984 terse = b''
6985 else:
6985 else:
6986 terse = ui.config(b'commands', b'status.terse')
6986 terse = ui.config(b'commands', b'status.terse')
6987
6987
6988 if revs and terse:
6988 if revs and terse:
6989 msg = _(b'cannot use --terse with --rev')
6989 msg = _(b'cannot use --terse with --rev')
6990 raise error.InputError(msg)
6990 raise error.InputError(msg)
6991 elif change:
6991 elif change:
6992 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
6992 repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
6993 ctx2 = logcmdutil.revsingle(repo, change, None)
6993 ctx2 = logcmdutil.revsingle(repo, change, None)
6994 ctx1 = ctx2.p1()
6994 ctx1 = ctx2.p1()
6995 else:
6995 else:
6996 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
6996 repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
6997 ctx1, ctx2 = logcmdutil.revpair(repo, revs)
6997 ctx1, ctx2 = logcmdutil.revpair(repo, revs)
6998
6998
6999 forcerelativevalue = None
6999 forcerelativevalue = None
7000 if ui.hasconfig(b'commands', b'status.relative'):
7000 if ui.hasconfig(b'commands', b'status.relative'):
7001 forcerelativevalue = ui.configbool(b'commands', b'status.relative')
7001 forcerelativevalue = ui.configbool(b'commands', b'status.relative')
7002 uipathfn = scmutil.getuipathfn(
7002 uipathfn = scmutil.getuipathfn(
7003 repo,
7003 repo,
7004 legacyrelativevalue=bool(pats),
7004 legacyrelativevalue=bool(pats),
7005 forcerelativevalue=forcerelativevalue,
7005 forcerelativevalue=forcerelativevalue,
7006 )
7006 )
7007
7007
7008 if opts.get(b'print0'):
7008 if opts.get(b'print0'):
7009 end = b'\0'
7009 end = b'\0'
7010 else:
7010 else:
7011 end = b'\n'
7011 end = b'\n'
7012 states = b'modified added removed deleted unknown ignored clean'.split()
7012 states = b'modified added removed deleted unknown ignored clean'.split()
7013 show = [k for k in states if opts.get(k)]
7013 show = [k for k in states if opts.get(k)]
7014 if opts.get(b'all'):
7014 if opts.get(b'all'):
7015 show += ui.quiet and (states[:4] + [b'clean']) or states
7015 show += ui.quiet and (states[:4] + [b'clean']) or states
7016
7016
7017 if not show:
7017 if not show:
7018 if ui.quiet:
7018 if ui.quiet:
7019 show = states[:4]
7019 show = states[:4]
7020 else:
7020 else:
7021 show = states[:5]
7021 show = states[:5]
7022
7022
7023 m = scmutil.match(ctx2, pats, opts)
7023 m = scmutil.match(ctx2, pats, opts)
7024 if terse:
7024 if terse:
7025 # we need to compute clean and unknown to terse
7025 # we need to compute clean and unknown to terse
7026 stat = repo.status(
7026 stat = repo.status(
7027 ctx1.node(),
7027 ctx1.node(),
7028 ctx2.node(),
7028 ctx2.node(),
7029 m,
7029 m,
7030 b'ignored' in show or b'i' in terse,
7030 b'ignored' in show or b'i' in terse,
7031 clean=True,
7031 clean=True,
7032 unknown=True,
7032 unknown=True,
7033 listsubrepos=opts.get(b'subrepos'),
7033 listsubrepos=opts.get(b'subrepos'),
7034 )
7034 )
7035
7035
7036 stat = cmdutil.tersedir(stat, terse)
7036 stat = cmdutil.tersedir(stat, terse)
7037 else:
7037 else:
7038 stat = repo.status(
7038 stat = repo.status(
7039 ctx1.node(),
7039 ctx1.node(),
7040 ctx2.node(),
7040 ctx2.node(),
7041 m,
7041 m,
7042 b'ignored' in show,
7042 b'ignored' in show,
7043 b'clean' in show,
7043 b'clean' in show,
7044 b'unknown' in show,
7044 b'unknown' in show,
7045 opts.get(b'subrepos'),
7045 opts.get(b'subrepos'),
7046 )
7046 )
7047
7047
7048 changestates = zip(
7048 changestates = zip(
7049 states,
7049 states,
7050 pycompat.iterbytestr(b'MAR!?IC'),
7050 pycompat.iterbytestr(b'MAR!?IC'),
7051 [getattr(stat, s.decode('utf8')) for s in states],
7051 [getattr(stat, s.decode('utf8')) for s in states],
7052 )
7052 )
7053
7053
7054 copy = {}
7054 copy = {}
7055 show_copies = ui.configbool(b'ui', b'statuscopies')
7055 show_copies = ui.configbool(b'ui', b'statuscopies')
7056 if opts.get(b'copies') is not None:
7056 if opts.get(b'copies') is not None:
7057 show_copies = opts.get(b'copies')
7057 show_copies = opts.get(b'copies')
7058 show_copies = (show_copies or opts.get(b'all')) and not opts.get(
7058 show_copies = (show_copies or opts.get(b'all')) and not opts.get(
7059 b'no_status'
7059 b'no_status'
7060 )
7060 )
7061 if show_copies:
7061 if show_copies:
7062 copy = copies.pathcopies(ctx1, ctx2, m)
7062 copy = copies.pathcopies(ctx1, ctx2, m)
7063
7063
7064 morestatus = None
7064 morestatus = None
7065 if (
7065 if (
7066 (ui.verbose or ui.configbool(b'commands', b'status.verbose'))
7066 (ui.verbose or ui.configbool(b'commands', b'status.verbose'))
7067 and not ui.plain()
7067 and not ui.plain()
7068 and not opts.get(b'print0')
7068 and not opts.get(b'print0')
7069 ):
7069 ):
7070 morestatus = cmdutil.readmorestatus(repo)
7070 morestatus = cmdutil.readmorestatus(repo)
7071
7071
7072 ui.pager(b'status')
7072 ui.pager(b'status')
7073 fm = ui.formatter(b'status', opts)
7073 fm = ui.formatter(b'status', opts)
7074 fmt = b'%s' + end
7074 fmt = b'%s' + end
7075 showchar = not opts.get(b'no_status')
7075 showchar = not opts.get(b'no_status')
7076
7076
7077 for state, char, files in changestates:
7077 for state, char, files in changestates:
7078 if state in show:
7078 if state in show:
7079 label = b'status.' + state
7079 label = b'status.' + state
7080 for f in files:
7080 for f in files:
7081 fm.startitem()
7081 fm.startitem()
7082 fm.context(ctx=ctx2)
7082 fm.context(ctx=ctx2)
7083 fm.data(itemtype=b'file', path=f)
7083 fm.data(itemtype=b'file', path=f)
7084 fm.condwrite(showchar, b'status', b'%s ', char, label=label)
7084 fm.condwrite(showchar, b'status', b'%s ', char, label=label)
7085 fm.plain(fmt % uipathfn(f), label=label)
7085 fm.plain(fmt % uipathfn(f), label=label)
7086 if f in copy:
7086 if f in copy:
7087 fm.data(source=copy[f])
7087 fm.data(source=copy[f])
7088 fm.plain(
7088 fm.plain(
7089 (b' %s' + end) % uipathfn(copy[f]),
7089 (b' %s' + end) % uipathfn(copy[f]),
7090 label=b'status.copied',
7090 label=b'status.copied',
7091 )
7091 )
7092 if morestatus:
7092 if morestatus:
7093 morestatus.formatfile(f, fm)
7093 morestatus.formatfile(f, fm)
7094
7094
7095 if morestatus:
7095 if morestatus:
7096 morestatus.formatfooter(fm)
7096 morestatus.formatfooter(fm)
7097 fm.end()
7097 fm.end()
7098
7098
7099
7099
7100 @command(
7100 @command(
7101 b'summary|sum',
7101 b'summary|sum',
7102 [(b'', b'remote', None, _(b'check for push and pull'))],
7102 [(b'', b'remote', None, _(b'check for push and pull'))],
7103 b'[--remote]',
7103 b'[--remote]',
7104 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7104 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7105 helpbasic=True,
7105 helpbasic=True,
7106 intents={INTENT_READONLY},
7106 intents={INTENT_READONLY},
7107 )
7107 )
7108 def summary(ui, repo, **opts):
7108 def summary(ui, repo, **opts):
7109 """summarize working directory state
7109 """summarize working directory state
7110
7110
7111 This generates a brief summary of the working directory state,
7111 This generates a brief summary of the working directory state,
7112 including parents, branch, commit status, phase and available updates.
7112 including parents, branch, commit status, phase and available updates.
7113
7113
7114 With the --remote option, this will check the default paths for
7114 With the --remote option, this will check the default paths for
7115 incoming and outgoing changes. This can be time-consuming.
7115 incoming and outgoing changes. This can be time-consuming.
7116
7116
7117 Returns 0 on success.
7117 Returns 0 on success.
7118 """
7118 """
7119
7119
7120 ui.pager(b'summary')
7120 ui.pager(b'summary')
7121 ctx = repo[None]
7121 ctx = repo[None]
7122 parents = ctx.parents()
7122 parents = ctx.parents()
7123 pnode = parents[0].node()
7123 pnode = parents[0].node()
7124 marks = []
7124 marks = []
7125
7125
7126 try:
7126 try:
7127 ms = mergestatemod.mergestate.read(repo)
7127 ms = mergestatemod.mergestate.read(repo)
7128 except error.UnsupportedMergeRecords as e:
7128 except error.UnsupportedMergeRecords as e:
7129 s = b' '.join(e.recordtypes)
7129 s = b' '.join(e.recordtypes)
7130 ui.warn(
7130 ui.warn(
7131 _(b'warning: merge state has unsupported record types: %s\n') % s
7131 _(b'warning: merge state has unsupported record types: %s\n') % s
7132 )
7132 )
7133 unresolved = []
7133 unresolved = []
7134 else:
7134 else:
7135 unresolved = list(ms.unresolved())
7135 unresolved = list(ms.unresolved())
7136
7136
7137 for p in parents:
7137 for p in parents:
7138 # label with log.changeset (instead of log.parent) since this
7138 # label with log.changeset (instead of log.parent) since this
7139 # shows a working directory parent *changeset*:
7139 # shows a working directory parent *changeset*:
7140 # i18n: column positioning for "hg summary"
7140 # i18n: column positioning for "hg summary"
7141 ui.write(
7141 ui.write(
7142 _(b'parent: %d:%s ') % (p.rev(), p),
7142 _(b'parent: %d:%s ') % (p.rev(), p),
7143 label=logcmdutil.changesetlabels(p),
7143 label=logcmdutil.changesetlabels(p),
7144 )
7144 )
7145 ui.write(b' '.join(p.tags()), label=b'log.tag')
7145 ui.write(b' '.join(p.tags()), label=b'log.tag')
7146 if p.bookmarks():
7146 if p.bookmarks():
7147 marks.extend(p.bookmarks())
7147 marks.extend(p.bookmarks())
7148 if p.rev() == -1:
7148 if p.rev() == -1:
7149 if not len(repo):
7149 if not len(repo):
7150 ui.write(_(b' (empty repository)'))
7150 ui.write(_(b' (empty repository)'))
7151 else:
7151 else:
7152 ui.write(_(b' (no revision checked out)'))
7152 ui.write(_(b' (no revision checked out)'))
7153 if p.obsolete():
7153 if p.obsolete():
7154 ui.write(_(b' (obsolete)'))
7154 ui.write(_(b' (obsolete)'))
7155 if p.isunstable():
7155 if p.isunstable():
7156 instabilities = (
7156 instabilities = (
7157 ui.label(instability, b'trouble.%s' % instability)
7157 ui.label(instability, b'trouble.%s' % instability)
7158 for instability in p.instabilities()
7158 for instability in p.instabilities()
7159 )
7159 )
7160 ui.write(b' (' + b', '.join(instabilities) + b')')
7160 ui.write(b' (' + b', '.join(instabilities) + b')')
7161 ui.write(b'\n')
7161 ui.write(b'\n')
7162 if p.description():
7162 if p.description():
7163 ui.status(
7163 ui.status(
7164 b' ' + p.description().splitlines()[0].strip() + b'\n',
7164 b' ' + p.description().splitlines()[0].strip() + b'\n',
7165 label=b'log.summary',
7165 label=b'log.summary',
7166 )
7166 )
7167
7167
7168 branch = ctx.branch()
7168 branch = ctx.branch()
7169 bheads = repo.branchheads(branch)
7169 bheads = repo.branchheads(branch)
7170 # i18n: column positioning for "hg summary"
7170 # i18n: column positioning for "hg summary"
7171 m = _(b'branch: %s\n') % branch
7171 m = _(b'branch: %s\n') % branch
7172 if branch != b'default':
7172 if branch != b'default':
7173 ui.write(m, label=b'log.branch')
7173 ui.write(m, label=b'log.branch')
7174 else:
7174 else:
7175 ui.status(m, label=b'log.branch')
7175 ui.status(m, label=b'log.branch')
7176
7176
7177 if marks:
7177 if marks:
7178 active = repo._activebookmark
7178 active = repo._activebookmark
7179 # i18n: column positioning for "hg summary"
7179 # i18n: column positioning for "hg summary"
7180 ui.write(_(b'bookmarks:'), label=b'log.bookmark')
7180 ui.write(_(b'bookmarks:'), label=b'log.bookmark')
7181 if active is not None:
7181 if active is not None:
7182 if active in marks:
7182 if active in marks:
7183 ui.write(b' *' + active, label=bookmarks.activebookmarklabel)
7183 ui.write(b' *' + active, label=bookmarks.activebookmarklabel)
7184 marks.remove(active)
7184 marks.remove(active)
7185 else:
7185 else:
7186 ui.write(b' [%s]' % active, label=bookmarks.activebookmarklabel)
7186 ui.write(b' [%s]' % active, label=bookmarks.activebookmarklabel)
7187 for m in marks:
7187 for m in marks:
7188 ui.write(b' ' + m, label=b'log.bookmark')
7188 ui.write(b' ' + m, label=b'log.bookmark')
7189 ui.write(b'\n', label=b'log.bookmark')
7189 ui.write(b'\n', label=b'log.bookmark')
7190
7190
7191 status = repo.status(unknown=True)
7191 status = repo.status(unknown=True)
7192
7192
7193 c = repo.dirstate.copies()
7193 c = repo.dirstate.copies()
7194 copied, renamed = [], []
7194 copied, renamed = [], []
7195 for d, s in c.items():
7195 for d, s in c.items():
7196 if s in status.removed:
7196 if s in status.removed:
7197 status.removed.remove(s)
7197 status.removed.remove(s)
7198 renamed.append(d)
7198 renamed.append(d)
7199 else:
7199 else:
7200 copied.append(d)
7200 copied.append(d)
7201 if d in status.added:
7201 if d in status.added:
7202 status.added.remove(d)
7202 status.added.remove(d)
7203
7203
7204 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
7204 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
7205
7205
7206 labels = [
7206 labels = [
7207 (ui.label(_(b'%d modified'), b'status.modified'), status.modified),
7207 (ui.label(_(b'%d modified'), b'status.modified'), status.modified),
7208 (ui.label(_(b'%d added'), b'status.added'), status.added),
7208 (ui.label(_(b'%d added'), b'status.added'), status.added),
7209 (ui.label(_(b'%d removed'), b'status.removed'), status.removed),
7209 (ui.label(_(b'%d removed'), b'status.removed'), status.removed),
7210 (ui.label(_(b'%d renamed'), b'status.copied'), renamed),
7210 (ui.label(_(b'%d renamed'), b'status.copied'), renamed),
7211 (ui.label(_(b'%d copied'), b'status.copied'), copied),
7211 (ui.label(_(b'%d copied'), b'status.copied'), copied),
7212 (ui.label(_(b'%d deleted'), b'status.deleted'), status.deleted),
7212 (ui.label(_(b'%d deleted'), b'status.deleted'), status.deleted),
7213 (ui.label(_(b'%d unknown'), b'status.unknown'), status.unknown),
7213 (ui.label(_(b'%d unknown'), b'status.unknown'), status.unknown),
7214 (ui.label(_(b'%d unresolved'), b'resolve.unresolved'), unresolved),
7214 (ui.label(_(b'%d unresolved'), b'resolve.unresolved'), unresolved),
7215 (ui.label(_(b'%d subrepos'), b'status.modified'), subs),
7215 (ui.label(_(b'%d subrepos'), b'status.modified'), subs),
7216 ]
7216 ]
7217 t = []
7217 t = []
7218 for l, s in labels:
7218 for l, s in labels:
7219 if s:
7219 if s:
7220 t.append(l % len(s))
7220 t.append(l % len(s))
7221
7221
7222 t = b', '.join(t)
7222 t = b', '.join(t)
7223 cleanworkdir = False
7223 cleanworkdir = False
7224
7224
7225 if repo.vfs.exists(b'graftstate'):
7225 if repo.vfs.exists(b'graftstate'):
7226 t += _(b' (graft in progress)')
7226 t += _(b' (graft in progress)')
7227 if repo.vfs.exists(b'updatestate'):
7227 if repo.vfs.exists(b'updatestate'):
7228 t += _(b' (interrupted update)')
7228 t += _(b' (interrupted update)')
7229 elif len(parents) > 1:
7229 elif len(parents) > 1:
7230 t += _(b' (merge)')
7230 t += _(b' (merge)')
7231 elif branch != parents[0].branch():
7231 elif branch != parents[0].branch():
7232 t += _(b' (new branch)')
7232 t += _(b' (new branch)')
7233 elif parents[0].closesbranch() and pnode in repo.branchheads(
7233 elif parents[0].closesbranch() and pnode in repo.branchheads(
7234 branch, closed=True
7234 branch, closed=True
7235 ):
7235 ):
7236 t += _(b' (head closed)')
7236 t += _(b' (head closed)')
7237 elif not (
7237 elif not (
7238 status.modified
7238 status.modified
7239 or status.added
7239 or status.added
7240 or status.removed
7240 or status.removed
7241 or renamed
7241 or renamed
7242 or copied
7242 or copied
7243 or subs
7243 or subs
7244 ):
7244 ):
7245 t += _(b' (clean)')
7245 t += _(b' (clean)')
7246 cleanworkdir = True
7246 cleanworkdir = True
7247 elif pnode not in bheads:
7247 elif pnode not in bheads:
7248 t += _(b' (new branch head)')
7248 t += _(b' (new branch head)')
7249
7249
7250 if parents:
7250 if parents:
7251 pendingphase = max(p.phase() for p in parents)
7251 pendingphase = max(p.phase() for p in parents)
7252 else:
7252 else:
7253 pendingphase = phases.public
7253 pendingphase = phases.public
7254
7254
7255 if pendingphase > phases.newcommitphase(ui):
7255 if pendingphase > phases.newcommitphase(ui):
7256 t += b' (%s)' % phases.phasenames[pendingphase]
7256 t += b' (%s)' % phases.phasenames[pendingphase]
7257
7257
7258 if cleanworkdir:
7258 if cleanworkdir:
7259 # i18n: column positioning for "hg summary"
7259 # i18n: column positioning for "hg summary"
7260 ui.status(_(b'commit: %s\n') % t.strip())
7260 ui.status(_(b'commit: %s\n') % t.strip())
7261 else:
7261 else:
7262 # i18n: column positioning for "hg summary"
7262 # i18n: column positioning for "hg summary"
7263 ui.write(_(b'commit: %s\n') % t.strip())
7263 ui.write(_(b'commit: %s\n') % t.strip())
7264
7264
7265 # all ancestors of branch heads - all ancestors of parent = new csets
7265 # all ancestors of branch heads - all ancestors of parent = new csets
7266 new = len(
7266 new = len(
7267 repo.changelog.findmissing([pctx.node() for pctx in parents], bheads)
7267 repo.changelog.findmissing([pctx.node() for pctx in parents], bheads)
7268 )
7268 )
7269
7269
7270 if new == 0:
7270 if new == 0:
7271 # i18n: column positioning for "hg summary"
7271 # i18n: column positioning for "hg summary"
7272 ui.status(_(b'update: (current)\n'))
7272 ui.status(_(b'update: (current)\n'))
7273 elif pnode not in bheads:
7273 elif pnode not in bheads:
7274 # i18n: column positioning for "hg summary"
7274 # i18n: column positioning for "hg summary"
7275 ui.write(_(b'update: %d new changesets (update)\n') % new)
7275 ui.write(_(b'update: %d new changesets (update)\n') % new)
7276 else:
7276 else:
7277 # i18n: column positioning for "hg summary"
7277 # i18n: column positioning for "hg summary"
7278 ui.write(
7278 ui.write(
7279 _(b'update: %d new changesets, %d branch heads (merge)\n')
7279 _(b'update: %d new changesets, %d branch heads (merge)\n')
7280 % (new, len(bheads))
7280 % (new, len(bheads))
7281 )
7281 )
7282
7282
7283 t = []
7283 t = []
7284 draft = len(repo.revs(b'draft()'))
7284 draft = len(repo.revs(b'draft()'))
7285 if draft:
7285 if draft:
7286 t.append(_(b'%d draft') % draft)
7286 t.append(_(b'%d draft') % draft)
7287 secret = len(repo.revs(b'secret()'))
7287 secret = len(repo.revs(b'secret()'))
7288 if secret:
7288 if secret:
7289 t.append(_(b'%d secret') % secret)
7289 t.append(_(b'%d secret') % secret)
7290
7290
7291 if draft or secret:
7291 if draft or secret:
7292 ui.status(_(b'phases: %s\n') % b', '.join(t))
7292 ui.status(_(b'phases: %s\n') % b', '.join(t))
7293
7293
7294 if obsolete.isenabled(repo, obsolete.createmarkersopt):
7294 if obsolete.isenabled(repo, obsolete.createmarkersopt):
7295 for trouble in (b"orphan", b"contentdivergent", b"phasedivergent"):
7295 for trouble in (b"orphan", b"contentdivergent", b"phasedivergent"):
7296 numtrouble = len(repo.revs(trouble + b"()"))
7296 numtrouble = len(repo.revs(trouble + b"()"))
7297 # We write all the possibilities to ease translation
7297 # We write all the possibilities to ease translation
7298 troublemsg = {
7298 troublemsg = {
7299 b"orphan": _(b"orphan: %d changesets"),
7299 b"orphan": _(b"orphan: %d changesets"),
7300 b"contentdivergent": _(b"content-divergent: %d changesets"),
7300 b"contentdivergent": _(b"content-divergent: %d changesets"),
7301 b"phasedivergent": _(b"phase-divergent: %d changesets"),
7301 b"phasedivergent": _(b"phase-divergent: %d changesets"),
7302 }
7302 }
7303 if numtrouble > 0:
7303 if numtrouble > 0:
7304 ui.status(troublemsg[trouble] % numtrouble + b"\n")
7304 ui.status(troublemsg[trouble] % numtrouble + b"\n")
7305
7305
7306 cmdutil.summaryhooks(ui, repo)
7306 cmdutil.summaryhooks(ui, repo)
7307
7307
7308 if opts.get('remote'):
7308 if opts.get('remote'):
7309 needsincoming, needsoutgoing = True, True
7309 needsincoming, needsoutgoing = True, True
7310 else:
7310 else:
7311 needsincoming, needsoutgoing = False, False
7311 needsincoming, needsoutgoing = False, False
7312 for i, o in cmdutil.summaryremotehooks(
7312 for i, o in cmdutil.summaryremotehooks(
7313 ui, repo, pycompat.byteskwargs(opts), None
7313 ui, repo, pycompat.byteskwargs(opts), None
7314 ):
7314 ):
7315 if i:
7315 if i:
7316 needsincoming = True
7316 needsincoming = True
7317 if o:
7317 if o:
7318 needsoutgoing = True
7318 needsoutgoing = True
7319 if not needsincoming and not needsoutgoing:
7319 if not needsincoming and not needsoutgoing:
7320 return
7320 return
7321
7321
7322 def getincoming():
7322 def getincoming():
7323 # XXX We should actually skip this if no default is specified, instead
7323 # XXX We should actually skip this if no default is specified, instead
7324 # of passing "default" which will resolve as "./default/" if no default
7324 # of passing "default" which will resolve as "./default/" if no default
7325 # path is defined.
7325 # path is defined.
7326 path = urlutil.get_unique_pull_path_obj(b'summary', ui, b'default')
7326 path = urlutil.get_unique_pull_path_obj(b'summary', ui, b'default')
7327 sbranch = path.branch
7327 sbranch = path.branch
7328 try:
7328 try:
7329 other = hg.peer(repo, {}, path)
7329 other = hg.peer(repo, {}, path)
7330 except error.RepoError:
7330 except error.RepoError:
7331 if opts.get('remote'):
7331 if opts.get('remote'):
7332 raise
7332 raise
7333 return path.loc, sbranch, None, None, None
7333 return path.loc, sbranch, None, None, None
7334 branches = (path.branch, [])
7334 branches = (path.branch, [])
7335 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
7335 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
7336 if revs:
7336 if revs:
7337 revs = [other.lookup(rev) for rev in revs]
7337 revs = [other.lookup(rev) for rev in revs]
7338 ui.debug(b'comparing with %s\n' % urlutil.hidepassword(path.loc))
7338 ui.debug(b'comparing with %s\n' % urlutil.hidepassword(path.loc))
7339 with repo.ui.silent():
7339 with repo.ui.silent():
7340 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
7340 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
7341 return path.loc, sbranch, other, commoninc, commoninc[1]
7341 return path.loc, sbranch, other, commoninc, commoninc[1]
7342
7342
7343 if needsincoming:
7343 if needsincoming:
7344 source, sbranch, sother, commoninc, incoming = getincoming()
7344 source, sbranch, sother, commoninc, incoming = getincoming()
7345 else:
7345 else:
7346 source = sbranch = sother = commoninc = incoming = None
7346 source = sbranch = sother = commoninc = incoming = None
7347
7347
7348 def getoutgoing():
7348 def getoutgoing():
7349 # XXX We should actually skip this if no default is specified, instead
7349 # XXX We should actually skip this if no default is specified, instead
7350 # of passing "default" which will resolve as "./default/" if no default
7350 # of passing "default" which will resolve as "./default/" if no default
7351 # path is defined.
7351 # path is defined.
7352 d = None
7352 d = None
7353 if b'default-push' in ui.paths:
7353 if b'default-push' in ui.paths:
7354 d = b'default-push'
7354 d = b'default-push'
7355 elif b'default' in ui.paths:
7355 elif b'default' in ui.paths:
7356 d = b'default'
7356 d = b'default'
7357 path = None
7357 path = None
7358 if d is not None:
7358 if d is not None:
7359 path = urlutil.get_unique_push_path(b'summary', repo, ui, d)
7359 path = urlutil.get_unique_push_path(b'summary', repo, ui, d)
7360 dest = path.loc
7360 dest = path.loc
7361 dbranch = path.branch
7361 dbranch = path.branch
7362 else:
7362 else:
7363 dest = b'default'
7363 dest = b'default'
7364 dbranch = None
7364 dbranch = None
7365 revs, checkout = hg.addbranchrevs(repo, repo, (dbranch, []), None)
7365 revs, checkout = hg.addbranchrevs(repo, repo, (dbranch, []), None)
7366 if source != dest:
7366 if source != dest:
7367 try:
7367 try:
7368 dother = hg.peer(repo, {}, path if path is not None else dest)
7368 dother = hg.peer(repo, {}, path if path is not None else dest)
7369 except error.RepoError:
7369 except error.RepoError:
7370 if opts.get('remote'):
7370 if opts.get('remote'):
7371 raise
7371 raise
7372 return dest, dbranch, None, None
7372 return dest, dbranch, None, None
7373 ui.debug(b'comparing with %s\n' % urlutil.hidepassword(dest))
7373 ui.debug(b'comparing with %s\n' % urlutil.hidepassword(dest))
7374 elif sother is None:
7374 elif sother is None:
7375 # there is no explicit destination peer, but source one is invalid
7375 # there is no explicit destination peer, but source one is invalid
7376 return dest, dbranch, None, None
7376 return dest, dbranch, None, None
7377 else:
7377 else:
7378 dother = sother
7378 dother = sother
7379 if source != dest or (sbranch is not None and sbranch != dbranch):
7379 if source != dest or (sbranch is not None and sbranch != dbranch):
7380 common = None
7380 common = None
7381 else:
7381 else:
7382 common = commoninc
7382 common = commoninc
7383 if revs:
7383 if revs:
7384 revs = [repo.lookup(rev) for rev in revs]
7384 revs = [repo.lookup(rev) for rev in revs]
7385 with repo.ui.silent():
7385 with repo.ui.silent():
7386 outgoing = discovery.findcommonoutgoing(
7386 outgoing = discovery.findcommonoutgoing(
7387 repo, dother, onlyheads=revs, commoninc=common
7387 repo, dother, onlyheads=revs, commoninc=common
7388 )
7388 )
7389 return dest, dbranch, dother, outgoing
7389 return dest, dbranch, dother, outgoing
7390
7390
7391 if needsoutgoing:
7391 if needsoutgoing:
7392 dest, dbranch, dother, outgoing = getoutgoing()
7392 dest, dbranch, dother, outgoing = getoutgoing()
7393 else:
7393 else:
7394 dest = dbranch = dother = outgoing = None
7394 dest = dbranch = dother = outgoing = None
7395
7395
7396 if opts.get('remote'):
7396 if opts.get('remote'):
7397 # Help pytype. --remote sets both `needsincoming` and `needsoutgoing`.
7397 # Help pytype. --remote sets both `needsincoming` and `needsoutgoing`.
7398 # The former always sets `sother` (or raises an exception if it can't);
7398 # The former always sets `sother` (or raises an exception if it can't);
7399 # the latter always sets `outgoing`.
7399 # the latter always sets `outgoing`.
7400 assert sother is not None
7400 assert sother is not None
7401 assert outgoing is not None
7401 assert outgoing is not None
7402
7402
7403 t = []
7403 t = []
7404 if incoming:
7404 if incoming:
7405 t.append(_(b'1 or more incoming'))
7405 t.append(_(b'1 or more incoming'))
7406 o = outgoing.missing
7406 o = outgoing.missing
7407 if o:
7407 if o:
7408 t.append(_(b'%d outgoing') % len(o))
7408 t.append(_(b'%d outgoing') % len(o))
7409 other = dother or sother
7409 other = dother or sother
7410 if b'bookmarks' in other.listkeys(b'namespaces'):
7410 if b'bookmarks' in other.listkeys(b'namespaces'):
7411 counts = bookmarks.summary(repo, other)
7411 counts = bookmarks.summary(repo, other)
7412 if counts[0] > 0:
7412 if counts[0] > 0:
7413 t.append(_(b'%d incoming bookmarks') % counts[0])
7413 t.append(_(b'%d incoming bookmarks') % counts[0])
7414 if counts[1] > 0:
7414 if counts[1] > 0:
7415 t.append(_(b'%d outgoing bookmarks') % counts[1])
7415 t.append(_(b'%d outgoing bookmarks') % counts[1])
7416
7416
7417 if t:
7417 if t:
7418 # i18n: column positioning for "hg summary"
7418 # i18n: column positioning for "hg summary"
7419 ui.write(_(b'remote: %s\n') % (b', '.join(t)))
7419 ui.write(_(b'remote: %s\n') % (b', '.join(t)))
7420 else:
7420 else:
7421 # i18n: column positioning for "hg summary"
7421 # i18n: column positioning for "hg summary"
7422 ui.status(_(b'remote: (synced)\n'))
7422 ui.status(_(b'remote: (synced)\n'))
7423
7423
7424 cmdutil.summaryremotehooks(
7424 cmdutil.summaryremotehooks(
7425 ui,
7425 ui,
7426 repo,
7426 repo,
7427 pycompat.byteskwargs(opts),
7427 pycompat.byteskwargs(opts),
7428 (
7428 (
7429 (source, sbranch, sother, commoninc),
7429 (source, sbranch, sother, commoninc),
7430 (dest, dbranch, dother, outgoing),
7430 (dest, dbranch, dother, outgoing),
7431 ),
7431 ),
7432 )
7432 )
7433
7433
7434
7434
7435 @command(
7435 @command(
7436 b'tag',
7436 b'tag',
7437 [
7437 [
7438 (b'f', b'force', None, _(b'force tag')),
7438 (b'f', b'force', None, _(b'force tag')),
7439 (b'l', b'local', None, _(b'make the tag local')),
7439 (b'l', b'local', None, _(b'make the tag local')),
7440 (b'r', b'rev', b'', _(b'revision to tag'), _(b'REV')),
7440 (b'r', b'rev', b'', _(b'revision to tag'), _(b'REV')),
7441 (b'', b'remove', None, _(b'remove a tag')),
7441 (b'', b'remove', None, _(b'remove a tag')),
7442 # -l/--local is already there, commitopts cannot be used
7442 # -l/--local is already there, commitopts cannot be used
7443 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
7443 (b'e', b'edit', None, _(b'invoke editor on commit messages')),
7444 (b'm', b'message', b'', _(b'use text as commit message'), _(b'TEXT')),
7444 (b'm', b'message', b'', _(b'use text as commit message'), _(b'TEXT')),
7445 ]
7445 ]
7446 + commitopts2,
7446 + commitopts2,
7447 _(b'[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
7447 _(b'[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
7448 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7448 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7449 )
7449 )
7450 def tag(ui, repo, name1, *names, **opts):
7450 def tag(ui, repo, name1, *names, **opts):
7451 """add one or more tags for the current or given revision
7451 """add one or more tags for the current or given revision
7452
7452
7453 Name a particular revision using <name>.
7453 Name a particular revision using <name>.
7454
7454
7455 Tags are used to name particular revisions of the repository and are
7455 Tags are used to name particular revisions of the repository and are
7456 very useful to compare different revisions, to go back to significant
7456 very useful to compare different revisions, to go back to significant
7457 earlier versions or to mark branch points as releases, etc. Changing
7457 earlier versions or to mark branch points as releases, etc. Changing
7458 an existing tag is normally disallowed; use -f/--force to override.
7458 an existing tag is normally disallowed; use -f/--force to override.
7459
7459
7460 If no revision is given, the parent of the working directory is
7460 If no revision is given, the parent of the working directory is
7461 used.
7461 used.
7462
7462
7463 To facilitate version control, distribution, and merging of tags,
7463 To facilitate version control, distribution, and merging of tags,
7464 they are stored as a file named ".hgtags" which is managed similarly
7464 they are stored as a file named ".hgtags" which is managed similarly
7465 to other project files and can be hand-edited if necessary. This
7465 to other project files and can be hand-edited if necessary. This
7466 also means that tagging creates a new commit. The file
7466 also means that tagging creates a new commit. The file
7467 ".hg/localtags" is used for local tags (not shared among
7467 ".hg/localtags" is used for local tags (not shared among
7468 repositories).
7468 repositories).
7469
7469
7470 Tag commits are usually made at the head of a branch. If the parent
7470 Tag commits are usually made at the head of a branch. If the parent
7471 of the working directory is not a branch head, :hg:`tag` aborts; use
7471 of the working directory is not a branch head, :hg:`tag` aborts; use
7472 -f/--force to force the tag commit to be based on a non-head
7472 -f/--force to force the tag commit to be based on a non-head
7473 changeset.
7473 changeset.
7474
7474
7475 See :hg:`help dates` for a list of formats valid for -d/--date.
7475 See :hg:`help dates` for a list of formats valid for -d/--date.
7476
7476
7477 Since tag names have priority over branch names during revision
7477 Since tag names have priority over branch names during revision
7478 lookup, using an existing branch name as a tag name is discouraged.
7478 lookup, using an existing branch name as a tag name is discouraged.
7479
7479
7480 Returns 0 on success.
7480 Returns 0 on success.
7481 """
7481 """
7482 cmdutil.check_incompatible_arguments(opts, 'remove', ['rev'])
7482 cmdutil.check_incompatible_arguments(opts, 'remove', ['rev'])
7483
7483
7484 with repo.wlock(), repo.lock():
7484 with repo.wlock(), repo.lock():
7485 rev_ = b"."
7485 rev_ = b"."
7486 names = [t.strip() for t in (name1,) + names]
7486 names = [t.strip() for t in (name1,) + names]
7487 if len(names) != len(set(names)):
7487 if len(names) != len(set(names)):
7488 raise error.InputError(_(b'tag names must be unique'))
7488 raise error.InputError(_(b'tag names must be unique'))
7489 for n in names:
7489 for n in names:
7490 scmutil.checknewlabel(repo, n, b'tag')
7490 scmutil.checknewlabel(repo, n, b'tag')
7491 if not n:
7491 if not n:
7492 raise error.InputError(
7492 raise error.InputError(
7493 _(b'tag names cannot consist entirely of whitespace')
7493 _(b'tag names cannot consist entirely of whitespace')
7494 )
7494 )
7495 if opts.get('rev'):
7495 if opts.get('rev'):
7496 rev_ = opts['rev']
7496 rev_ = opts['rev']
7497 message = opts.get('message')
7497 message = opts.get('message')
7498 if opts.get('remove'):
7498 if opts.get('remove'):
7499 if opts.get('local'):
7499 if opts.get('local'):
7500 expectedtype = b'local'
7500 expectedtype = b'local'
7501 else:
7501 else:
7502 expectedtype = b'global'
7502 expectedtype = b'global'
7503
7503
7504 for n in names:
7504 for n in names:
7505 if repo.tagtype(n) == b'global':
7505 if repo.tagtype(n) == b'global':
7506 alltags = tagsmod.findglobaltags(ui, repo)
7506 alltags = tagsmod.findglobaltags(ui, repo)
7507 if alltags[n][0] == repo.nullid:
7507 if alltags[n][0] == repo.nullid:
7508 raise error.InputError(
7508 raise error.InputError(
7509 _(b"tag '%s' is already removed") % n
7509 _(b"tag '%s' is already removed") % n
7510 )
7510 )
7511 if not repo.tagtype(n):
7511 if not repo.tagtype(n):
7512 raise error.InputError(_(b"tag '%s' does not exist") % n)
7512 raise error.InputError(_(b"tag '%s' does not exist") % n)
7513 if repo.tagtype(n) != expectedtype:
7513 if repo.tagtype(n) != expectedtype:
7514 if expectedtype == b'global':
7514 if expectedtype == b'global':
7515 raise error.InputError(
7515 raise error.InputError(
7516 _(b"tag '%s' is not a global tag") % n
7516 _(b"tag '%s' is not a global tag") % n
7517 )
7517 )
7518 else:
7518 else:
7519 raise error.InputError(
7519 raise error.InputError(
7520 _(b"tag '%s' is not a local tag") % n
7520 _(b"tag '%s' is not a local tag") % n
7521 )
7521 )
7522 rev_ = b'null'
7522 rev_ = b'null'
7523 if not message:
7523 if not message:
7524 # we don't translate commit messages
7524 # we don't translate commit messages
7525 message = b'Removed tag %s' % b', '.join(names)
7525 message = b'Removed tag %s' % b', '.join(names)
7526 elif not opts.get('force'):
7526 elif not opts.get('force'):
7527 for n in names:
7527 for n in names:
7528 if n in repo.tags():
7528 if n in repo.tags():
7529 raise error.InputError(
7529 raise error.InputError(
7530 _(b"tag '%s' already exists (use -f to force)") % n
7530 _(b"tag '%s' already exists (use -f to force)") % n
7531 )
7531 )
7532 if not opts.get('local'):
7532 if not opts.get('local'):
7533 p1, p2 = repo.dirstate.parents()
7533 p1, p2 = repo.dirstate.parents()
7534 if p2 != repo.nullid:
7534 if p2 != repo.nullid:
7535 raise error.StateError(_(b'uncommitted merge'))
7535 raise error.StateError(_(b'uncommitted merge'))
7536 bheads = repo.branchheads()
7536 bheads = repo.branchheads()
7537 if not opts.get('force') and bheads and p1 not in bheads:
7537 if not opts.get('force') and bheads and p1 not in bheads:
7538 raise error.InputError(
7538 raise error.InputError(
7539 _(
7539 _(
7540 b'working directory is not at a branch head '
7540 b'working directory is not at a branch head '
7541 b'(use -f to force)'
7541 b'(use -f to force)'
7542 )
7542 )
7543 )
7543 )
7544 node = logcmdutil.revsingle(repo, rev_).node()
7544 node = logcmdutil.revsingle(repo, rev_).node()
7545
7545
7546 # don't allow tagging the null rev or the working directory
7546 # don't allow tagging the null rev or the working directory
7547 if node is None:
7547 if node is None:
7548 raise error.InputError(_(b"cannot tag working directory"))
7548 raise error.InputError(_(b"cannot tag working directory"))
7549 elif not opts.get('remove') and node == nullid:
7549 elif not opts.get('remove') and node == nullid:
7550 raise error.InputError(_(b"cannot tag null revision"))
7550 raise error.InputError(_(b"cannot tag null revision"))
7551
7551
7552 if not message:
7552 if not message:
7553 # we don't translate commit messages
7553 # we don't translate commit messages
7554 message = b'Added tag %s for changeset %s' % (
7554 message = b'Added tag %s for changeset %s' % (
7555 b', '.join(names),
7555 b', '.join(names),
7556 short(node),
7556 short(node),
7557 )
7557 )
7558
7558
7559 date = opts.get('date')
7559 date = opts.get('date')
7560 if date:
7560 if date:
7561 date = dateutil.parsedate(date)
7561 date = dateutil.parsedate(date)
7562
7562
7563 if opts.get('remove'):
7563 if opts.get('remove'):
7564 editform = b'tag.remove'
7564 editform = b'tag.remove'
7565 else:
7565 else:
7566 editform = b'tag.add'
7566 editform = b'tag.add'
7567 editor = cmdutil.getcommiteditor(editform=editform, **opts)
7567 editor = cmdutil.getcommiteditor(editform=editform, **opts)
7568
7568
7569 tagsmod.tag(
7569 tagsmod.tag(
7570 repo,
7570 repo,
7571 names,
7571 names,
7572 node,
7572 node,
7573 message,
7573 message,
7574 opts.get('local'),
7574 opts.get('local'),
7575 opts.get('user'),
7575 opts.get('user'),
7576 date,
7576 date,
7577 editor=editor,
7577 editor=editor,
7578 )
7578 )
7579
7579
7580
7580
7581 @command(
7581 @command(
7582 b'tags',
7582 b'tags',
7583 formatteropts,
7583 formatteropts,
7584 b'',
7584 b'',
7585 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7585 helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
7586 intents={INTENT_READONLY},
7586 intents={INTENT_READONLY},
7587 )
7587 )
7588 def tags(ui, repo, **opts):
7588 def tags(ui, repo, **opts):
7589 """list repository tags
7589 """list repository tags
7590
7590
7591 This lists both regular and local tags. When the -v/--verbose
7591 This lists both regular and local tags. When the -v/--verbose
7592 switch is used, a third column "local" is printed for local tags.
7592 switch is used, a third column "local" is printed for local tags.
7593 When the -q/--quiet switch is used, only the tag name is printed.
7593 When the -q/--quiet switch is used, only the tag name is printed.
7594
7594
7595 .. container:: verbose
7595 .. container:: verbose
7596
7596
7597 Template:
7597 Template:
7598
7598
7599 The following keywords are supported in addition to the common template
7599 The following keywords are supported in addition to the common template
7600 keywords and functions such as ``{tag}``. See also
7600 keywords and functions such as ``{tag}``. See also
7601 :hg:`help templates`.
7601 :hg:`help templates`.
7602
7602
7603 :type: String. ``local`` for local tags.
7603 :type: String. ``local`` for local tags.
7604
7604
7605 Returns 0 on success.
7605 Returns 0 on success.
7606 """
7606 """
7607
7607
7608 ui.pager(b'tags')
7608 ui.pager(b'tags')
7609 fm = ui.formatter(b'tags', pycompat.byteskwargs(opts))
7609 fm = ui.formatter(b'tags', pycompat.byteskwargs(opts))
7610 hexfunc = fm.hexfunc
7610 hexfunc = fm.hexfunc
7611
7611
7612 for t, n in reversed(repo.tagslist()):
7612 for t, n in reversed(repo.tagslist()):
7613 hn = hexfunc(n)
7613 hn = hexfunc(n)
7614 label = b'tags.normal'
7614 label = b'tags.normal'
7615 tagtype = repo.tagtype(t)
7615 tagtype = repo.tagtype(t)
7616 if not tagtype or tagtype == b'global':
7616 if not tagtype or tagtype == b'global':
7617 tagtype = b''
7617 tagtype = b''
7618 else:
7618 else:
7619 label = b'tags.' + tagtype
7619 label = b'tags.' + tagtype
7620
7620
7621 fm.startitem()
7621 fm.startitem()
7622 fm.context(repo=repo)
7622 fm.context(repo=repo)
7623 fm.write(b'tag', b'%s', t, label=label)
7623 fm.write(b'tag', b'%s', t, label=label)
7624 fmt = b" " * (30 - encoding.colwidth(t)) + b' %5d:%s'
7624 fmt = b" " * (30 - encoding.colwidth(t)) + b' %5d:%s'
7625 fm.condwrite(
7625 fm.condwrite(
7626 not ui.quiet,
7626 not ui.quiet,
7627 b'rev node',
7627 b'rev node',
7628 fmt,
7628 fmt,
7629 repo.changelog.rev(n),
7629 repo.changelog.rev(n),
7630 hn,
7630 hn,
7631 label=label,
7631 label=label,
7632 )
7632 )
7633 fm.condwrite(
7633 fm.condwrite(
7634 ui.verbose and tagtype, b'type', b' %s', tagtype, label=label
7634 ui.verbose and tagtype, b'type', b' %s', tagtype, label=label
7635 )
7635 )
7636 fm.plain(b'\n')
7636 fm.plain(b'\n')
7637 fm.end()
7637 fm.end()
7638
7638
7639
7639
7640 @command(
7640 @command(
7641 b'tip',
7641 b'tip',
7642 [
7642 [
7643 (b'p', b'patch', None, _(b'show patch')),
7643 (b'p', b'patch', None, _(b'show patch')),
7644 (b'g', b'git', None, _(b'use git extended diff format')),
7644 (b'g', b'git', None, _(b'use git extended diff format')),
7645 ]
7645 ]
7646 + templateopts,
7646 + templateopts,
7647 _(b'[-p] [-g]'),
7647 _(b'[-p] [-g]'),
7648 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
7648 helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
7649 )
7649 )
7650 def tip(ui, repo, **opts):
7650 def tip(ui, repo, **opts):
7651 """show the tip revision (DEPRECATED)
7651 """show the tip revision (DEPRECATED)
7652
7652
7653 The tip revision (usually just called the tip) is the changeset
7653 The tip revision (usually just called the tip) is the changeset
7654 most recently added to the repository (and therefore the most
7654 most recently added to the repository (and therefore the most
7655 recently changed head).
7655 recently changed head).
7656
7656
7657 If you have just made a commit, that commit will be the tip. If
7657 If you have just made a commit, that commit will be the tip. If
7658 you have just pulled changes from another repository, the tip of
7658 you have just pulled changes from another repository, the tip of
7659 that repository becomes the current tip. The "tip" tag is special
7659 that repository becomes the current tip. The "tip" tag is special
7660 and cannot be renamed or assigned to a different changeset.
7660 and cannot be renamed or assigned to a different changeset.
7661
7661
7662 This command is deprecated, please use :hg:`heads` instead.
7662 This command is deprecated, please use :hg:`heads` instead.
7663
7663
7664 Returns 0 on success.
7664 Returns 0 on success.
7665 """
7665 """
7666 opts = pycompat.byteskwargs(opts)
7666 opts = pycompat.byteskwargs(opts)
7667 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
7667 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
7668 displayer.show(repo[b'tip'])
7668 displayer.show(repo[b'tip'])
7669 displayer.close()
7669 displayer.close()
7670
7670
7671
7671
7672 @command(
7672 @command(
7673 b'unbundle',
7673 b'unbundle',
7674 [
7674 [
7675 (
7675 (
7676 b'u',
7676 b'u',
7677 b'update',
7677 b'update',
7678 None,
7678 None,
7679 _(b'update to new branch head if changesets were unbundled'),
7679 _(b'update to new branch head if changesets were unbundled'),
7680 )
7680 )
7681 ],
7681 ],
7682 _(b'[-u] FILE...'),
7682 _(b'[-u] FILE...'),
7683 helpcategory=command.CATEGORY_IMPORT_EXPORT,
7683 helpcategory=command.CATEGORY_IMPORT_EXPORT,
7684 )
7684 )
7685 def unbundle(ui, repo, fname1, *fnames, **opts):
7685 def unbundle(ui, repo, fname1, *fnames, **opts):
7686 """apply one or more bundle files
7686 """apply one or more bundle files
7687
7687
7688 Apply one or more bundle files generated by :hg:`bundle`.
7688 Apply one or more bundle files generated by :hg:`bundle`.
7689
7689
7690 Returns 0 on success, 1 if an update has unresolved files.
7690 Returns 0 on success, 1 if an update has unresolved files.
7691 """
7691 """
7692 fnames = (fname1,) + fnames
7692 fnames = (fname1,) + fnames
7693
7693
7694 with repo.lock():
7694 with repo.lock():
7695 for fname in fnames:
7695 for fname in fnames:
7696 f = hg.openpath(ui, fname)
7696 f = hg.openpath(ui, fname)
7697 gen = exchange.readbundle(ui, f, fname)
7697 gen = exchange.readbundle(ui, f, fname)
7698 if isinstance(gen, streamclone.streamcloneapplier):
7698 if isinstance(gen, streamclone.streamcloneapplier):
7699 raise error.InputError(
7699 raise error.InputError(
7700 _(
7700 _(
7701 b'packed bundles cannot be applied with '
7701 b'packed bundles cannot be applied with '
7702 b'"hg unbundle"'
7702 b'"hg unbundle"'
7703 ),
7703 ),
7704 hint=_(b'use "hg debugapplystreamclonebundle"'),
7704 hint=_(b'use "hg debugapplystreamclonebundle"'),
7705 )
7705 )
7706 url = b'bundle:' + fname
7706 url = b'bundle:' + fname
7707 try:
7707 try:
7708 txnname = b'unbundle'
7708 txnname = b'unbundle'
7709 if not isinstance(gen, bundle2.unbundle20):
7709 if not isinstance(gen, bundle2.unbundle20):
7710 txnname = b'unbundle\n%s' % urlutil.hidepassword(url)
7710 txnname = b'unbundle\n%s' % urlutil.hidepassword(url)
7711 with repo.transaction(txnname) as tr:
7711 with repo.transaction(txnname) as tr:
7712 op = bundle2.applybundle(
7712 op = bundle2.applybundle(
7713 repo, gen, tr, source=b'unbundle', url=url
7713 repo, gen, tr, source=b'unbundle', url=url
7714 )
7714 )
7715 except error.BundleUnknownFeatureError as exc:
7715 except error.BundleUnknownFeatureError as exc:
7716 raise error.Abort(
7716 raise error.Abort(
7717 _(b'%s: unknown bundle feature, %s') % (fname, exc),
7717 _(b'%s: unknown bundle feature, %s') % (fname, exc),
7718 hint=_(
7718 hint=_(
7719 b"see https://mercurial-scm.org/"
7719 b"see https://mercurial-scm.org/"
7720 b"wiki/BundleFeature for more "
7720 b"wiki/BundleFeature for more "
7721 b"information"
7721 b"information"
7722 ),
7722 ),
7723 )
7723 )
7724 modheads = bundle2.combinechangegroupresults(op)
7724 modheads = bundle2.combinechangegroupresults(op)
7725
7725
7726 if postincoming(ui, repo, modheads, opts.get('update'), None, None):
7726 if postincoming(ui, repo, modheads, opts.get('update'), None, None):
7727 return 1
7727 return 1
7728 else:
7728 else:
7729 return 0
7729 return 0
7730
7730
7731
7731
7732 @command(
7732 @command(
7733 b'unshelve',
7733 b'unshelve',
7734 [
7734 [
7735 (b'a', b'abort', None, _(b'abort an incomplete unshelve operation')),
7735 (b'a', b'abort', None, _(b'abort an incomplete unshelve operation')),
7736 (
7736 (
7737 b'c',
7737 b'c',
7738 b'continue',
7738 b'continue',
7739 None,
7739 None,
7740 _(b'continue an incomplete unshelve operation'),
7740 _(b'continue an incomplete unshelve operation'),
7741 ),
7741 ),
7742 (b'i', b'interactive', None, _(b'use interactive mode (EXPERIMENTAL)')),
7742 (b'i', b'interactive', None, _(b'use interactive mode (EXPERIMENTAL)')),
7743 (b'k', b'keep', None, _(b'keep shelve after unshelving')),
7743 (b'k', b'keep', None, _(b'keep shelve after unshelving')),
7744 (
7744 (
7745 b'n',
7745 b'n',
7746 b'name',
7746 b'name',
7747 b'',
7747 b'',
7748 _(b'restore shelved change with given name'),
7748 _(b'restore shelved change with given name'),
7749 _(b'NAME'),
7749 _(b'NAME'),
7750 ),
7750 ),
7751 (b't', b'tool', b'', _(b'specify merge tool')),
7751 (b't', b'tool', b'', _(b'specify merge tool')),
7752 (
7752 (
7753 b'',
7753 b'',
7754 b'date',
7754 b'date',
7755 b'',
7755 b'',
7756 _(b'set date for temporary commits (DEPRECATED)'),
7756 _(b'set date for temporary commits (DEPRECATED)'),
7757 _(b'DATE'),
7757 _(b'DATE'),
7758 ),
7758 ),
7759 ],
7759 ],
7760 _(b'hg unshelve [OPTION]... [[-n] SHELVED]'),
7760 _(b'hg unshelve [OPTION]... [[-n] SHELVED]'),
7761 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7761 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7762 )
7762 )
7763 def unshelve(ui, repo, *shelved, **opts):
7763 def unshelve(ui, repo, *shelved, **opts):
7764 """restore a shelved change to the working directory
7764 """restore a shelved change to the working directory
7765
7765
7766 This command accepts an optional name of a shelved change to
7766 This command accepts an optional name of a shelved change to
7767 restore. If none is given, the most recent shelved change is used.
7767 restore. If none is given, the most recent shelved change is used.
7768
7768
7769 If a shelved change is applied successfully, the bundle that
7769 If a shelved change is applied successfully, the bundle that
7770 contains the shelved changes is moved to a backup location
7770 contains the shelved changes is moved to a backup location
7771 (.hg/shelve-backup).
7771 (.hg/shelve-backup).
7772
7772
7773 Since you can restore a shelved change on top of an arbitrary
7773 Since you can restore a shelved change on top of an arbitrary
7774 commit, it is possible that unshelving will result in a conflict
7774 commit, it is possible that unshelving will result in a conflict
7775 between your changes and the commits you are unshelving onto. If
7775 between your changes and the commits you are unshelving onto. If
7776 this occurs, you must resolve the conflict, then use
7776 this occurs, you must resolve the conflict, then use
7777 ``--continue`` to complete the unshelve operation. (The bundle
7777 ``--continue`` to complete the unshelve operation. (The bundle
7778 will not be moved until you successfully complete the unshelve.)
7778 will not be moved until you successfully complete the unshelve.)
7779
7779
7780 (Alternatively, you can use ``--abort`` to abandon an unshelve
7780 (Alternatively, you can use ``--abort`` to abandon an unshelve
7781 that causes a conflict. This reverts the unshelved changes, and
7781 that causes a conflict. This reverts the unshelved changes, and
7782 leaves the bundle in place.)
7782 leaves the bundle in place.)
7783
7783
7784 If bare shelved change (without interactive, include and exclude
7784 If bare shelved change (without interactive, include and exclude
7785 option) was done on newly created branch it would restore branch
7785 option) was done on newly created branch it would restore branch
7786 information to the working directory.
7786 information to the working directory.
7787
7787
7788 After a successful unshelve, the shelved changes are stored in a
7788 After a successful unshelve, the shelved changes are stored in a
7789 backup directory. Only the N most recent backups are kept. N
7789 backup directory. Only the N most recent backups are kept. N
7790 defaults to 10 but can be overridden using the ``shelve.maxbackups``
7790 defaults to 10 but can be overridden using the ``shelve.maxbackups``
7791 configuration option.
7791 configuration option.
7792
7792
7793 .. container:: verbose
7793 .. container:: verbose
7794
7794
7795 Timestamp in seconds is used to decide order of backups. More
7795 Timestamp in seconds is used to decide order of backups. More
7796 than ``maxbackups`` backups are kept, if same timestamp
7796 than ``maxbackups`` backups are kept, if same timestamp
7797 prevents from deciding exact order of them, for safety.
7797 prevents from deciding exact order of them, for safety.
7798
7798
7799 Selected changes can be unshelved with ``--interactive`` flag.
7799 Selected changes can be unshelved with ``--interactive`` flag.
7800 The working directory is updated with the selected changes, and
7800 The working directory is updated with the selected changes, and
7801 only the unselected changes remain shelved.
7801 only the unselected changes remain shelved.
7802 Note: The whole shelve is applied to working directory first before
7802 Note: The whole shelve is applied to working directory first before
7803 running interactively. So, this will bring up all the conflicts between
7803 running interactively. So, this will bring up all the conflicts between
7804 working directory and the shelve, irrespective of which changes will be
7804 working directory and the shelve, irrespective of which changes will be
7805 unshelved.
7805 unshelved.
7806 """
7806 """
7807 with repo.wlock():
7807 with repo.wlock():
7808 return shelvemod.unshelvecmd(ui, repo, *shelved, **opts)
7808 return shelvemod.unshelvecmd(ui, repo, *shelved, **opts)
7809
7809
7810
7810
7811 statemod.addunfinished(
7811 statemod.addunfinished(
7812 b'unshelve',
7812 b'unshelve',
7813 fname=b'shelvedstate',
7813 fname=b'shelvedstate',
7814 continueflag=True,
7814 continueflag=True,
7815 abortfunc=shelvemod.hgabortunshelve,
7815 abortfunc=shelvemod.hgabortunshelve,
7816 continuefunc=shelvemod.hgcontinueunshelve,
7816 continuefunc=shelvemod.hgcontinueunshelve,
7817 cmdmsg=_(b'unshelve already in progress'),
7817 cmdmsg=_(b'unshelve already in progress'),
7818 )
7818 )
7819
7819
7820
7820
7821 @command(
7821 @command(
7822 b'update|up|checkout|co',
7822 b'update|up|checkout|co',
7823 [
7823 [
7824 (b'C', b'clean', None, _(b'discard uncommitted changes (no backup)')),
7824 (b'C', b'clean', None, _(b'discard uncommitted changes (no backup)')),
7825 (b'c', b'check', None, _(b'require clean working directory')),
7825 (b'c', b'check', None, _(b'require clean working directory')),
7826 (b'm', b'merge', None, _(b'merge uncommitted changes')),
7826 (b'm', b'merge', None, _(b'merge uncommitted changes')),
7827 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
7827 (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
7828 (b'r', b'rev', b'', _(b'revision'), _(b'REV')),
7828 (b'r', b'rev', b'', _(b'revision'), _(b'REV')),
7829 ]
7829 ]
7830 + mergetoolopts,
7830 + mergetoolopts,
7831 _(b'[-C|-c|-m] [-d DATE] [[-r] REV]'),
7831 _(b'[-C|-c|-m] [-d DATE] [[-r] REV]'),
7832 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7832 helpcategory=command.CATEGORY_WORKING_DIRECTORY,
7833 helpbasic=True,
7833 helpbasic=True,
7834 )
7834 )
7835 def update(ui, repo, node=None, **opts):
7835 def update(ui, repo, node=None, **opts):
7836 """update working directory (or switch revisions)
7836 """update working directory (or switch revisions)
7837
7837
7838 Update the repository's working directory to the specified
7838 Update the repository's working directory to the specified
7839 changeset. If no changeset is specified, update to the tip of the
7839 changeset. If no changeset is specified, update to the tip of the
7840 current named branch and move the active bookmark (see :hg:`help
7840 current named branch and move the active bookmark (see :hg:`help
7841 bookmarks`).
7841 bookmarks`).
7842
7842
7843 Update sets the working directory's parent revision to the specified
7843 Update sets the working directory's parent revision to the specified
7844 changeset (see :hg:`help parents`).
7844 changeset (see :hg:`help parents`).
7845
7845
7846 If the changeset is not a descendant or ancestor of the working
7846 If the changeset is not a descendant or ancestor of the working
7847 directory's parent and there are uncommitted changes, the update is
7847 directory's parent and there are uncommitted changes, the update is
7848 aborted. With the -c/--check option, the working directory is checked
7848 aborted. With the -c/--check option, the working directory is checked
7849 for uncommitted changes; if none are found, the working directory is
7849 for uncommitted changes; if none are found, the working directory is
7850 updated to the specified changeset.
7850 updated to the specified changeset.
7851
7851
7852 .. container:: verbose
7852 .. container:: verbose
7853
7853
7854 The -C/--clean, -c/--check, and -m/--merge options control what
7854 The -C/--clean, -c/--check, and -m/--merge options control what
7855 happens if the working directory contains uncommitted changes.
7855 happens if the working directory contains uncommitted changes.
7856 At most of one of them can be specified.
7856 At most of one of them can be specified.
7857
7857
7858 1. If no option is specified, and if
7858 1. If no option is specified, and if
7859 the requested changeset is an ancestor or descendant of
7859 the requested changeset is an ancestor or descendant of
7860 the working directory's parent, the uncommitted changes
7860 the working directory's parent, the uncommitted changes
7861 are merged into the requested changeset and the merged
7861 are merged into the requested changeset and the merged
7862 result is left uncommitted. If the requested changeset is
7862 result is left uncommitted. If the requested changeset is
7863 not an ancestor or descendant (that is, it is on another
7863 not an ancestor or descendant (that is, it is on another
7864 branch), the update is aborted and the uncommitted changes
7864 branch), the update is aborted and the uncommitted changes
7865 are preserved.
7865 are preserved.
7866
7866
7867 2. With the -m/--merge option, the update is allowed even if the
7867 2. With the -m/--merge option, the update is allowed even if the
7868 requested changeset is not an ancestor or descendant of
7868 requested changeset is not an ancestor or descendant of
7869 the working directory's parent.
7869 the working directory's parent.
7870
7870
7871 3. With the -c/--check option, the update is aborted and the
7871 3. With the -c/--check option, the update is aborted and the
7872 uncommitted changes are preserved.
7872 uncommitted changes are preserved.
7873
7873
7874 4. With the -C/--clean option, uncommitted changes are discarded and
7874 4. With the -C/--clean option, uncommitted changes are discarded and
7875 the working directory is updated to the requested changeset.
7875 the working directory is updated to the requested changeset.
7876
7876
7877 To cancel an uncommitted merge (and lose your changes), use
7877 To cancel an uncommitted merge (and lose your changes), use
7878 :hg:`merge --abort`.
7878 :hg:`merge --abort`.
7879
7879
7880 Use null as the changeset to remove the working directory (like
7880 Use null as the changeset to remove the working directory (like
7881 :hg:`clone -U`).
7881 :hg:`clone -U`).
7882
7882
7883 If you want to revert just one file to an older revision, use
7883 If you want to revert just one file to an older revision, use
7884 :hg:`revert [-r REV] NAME`.
7884 :hg:`revert [-r REV] NAME`.
7885
7885
7886 See :hg:`help dates` for a list of formats valid for -d/--date.
7886 See :hg:`help dates` for a list of formats valid for -d/--date.
7887
7887
7888 Returns 0 on success, 1 if there are unresolved files.
7888 Returns 0 on success, 1 if there are unresolved files.
7889 """
7889 """
7890 cmdutil.check_at_most_one_arg(opts, 'clean', 'check', 'merge')
7890 cmdutil.check_at_most_one_arg(opts, 'clean', 'check', 'merge')
7891 rev = opts.get('rev')
7891 rev = opts.get('rev')
7892 date = opts.get('date')
7892 date = opts.get('date')
7893 clean = opts.get('clean')
7893 clean = opts.get('clean')
7894 check = opts.get('check')
7894 check = opts.get('check')
7895 merge = opts.get('merge')
7895 merge = opts.get('merge')
7896 if rev and node:
7896 if rev and node:
7897 raise error.InputError(_(b"please specify just one revision"))
7897 raise error.InputError(_(b"please specify just one revision"))
7898
7898
7899 if ui.configbool(b'commands', b'update.requiredest'):
7899 if ui.configbool(b'commands', b'update.requiredest'):
7900 if not node and not rev and not date:
7900 if not node and not rev and not date:
7901 raise error.InputError(
7901 raise error.InputError(
7902 _(b'you must specify a destination'),
7902 _(b'you must specify a destination'),
7903 hint=_(b'for example: hg update ".::"'),
7903 hint=_(b'for example: hg update ".::"'),
7904 )
7904 )
7905
7905
7906 if rev is None or rev == b'':
7906 if rev is None or rev == b'':
7907 rev = node
7907 rev = node
7908
7908
7909 if date and rev is not None:
7909 if date and rev is not None:
7910 raise error.InputError(_(b"you can't specify a revision and a date"))
7910 raise error.InputError(_(b"you can't specify a revision and a date"))
7911
7911
7912 updatecheck = None
7912 updatecheck = None
7913 if check or merge is not None and not merge:
7913 if check or merge is not None and not merge:
7914 updatecheck = b'abort'
7914 updatecheck = b'abort'
7915 elif merge or check is not None and not check:
7915 elif merge or check is not None and not check:
7916 updatecheck = b'none'
7916 updatecheck = b'none'
7917
7917
7918 with repo.wlock():
7918 with repo.wlock():
7919 cmdutil.clearunfinished(repo)
7919 cmdutil.clearunfinished(repo)
7920 if date:
7920 if date:
7921 rev = cmdutil.finddate(ui, repo, date)
7921 rev = cmdutil.finddate(ui, repo, date)
7922
7922
7923 # if we defined a bookmark, we have to remember the original name
7923 # if we defined a bookmark, we have to remember the original name
7924 brev = rev
7924 brev = rev
7925 if rev:
7925 if rev:
7926 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
7926 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
7927 ctx = logcmdutil.revsingle(repo, rev, default=None)
7927 ctx = logcmdutil.revsingle(repo, rev, default=None)
7928 rev = ctx.rev()
7928 rev = ctx.rev()
7929 hidden = ctx.hidden()
7929 hidden = ctx.hidden()
7930 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
7930 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
7931 with ui.configoverride(overrides, b'update'):
7931 with ui.configoverride(overrides, b'update'):
7932 ret = hg.updatetotally(
7932 ret = hg.updatetotally(
7933 ui, repo, rev, brev, clean=clean, updatecheck=updatecheck
7933 ui, repo, rev, brev, clean=clean, updatecheck=updatecheck
7934 )
7934 )
7935 if hidden:
7935 if hidden:
7936 ctxstr = ctx.hex()[:12]
7936 ctxstr = ctx.hex()[:12]
7937 ui.warn(_(b"updated to hidden changeset %s\n") % ctxstr)
7937 ui.warn(_(b"updated to hidden changeset %s\n") % ctxstr)
7938
7938
7939 if ctx.obsolete():
7939 if ctx.obsolete():
7940 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
7940 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
7941 ui.warn(b"(%s)\n" % obsfatemsg)
7941 ui.warn(b"(%s)\n" % obsfatemsg)
7942 return ret
7942 return ret
7943
7943
7944
7944
7945 @command(
7945 @command(
7946 b'verify',
7946 b'verify',
7947 [(b'', b'full', False, b'perform more checks (EXPERIMENTAL)')],
7947 [(b'', b'full', False, b'perform more checks (EXPERIMENTAL)')],
7948 helpcategory=command.CATEGORY_MAINTENANCE,
7948 helpcategory=command.CATEGORY_MAINTENANCE,
7949 )
7949 )
7950 def verify(ui, repo, **opts):
7950 def verify(ui, repo, **opts):
7951 """verify the integrity of the repository
7951 """verify the integrity of the repository
7952
7952
7953 Verify the integrity of the current repository.
7953 Verify the integrity of the current repository.
7954
7954
7955 This will perform an extensive check of the repository's
7955 This will perform an extensive check of the repository's
7956 integrity, validating the hashes and checksums of each entry in
7956 integrity, validating the hashes and checksums of each entry in
7957 the changelog, manifest, and tracked files, as well as the
7957 the changelog, manifest, and tracked files, as well as the
7958 integrity of their crosslinks and indices.
7958 integrity of their crosslinks and indices.
7959
7959
7960 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
7960 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
7961 for more information about recovery from corruption of the
7961 for more information about recovery from corruption of the
7962 repository.
7962 repository.
7963
7963
7964 For an alternative UI with a lot more control over the verification
7965 process and better error reporting, try `hg help admin::verify`.
7966
7964 Returns 0 on success, 1 if errors are encountered.
7967 Returns 0 on success, 1 if errors are encountered.
7965 """
7968 """
7966 level = None
7969 level = None
7967 if opts['full']:
7970 if opts['full']:
7968 level = verifymod.VERIFY_FULL
7971 level = verifymod.VERIFY_FULL
7969 return hg.verify(repo, level)
7972 return hg.verify(repo, level)
7970
7973
7971
7974
7972 @command(
7975 @command(
7973 b'version',
7976 b'version',
7974 [] + formatteropts,
7977 [] + formatteropts,
7975 helpcategory=command.CATEGORY_HELP,
7978 helpcategory=command.CATEGORY_HELP,
7976 norepo=True,
7979 norepo=True,
7977 intents={INTENT_READONLY},
7980 intents={INTENT_READONLY},
7978 )
7981 )
7979 def version_(ui, **opts):
7982 def version_(ui, **opts):
7980 """output version and copyright information
7983 """output version and copyright information
7981
7984
7982 .. container:: verbose
7985 .. container:: verbose
7983
7986
7984 Template:
7987 Template:
7985
7988
7986 The following keywords are supported. See also :hg:`help templates`.
7989 The following keywords are supported. See also :hg:`help templates`.
7987
7990
7988 :extensions: List of extensions.
7991 :extensions: List of extensions.
7989 :ver: String. Version number.
7992 :ver: String. Version number.
7990
7993
7991 And each entry of ``{extensions}`` provides the following sub-keywords
7994 And each entry of ``{extensions}`` provides the following sub-keywords
7992 in addition to ``{ver}``.
7995 in addition to ``{ver}``.
7993
7996
7994 :bundled: Boolean. True if included in the release.
7997 :bundled: Boolean. True if included in the release.
7995 :name: String. Extension name.
7998 :name: String. Extension name.
7996 """
7999 """
7997 if ui.verbose:
8000 if ui.verbose:
7998 ui.pager(b'version')
8001 ui.pager(b'version')
7999 fm = ui.formatter(b"version", pycompat.byteskwargs(opts))
8002 fm = ui.formatter(b"version", pycompat.byteskwargs(opts))
8000 fm.startitem()
8003 fm.startitem()
8001 fm.write(
8004 fm.write(
8002 b"ver", _(b"Mercurial Distributed SCM (version %s)\n"), util.version()
8005 b"ver", _(b"Mercurial Distributed SCM (version %s)\n"), util.version()
8003 )
8006 )
8004 license = _(
8007 license = _(
8005 b"(see https://mercurial-scm.org for more information)\n"
8008 b"(see https://mercurial-scm.org for more information)\n"
8006 b"\nCopyright (C) 2005-2023 Olivia Mackall and others\n"
8009 b"\nCopyright (C) 2005-2023 Olivia Mackall and others\n"
8007 b"This is free software; see the source for copying conditions. "
8010 b"This is free software; see the source for copying conditions. "
8008 b"There is NO\nwarranty; "
8011 b"There is NO\nwarranty; "
8009 b"not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
8012 b"not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
8010 )
8013 )
8011 if not ui.quiet:
8014 if not ui.quiet:
8012 fm.plain(license)
8015 fm.plain(license)
8013
8016
8014 if ui.verbose:
8017 if ui.verbose:
8015 fm.plain(_(b"\nEnabled extensions:\n\n"))
8018 fm.plain(_(b"\nEnabled extensions:\n\n"))
8016 # format names and versions into columns
8019 # format names and versions into columns
8017 names = []
8020 names = []
8018 vers = []
8021 vers = []
8019 isinternals = []
8022 isinternals = []
8020 for name, module in sorted(extensions.extensions()):
8023 for name, module in sorted(extensions.extensions()):
8021 names.append(name)
8024 names.append(name)
8022 vers.append(extensions.moduleversion(module) or None)
8025 vers.append(extensions.moduleversion(module) or None)
8023 isinternals.append(extensions.ismoduleinternal(module))
8026 isinternals.append(extensions.ismoduleinternal(module))
8024 fn = fm.nested(b"extensions", tmpl=b'{name}\n')
8027 fn = fm.nested(b"extensions", tmpl=b'{name}\n')
8025 if names:
8028 if names:
8026 namefmt = b" %%-%ds " % max(len(n) for n in names)
8029 namefmt = b" %%-%ds " % max(len(n) for n in names)
8027 places = [_(b"external"), _(b"internal")]
8030 places = [_(b"external"), _(b"internal")]
8028 for n, v, p in zip(names, vers, isinternals):
8031 for n, v, p in zip(names, vers, isinternals):
8029 fn.startitem()
8032 fn.startitem()
8030 fn.condwrite(ui.verbose, b"name", namefmt, n)
8033 fn.condwrite(ui.verbose, b"name", namefmt, n)
8031 if ui.verbose:
8034 if ui.verbose:
8032 fn.plain(b"%s " % places[p])
8035 fn.plain(b"%s " % places[p])
8033 fn.data(bundled=p)
8036 fn.data(bundled=p)
8034 fn.condwrite(ui.verbose and v, b"ver", b"%s", v)
8037 fn.condwrite(ui.verbose and v, b"ver", b"%s", v)
8035 if ui.verbose:
8038 if ui.verbose:
8036 fn.plain(b"\n")
8039 fn.plain(b"\n")
8037 fn.end()
8040 fn.end()
8038 fm.end()
8041 fm.end()
8039
8042
8040
8043
8041 def loadcmdtable(ui, name, cmdtable):
8044 def loadcmdtable(ui, name, cmdtable):
8042 """Load command functions from specified cmdtable"""
8045 """Load command functions from specified cmdtable"""
8043 overrides = [cmd for cmd in cmdtable if cmd in table]
8046 overrides = [cmd for cmd in cmdtable if cmd in table]
8044 if overrides:
8047 if overrides:
8045 ui.warn(
8048 ui.warn(
8046 _(b"extension '%s' overrides commands: %s\n")
8049 _(b"extension '%s' overrides commands: %s\n")
8047 % (name, b" ".join(overrides))
8050 % (name, b" ".join(overrides))
8048 )
8051 )
8049 table.update(cmdtable)
8052 table.update(cmdtable)
@@ -1,535 +1,563 b''
1 # registrar.py - utilities to register function for specific purpose
1 # registrar.py - utilities to register function for specific purpose
2 #
2 #
3 # Copyright FUJIWARA Katsunori <foozy@lares.dti.ne.jp> and others
3 # Copyright FUJIWARA Katsunori <foozy@lares.dti.ne.jp> and others
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
8
9 from typing import Any, List, Optional, Tuple
9 from . import (
10 from . import (
10 configitems,
11 configitems,
11 error,
12 error,
12 pycompat,
13 pycompat,
13 )
14 )
14
15
15 # unlike the other registered items, config options are neither functions or
16 # unlike the other registered items, config options are neither functions or
16 # classes. Registering the option is just small function call.
17 # classes. Registering the option is just small function call.
17 #
18 #
18 # We still add the official API to the registrar module for consistency with
19 # We still add the official API to the registrar module for consistency with
19 # the other items extensions want might to register.
20 # the other items extensions want might to register.
20 configitem = configitems.getitemregister
21 configitem = configitems.getitemregister
21
22
22
23
23 class _funcregistrarbase:
24 class _funcregistrarbase:
24 """Base of decorator to register a function for specific purpose
25 """Base of decorator to register a function for specific purpose
25
26
26 This decorator stores decorated functions into own dict 'table'.
27 This decorator stores decorated functions into own dict 'table'.
27
28
28 The least derived class can be defined by overriding 'formatdoc',
29 The least derived class can be defined by overriding 'formatdoc',
29 for example::
30 for example::
30
31
31 class keyword(_funcregistrarbase):
32 class keyword(_funcregistrarbase):
32 _docformat = ":%s: %s"
33 _docformat = ":%s: %s"
33
34
34 This should be used as below:
35 This should be used as below:
35
36
36 keyword = registrar.keyword()
37 keyword = registrar.keyword()
37
38
38 @keyword(b'bar')
39 @keyword(b'bar')
39 def barfunc(*args, **kwargs):
40 def barfunc(*args, **kwargs):
40 '''Explanation of bar keyword ....
41 '''Explanation of bar keyword ....
41 '''
42 '''
42 pass
43 pass
43
44
44 In this case:
45 In this case:
45
46
46 - 'barfunc' is stored as 'bar' in '_table' of an instance 'keyword' above
47 - 'barfunc' is stored as 'bar' in '_table' of an instance 'keyword' above
47 - 'barfunc.__doc__' becomes ":bar: Explanation of bar keyword"
48 - 'barfunc.__doc__' becomes ":bar: Explanation of bar keyword"
48 """
49 """
49
50
50 def __init__(self, table=None):
51 def __init__(self, table=None):
51 if table is None:
52 if table is None:
52 self._table = {}
53 self._table = {}
53 else:
54 else:
54 self._table = table
55 self._table = table
55
56
56 def __call__(self, decl, *args, **kwargs):
57 def __call__(self, decl, *args, **kwargs):
57 return lambda func: self._doregister(func, decl, *args, **kwargs)
58 return lambda func: self._doregister(func, decl, *args, **kwargs)
58
59
59 def _doregister(self, func, decl, *args, **kwargs):
60 def _doregister(self, func, decl, *args, **kwargs):
60 name = self._getname(decl)
61 name = self._getname(decl)
61
62
62 if name in self._table:
63 if name in self._table:
63 msg = b'duplicate registration for name: "%s"' % name
64 msg = b'duplicate registration for name: "%s"' % name
64 raise error.ProgrammingError(msg)
65 raise error.ProgrammingError(msg)
65
66
66 if func.__doc__ and not hasattr(func, '_origdoc'):
67 if func.__doc__ and not hasattr(func, '_origdoc'):
67 func._origdoc = func.__doc__.strip()
68 func._origdoc = func.__doc__.strip()
68 doc = pycompat.sysbytes(func._origdoc)
69 doc = pycompat.sysbytes(func._origdoc)
69 func.__doc__ = pycompat.sysstr(self._formatdoc(decl, doc))
70 func.__doc__ = pycompat.sysstr(self._formatdoc(decl, doc))
70
71
71 self._table[name] = func
72 self._table[name] = func
72 self._extrasetup(name, func, *args, **kwargs)
73 self._extrasetup(name, func, *args, **kwargs)
73
74
74 return func
75 return func
75
76
76 def _merge(self, registrarbase):
77 def _merge(self, registrarbase):
77 """Merge the entries of the given registrar object into this one.
78 """Merge the entries of the given registrar object into this one.
78
79
79 The other registrar object must not contain any entries already in the
80 The other registrar object must not contain any entries already in the
80 current one, or a ProgrammmingError is raised. Additionally, the types
81 current one, or a ProgrammmingError is raised. Additionally, the types
81 of the two registrars must match.
82 of the two registrars must match.
82 """
83 """
83 if not isinstance(registrarbase, type(self)):
84 if not isinstance(registrarbase, type(self)):
84 msg = b"cannot merge different types of registrar"
85 msg = b"cannot merge different types of registrar"
85 raise error.ProgrammingError(msg)
86 raise error.ProgrammingError(msg)
86
87
87 dups = set(registrarbase._table).intersection(self._table)
88 dups = set(registrarbase._table).intersection(self._table)
88
89
89 if dups:
90 if dups:
90 msg = b'duplicate registration for names: "%s"' % b'", "'.join(dups)
91 msg = b'duplicate registration for names: "%s"' % b'", "'.join(dups)
91 raise error.ProgrammingError(msg)
92 raise error.ProgrammingError(msg)
92
93
93 self._table.update(registrarbase._table)
94 self._table.update(registrarbase._table)
94
95
95 def _parsefuncdecl(self, decl):
96 def _parsefuncdecl(self, decl):
96 """Parse function declaration and return the name of function in it"""
97 """Parse function declaration and return the name of function in it"""
97 i = decl.find(b'(')
98 i = decl.find(b'(')
98 if i >= 0:
99 if i >= 0:
99 return decl[:i]
100 return decl[:i]
100 else:
101 else:
101 return decl
102 return decl
102
103
103 def _getname(self, decl):
104 def _getname(self, decl):
104 """Return the name of the registered function from decl
105 """Return the name of the registered function from decl
105
106
106 Derived class should override this, if it allows more
107 Derived class should override this, if it allows more
107 descriptive 'decl' string than just a name.
108 descriptive 'decl' string than just a name.
108 """
109 """
109 return decl
110 return decl
110
111
111 _docformat = None
112 _docformat = None
112
113
113 def _formatdoc(self, decl, doc):
114 def _formatdoc(self, decl, doc):
114 """Return formatted document of the registered function for help
115 """Return formatted document of the registered function for help
115
116
116 'doc' is '__doc__.strip()' of the registered function.
117 'doc' is '__doc__.strip()' of the registered function.
117 """
118 """
118 return self._docformat % (decl, doc)
119 return self._docformat % (decl, doc)
119
120
120 def _extrasetup(self, name, func):
121 def _extrasetup(self, name, func):
121 """Execute extra setup for registered function, if needed"""
122 """Execute extra setup for registered function, if needed"""
122
123
123
124
124 class command(_funcregistrarbase):
125 class command(_funcregistrarbase):
125 """Decorator to register a command function to table
126 """Decorator to register a command function to table
126
127
127 This class receives a command table as its argument. The table should
128 This class receives a command table as its argument. The table should
128 be a dict.
129 be a dict.
129
130
130 The created object can be used as a decorator for adding commands to
131 The created object can be used as a decorator for adding commands to
131 that command table. This accepts multiple arguments to define a command.
132 that command table. This accepts multiple arguments to define a command.
132
133
133 The first argument is the command name (as bytes).
134 The first argument is the command name (as bytes).
134
135
135 The `options` keyword argument is an iterable of tuples defining command
136 The `options` keyword argument is an iterable of tuples defining command
136 arguments. See ``mercurial.fancyopts.fancyopts()`` for the format of each
137 arguments. See ``mercurial.fancyopts.fancyopts()`` for the format of each
137 tuple.
138 tuple.
138
139
139 The `synopsis` argument defines a short, one line summary of how to use the
140 The `synopsis` argument defines a short, one line summary of how to use the
140 command. This shows up in the help output.
141 command. This shows up in the help output.
141
142
142 There are three arguments that control what repository (if any) is found
143 There are three arguments that control what repository (if any) is found
143 and passed to the decorated function: `norepo`, `optionalrepo`, and
144 and passed to the decorated function: `norepo`, `optionalrepo`, and
144 `inferrepo`.
145 `inferrepo`.
145
146
146 The `norepo` argument defines whether the command does not require a
147 The `norepo` argument defines whether the command does not require a
147 local repository. Most commands operate against a repository, thus the
148 local repository. Most commands operate against a repository, thus the
148 default is False. When True, no repository will be passed.
149 default is False. When True, no repository will be passed.
149
150
150 The `optionalrepo` argument defines whether the command optionally requires
151 The `optionalrepo` argument defines whether the command optionally requires
151 a local repository. If no repository can be found, None will be passed
152 a local repository. If no repository can be found, None will be passed
152 to the decorated function.
153 to the decorated function.
153
154
154 The `inferrepo` argument defines whether to try to find a repository from
155 The `inferrepo` argument defines whether to try to find a repository from
155 the command line arguments. If True, arguments will be examined for
156 the command line arguments. If True, arguments will be examined for
156 potential repository locations. See ``findrepo()``. If a repository is
157 potential repository locations. See ``findrepo()``. If a repository is
157 found, it will be used and passed to the decorated function.
158 found, it will be used and passed to the decorated function.
158
159
159 The `intents` argument defines a set of intended actions or capabilities
160 The `intents` argument defines a set of intended actions or capabilities
160 the command is taking. These intents can be used to affect the construction
161 the command is taking. These intents can be used to affect the construction
161 of the repository object passed to the command. For example, commands
162 of the repository object passed to the command. For example, commands
162 declaring that they are read-only could receive a repository that doesn't
163 declaring that they are read-only could receive a repository that doesn't
163 have any methods allowing repository mutation. Other intents could be used
164 have any methods allowing repository mutation. Other intents could be used
164 to prevent the command from running if the requested intent could not be
165 to prevent the command from running if the requested intent could not be
165 fulfilled.
166 fulfilled.
166
167
167 If `helpcategory` is set (usually to one of the constants in the help
168 If `helpcategory` is set (usually to one of the constants in the help
168 module), the command will be displayed under that category in the help's
169 module), the command will be displayed under that category in the help's
169 list of commands.
170 list of commands.
170
171
171 The following intents are defined:
172 The following intents are defined:
172
173
173 readonly
174 readonly
174 The command is read-only
175 The command is read-only
175
176
176 The signature of the decorated function looks like this:
177 The signature of the decorated function looks like this:
177 def cmd(ui[, repo] [, <args>] [, <options>])
178 def cmd(ui[, repo] [, <args>] [, <options>])
178
179
179 `repo` is required if `norepo` is False.
180 `repo` is required if `norepo` is False.
180 `<args>` are positional args (or `*args`) arguments, of non-option
181 `<args>` are positional args (or `*args`) arguments, of non-option
181 arguments from the command line.
182 arguments from the command line.
182 `<options>` are keyword arguments (or `**options`) of option arguments
183 `<options>` are keyword arguments (or `**options`) of option arguments
183 from the command line.
184 from the command line.
184
185
185 See the WritingExtensions and MercurialApi documentation for more exhaustive
186 See the WritingExtensions and MercurialApi documentation for more exhaustive
186 descriptions and examples.
187 descriptions and examples.
187 """
188 """
188
189
189 # Command categories for grouping them in help output.
190 # Command categories for grouping them in help output.
190 # These can also be specified for aliases, like:
191 # These can also be specified for aliases, like:
191 # [alias]
192 # [alias]
192 # myalias = something
193 # myalias = something
193 # myalias:category = repo
194 # myalias:category = repo
194 CATEGORY_REPO_CREATION = b'repo'
195 CATEGORY_REPO_CREATION = b'repo'
195 CATEGORY_REMOTE_REPO_MANAGEMENT = b'remote'
196 CATEGORY_REMOTE_REPO_MANAGEMENT = b'remote'
196 CATEGORY_COMMITTING = b'commit'
197 CATEGORY_COMMITTING = b'commit'
197 CATEGORY_CHANGE_MANAGEMENT = b'management'
198 CATEGORY_CHANGE_MANAGEMENT = b'management'
198 CATEGORY_CHANGE_ORGANIZATION = b'organization'
199 CATEGORY_CHANGE_ORGANIZATION = b'organization'
199 CATEGORY_FILE_CONTENTS = b'files'
200 CATEGORY_FILE_CONTENTS = b'files'
200 CATEGORY_CHANGE_NAVIGATION = b'navigation'
201 CATEGORY_CHANGE_NAVIGATION = b'navigation'
201 CATEGORY_WORKING_DIRECTORY = b'wdir'
202 CATEGORY_WORKING_DIRECTORY = b'wdir'
202 CATEGORY_IMPORT_EXPORT = b'import'
203 CATEGORY_IMPORT_EXPORT = b'import'
203 CATEGORY_MAINTENANCE = b'maintenance'
204 CATEGORY_MAINTENANCE = b'maintenance'
204 CATEGORY_HELP = b'help'
205 CATEGORY_HELP = b'help'
205 CATEGORY_MISC = b'misc'
206 CATEGORY_MISC = b'misc'
206 CATEGORY_NONE = b'none'
207 CATEGORY_NONE = b'none'
207
208
208 def _doregister(
209 def _doregister(
209 self,
210 self,
210 func,
211 func,
211 name,
212 name,
212 options=(),
213 options=(),
213 synopsis=None,
214 synopsis=None,
214 norepo=False,
215 norepo=False,
215 optionalrepo=False,
216 optionalrepo=False,
216 inferrepo=False,
217 inferrepo=False,
217 intents=None,
218 intents=None,
218 helpcategory=None,
219 helpcategory=None,
219 helpbasic=False,
220 helpbasic=False,
220 ):
221 ):
221 func.norepo = norepo
222 func.norepo = norepo
222 func.optionalrepo = optionalrepo
223 func.optionalrepo = optionalrepo
223 func.inferrepo = inferrepo
224 func.inferrepo = inferrepo
224 func.intents = intents or set()
225 func.intents = intents or set()
225 func.helpcategory = helpcategory
226 func.helpcategory = helpcategory
226 func.helpbasic = helpbasic
227 func.helpbasic = helpbasic
227 if synopsis:
228 if synopsis:
228 self._table[name] = func, list(options), synopsis
229 self._table[name] = func, list(options), synopsis
229 else:
230 else:
230 self._table[name] = func, list(options)
231 self._table[name] = func, list(options)
231 return func
232 return func
232
233
233 def rename(self, old, new):
234 def rename(self, old, new):
234 """rename a command. Used to add aliases, debugstrip ->
235 """rename a command. Used to add aliases, debugstrip ->
235 debugstrip|strip
236 debugstrip|strip
236 """
237 """
237 self._table[new] = self._table.pop(old)
238 self._table[new] = self._table.pop(old)
238
239
239
240
240 INTENT_READONLY = b'readonly'
241 INTENT_READONLY = b'readonly'
241
242
242
243
243 class revsetpredicate(_funcregistrarbase):
244 class revsetpredicate(_funcregistrarbase):
244 """Decorator to register revset predicate
245 """Decorator to register revset predicate
245
246
246 Usage::
247 Usage::
247
248
248 revsetpredicate = registrar.revsetpredicate()
249 revsetpredicate = registrar.revsetpredicate()
249
250
250 @revsetpredicate(b'mypredicate(arg1, arg2[, arg3])')
251 @revsetpredicate(b'mypredicate(arg1, arg2[, arg3])')
251 def mypredicatefunc(repo, subset, x):
252 def mypredicatefunc(repo, subset, x):
252 '''Explanation of this revset predicate ....
253 '''Explanation of this revset predicate ....
253 '''
254 '''
254 pass
255 pass
255
256
256 The first string argument is used also in online help.
257 The first string argument is used also in online help.
257
258
258 Optional argument 'safe' indicates whether a predicate is safe for
259 Optional argument 'safe' indicates whether a predicate is safe for
259 DoS attack (False by default).
260 DoS attack (False by default).
260
261
261 Optional argument 'takeorder' indicates whether a predicate function
262 Optional argument 'takeorder' indicates whether a predicate function
262 takes ordering policy as the last argument.
263 takes ordering policy as the last argument.
263
264
264 Optional argument 'weight' indicates the estimated run-time cost, useful
265 Optional argument 'weight' indicates the estimated run-time cost, useful
265 for static optimization, default is 1. Higher weight means more expensive.
266 for static optimization, default is 1. Higher weight means more expensive.
266 Usually, revsets that are fast and return only one revision has a weight of
267 Usually, revsets that are fast and return only one revision has a weight of
267 0.5 (ex. a symbol); revsets with O(changelog) complexity and read only the
268 0.5 (ex. a symbol); revsets with O(changelog) complexity and read only the
268 changelog have weight 10 (ex. author); revsets reading manifest deltas have
269 changelog have weight 10 (ex. author); revsets reading manifest deltas have
269 weight 30 (ex. adds); revset reading manifest contents have weight 100
270 weight 30 (ex. adds); revset reading manifest contents have weight 100
270 (ex. contains). Note: those values are flexible. If the revset has a
271 (ex. contains). Note: those values are flexible. If the revset has a
271 same big-O time complexity as 'contains', but with a smaller constant, it
272 same big-O time complexity as 'contains', but with a smaller constant, it
272 might have a weight of 90.
273 might have a weight of 90.
273
274
274 'revsetpredicate' instance in example above can be used to
275 'revsetpredicate' instance in example above can be used to
275 decorate multiple functions.
276 decorate multiple functions.
276
277
277 Decorated functions are registered automatically at loading
278 Decorated functions are registered automatically at loading
278 extension, if an instance named as 'revsetpredicate' is used for
279 extension, if an instance named as 'revsetpredicate' is used for
279 decorating in extension.
280 decorating in extension.
280
281
281 Otherwise, explicit 'revset.loadpredicate()' is needed.
282 Otherwise, explicit 'revset.loadpredicate()' is needed.
282 """
283 """
283
284
284 _getname = _funcregistrarbase._parsefuncdecl
285 _getname = _funcregistrarbase._parsefuncdecl
285 _docformat = b"``%s``\n %s"
286 _docformat = b"``%s``\n %s"
286
287
287 def _extrasetup(self, name, func, safe=False, takeorder=False, weight=1):
288 def _extrasetup(self, name, func, safe=False, takeorder=False, weight=1):
288 func._safe = safe
289 func._safe = safe
289 func._takeorder = takeorder
290 func._takeorder = takeorder
290 func._weight = weight
291 func._weight = weight
291
292
292
293
293 class filesetpredicate(_funcregistrarbase):
294 class filesetpredicate(_funcregistrarbase):
294 """Decorator to register fileset predicate
295 """Decorator to register fileset predicate
295
296
296 Usage::
297 Usage::
297
298
298 filesetpredicate = registrar.filesetpredicate()
299 filesetpredicate = registrar.filesetpredicate()
299
300
300 @filesetpredicate(b'mypredicate()')
301 @filesetpredicate(b'mypredicate()')
301 def mypredicatefunc(mctx, x):
302 def mypredicatefunc(mctx, x):
302 '''Explanation of this fileset predicate ....
303 '''Explanation of this fileset predicate ....
303 '''
304 '''
304 pass
305 pass
305
306
306 The first string argument is used also in online help.
307 The first string argument is used also in online help.
307
308
308 Optional argument 'callstatus' indicates whether a predicate
309 Optional argument 'callstatus' indicates whether a predicate
309 implies 'matchctx.status()' at runtime or not (False, by
310 implies 'matchctx.status()' at runtime or not (False, by
310 default).
311 default).
311
312
312 Optional argument 'weight' indicates the estimated run-time cost, useful
313 Optional argument 'weight' indicates the estimated run-time cost, useful
313 for static optimization, default is 1. Higher weight means more expensive.
314 for static optimization, default is 1. Higher weight means more expensive.
314 There are predefined weights in the 'filesetlang' module.
315 There are predefined weights in the 'filesetlang' module.
315
316
316 ====== =============================================================
317 ====== =============================================================
317 Weight Description and examples
318 Weight Description and examples
318 ====== =============================================================
319 ====== =============================================================
319 0.5 basic match patterns (e.g. a symbol)
320 0.5 basic match patterns (e.g. a symbol)
320 10 computing status (e.g. added()) or accessing a few files
321 10 computing status (e.g. added()) or accessing a few files
321 30 reading file content for each (e.g. grep())
322 30 reading file content for each (e.g. grep())
322 50 scanning working directory (ignored())
323 50 scanning working directory (ignored())
323 ====== =============================================================
324 ====== =============================================================
324
325
325 'filesetpredicate' instance in example above can be used to
326 'filesetpredicate' instance in example above can be used to
326 decorate multiple functions.
327 decorate multiple functions.
327
328
328 Decorated functions are registered automatically at loading
329 Decorated functions are registered automatically at loading
329 extension, if an instance named as 'filesetpredicate' is used for
330 extension, if an instance named as 'filesetpredicate' is used for
330 decorating in extension.
331 decorating in extension.
331
332
332 Otherwise, explicit 'fileset.loadpredicate()' is needed.
333 Otherwise, explicit 'fileset.loadpredicate()' is needed.
333 """
334 """
334
335
335 _getname = _funcregistrarbase._parsefuncdecl
336 _getname = _funcregistrarbase._parsefuncdecl
336 _docformat = b"``%s``\n %s"
337 _docformat = b"``%s``\n %s"
337
338
338 def _extrasetup(self, name, func, callstatus=False, weight=1):
339 def _extrasetup(self, name, func, callstatus=False, weight=1):
339 func._callstatus = callstatus
340 func._callstatus = callstatus
340 func._weight = weight
341 func._weight = weight
341
342
342
343
343 class _templateregistrarbase(_funcregistrarbase):
344 class _templateregistrarbase(_funcregistrarbase):
344 """Base of decorator to register functions as template specific one"""
345 """Base of decorator to register functions as template specific one"""
345
346
346 _docformat = b":%s: %s"
347 _docformat = b":%s: %s"
347
348
348
349
349 class templatekeyword(_templateregistrarbase):
350 class templatekeyword(_templateregistrarbase):
350 """Decorator to register template keyword
351 """Decorator to register template keyword
351
352
352 Usage::
353 Usage::
353
354
354 templatekeyword = registrar.templatekeyword()
355 templatekeyword = registrar.templatekeyword()
355
356
356 # new API (since Mercurial 4.6)
357 # new API (since Mercurial 4.6)
357 @templatekeyword(b'mykeyword', requires={b'repo', b'ctx'})
358 @templatekeyword(b'mykeyword', requires={b'repo', b'ctx'})
358 def mykeywordfunc(context, mapping):
359 def mykeywordfunc(context, mapping):
359 '''Explanation of this template keyword ....
360 '''Explanation of this template keyword ....
360 '''
361 '''
361 pass
362 pass
362
363
363 The first string argument is used also in online help.
364 The first string argument is used also in online help.
364
365
365 Optional argument 'requires' should be a collection of resource names
366 Optional argument 'requires' should be a collection of resource names
366 which the template keyword depends on.
367 which the template keyword depends on.
367
368
368 'templatekeyword' instance in example above can be used to
369 'templatekeyword' instance in example above can be used to
369 decorate multiple functions.
370 decorate multiple functions.
370
371
371 Decorated functions are registered automatically at loading
372 Decorated functions are registered automatically at loading
372 extension, if an instance named as 'templatekeyword' is used for
373 extension, if an instance named as 'templatekeyword' is used for
373 decorating in extension.
374 decorating in extension.
374
375
375 Otherwise, explicit 'templatekw.loadkeyword()' is needed.
376 Otherwise, explicit 'templatekw.loadkeyword()' is needed.
376 """
377 """
377
378
378 def _extrasetup(self, name, func, requires=()):
379 def _extrasetup(self, name, func, requires=()):
379 func._requires = requires
380 func._requires = requires
380
381
381
382
382 class templatefilter(_templateregistrarbase):
383 class templatefilter(_templateregistrarbase):
383 """Decorator to register template filer
384 """Decorator to register template filer
384
385
385 Usage::
386 Usage::
386
387
387 templatefilter = registrar.templatefilter()
388 templatefilter = registrar.templatefilter()
388
389
389 @templatefilter(b'myfilter', intype=bytes)
390 @templatefilter(b'myfilter', intype=bytes)
390 def myfilterfunc(text):
391 def myfilterfunc(text):
391 '''Explanation of this template filter ....
392 '''Explanation of this template filter ....
392 '''
393 '''
393 pass
394 pass
394
395
395 The first string argument is used also in online help.
396 The first string argument is used also in online help.
396
397
397 Optional argument 'intype' defines the type of the input argument,
398 Optional argument 'intype' defines the type of the input argument,
398 which should be (bytes, int, templateutil.date, or None for any.)
399 which should be (bytes, int, templateutil.date, or None for any.)
399
400
400 'templatefilter' instance in example above can be used to
401 'templatefilter' instance in example above can be used to
401 decorate multiple functions.
402 decorate multiple functions.
402
403
403 Decorated functions are registered automatically at loading
404 Decorated functions are registered automatically at loading
404 extension, if an instance named as 'templatefilter' is used for
405 extension, if an instance named as 'templatefilter' is used for
405 decorating in extension.
406 decorating in extension.
406
407
407 Otherwise, explicit 'templatefilters.loadkeyword()' is needed.
408 Otherwise, explicit 'templatefilters.loadkeyword()' is needed.
408 """
409 """
409
410
410 def _extrasetup(self, name, func, intype=None):
411 def _extrasetup(self, name, func, intype=None):
411 func._intype = intype
412 func._intype = intype
412
413
413
414
414 class templatefunc(_templateregistrarbase):
415 class templatefunc(_templateregistrarbase):
415 """Decorator to register template function
416 """Decorator to register template function
416
417
417 Usage::
418 Usage::
418
419
419 templatefunc = registrar.templatefunc()
420 templatefunc = registrar.templatefunc()
420
421
421 @templatefunc(b'myfunc(arg1, arg2[, arg3])', argspec=b'arg1 arg2 arg3',
422 @templatefunc(b'myfunc(arg1, arg2[, arg3])', argspec=b'arg1 arg2 arg3',
422 requires={b'ctx'})
423 requires={b'ctx'})
423 def myfuncfunc(context, mapping, args):
424 def myfuncfunc(context, mapping, args):
424 '''Explanation of this template function ....
425 '''Explanation of this template function ....
425 '''
426 '''
426 pass
427 pass
427
428
428 The first string argument is used also in online help.
429 The first string argument is used also in online help.
429
430
430 If optional 'argspec' is defined, the function will receive 'args' as
431 If optional 'argspec' is defined, the function will receive 'args' as
431 a dict of named arguments. Otherwise 'args' is a list of positional
432 a dict of named arguments. Otherwise 'args' is a list of positional
432 arguments.
433 arguments.
433
434
434 Optional argument 'requires' should be a collection of resource names
435 Optional argument 'requires' should be a collection of resource names
435 which the template function depends on.
436 which the template function depends on.
436
437
437 'templatefunc' instance in example above can be used to
438 'templatefunc' instance in example above can be used to
438 decorate multiple functions.
439 decorate multiple functions.
439
440
440 Decorated functions are registered automatically at loading
441 Decorated functions are registered automatically at loading
441 extension, if an instance named as 'templatefunc' is used for
442 extension, if an instance named as 'templatefunc' is used for
442 decorating in extension.
443 decorating in extension.
443
444
444 Otherwise, explicit 'templatefuncs.loadfunction()' is needed.
445 Otherwise, explicit 'templatefuncs.loadfunction()' is needed.
445 """
446 """
446
447
447 _getname = _funcregistrarbase._parsefuncdecl
448 _getname = _funcregistrarbase._parsefuncdecl
448
449
449 def _extrasetup(self, name, func, argspec=None, requires=()):
450 def _extrasetup(self, name, func, argspec=None, requires=()):
450 func._argspec = argspec
451 func._argspec = argspec
451 func._requires = requires
452 func._requires = requires
452
453
453
454
454 class internalmerge(_funcregistrarbase):
455 class internalmerge(_funcregistrarbase):
455 """Decorator to register in-process merge tool
456 """Decorator to register in-process merge tool
456
457
457 Usage::
458 Usage::
458
459
459 internalmerge = registrar.internalmerge()
460 internalmerge = registrar.internalmerge()
460
461
461 @internalmerge(b'mymerge', internalmerge.mergeonly,
462 @internalmerge(b'mymerge', internalmerge.mergeonly,
462 onfailure=None, precheck=None,
463 onfailure=None, precheck=None,
463 binary=False, symlink=False):
464 binary=False, symlink=False):
464 def mymergefunc(repo, mynode, orig, fcd, fco, fca,
465 def mymergefunc(repo, mynode, orig, fcd, fco, fca,
465 toolconf, files, labels=None):
466 toolconf, files, labels=None):
466 '''Explanation of this internal merge tool ....
467 '''Explanation of this internal merge tool ....
467 '''
468 '''
468 return 1, False # means "conflicted", "no deletion needed"
469 return 1, False # means "conflicted", "no deletion needed"
469
470
470 The first string argument is used to compose actual merge tool name,
471 The first string argument is used to compose actual merge tool name,
471 ":name" and "internal:name" (the latter is historical one).
472 ":name" and "internal:name" (the latter is historical one).
472
473
473 The second argument is one of merge types below:
474 The second argument is one of merge types below:
474
475
475 ========== ======== ======== =========
476 ========== ======== ======== =========
476 merge type precheck premerge fullmerge
477 merge type precheck premerge fullmerge
477 ========== ======== ======== =========
478 ========== ======== ======== =========
478 nomerge x x x
479 nomerge x x x
479 mergeonly o x o
480 mergeonly o x o
480 fullmerge o o o
481 fullmerge o o o
481 ========== ======== ======== =========
482 ========== ======== ======== =========
482
483
483 Optional argument 'onfailure' is the format of warning message
484 Optional argument 'onfailure' is the format of warning message
484 to be used at failure of merging (target filename is specified
485 to be used at failure of merging (target filename is specified
485 at formatting). Or, None or so, if warning message should be
486 at formatting). Or, None or so, if warning message should be
486 suppressed.
487 suppressed.
487
488
488 Optional argument 'precheck' is the function to be used
489 Optional argument 'precheck' is the function to be used
489 before actual invocation of internal merge tool itself.
490 before actual invocation of internal merge tool itself.
490 It takes as same arguments as internal merge tool does, other than
491 It takes as same arguments as internal merge tool does, other than
491 'files' and 'labels'. If it returns false value, merging is aborted
492 'files' and 'labels'. If it returns false value, merging is aborted
492 immediately (and file is marked as "unresolved").
493 immediately (and file is marked as "unresolved").
493
494
494 Optional argument 'binary' is a binary files capability of internal
495 Optional argument 'binary' is a binary files capability of internal
495 merge tool. 'nomerge' merge type implies binary=True.
496 merge tool. 'nomerge' merge type implies binary=True.
496
497
497 Optional argument 'symlink' is a symlinks capability of inetrnal
498 Optional argument 'symlink' is a symlinks capability of inetrnal
498 merge function. 'nomerge' merge type implies symlink=True.
499 merge function. 'nomerge' merge type implies symlink=True.
499
500
500 'internalmerge' instance in example above can be used to
501 'internalmerge' instance in example above can be used to
501 decorate multiple functions.
502 decorate multiple functions.
502
503
503 Decorated functions are registered automatically at loading
504 Decorated functions are registered automatically at loading
504 extension, if an instance named as 'internalmerge' is used for
505 extension, if an instance named as 'internalmerge' is used for
505 decorating in extension.
506 decorating in extension.
506
507
507 Otherwise, explicit 'filemerge.loadinternalmerge()' is needed.
508 Otherwise, explicit 'filemerge.loadinternalmerge()' is needed.
508 """
509 """
509
510
510 _docformat = b"``:%s``\n %s"
511 _docformat = b"``:%s``\n %s"
511
512
512 # merge type definitions:
513 # merge type definitions:
513 nomerge = None
514 nomerge = None
514 mergeonly = b'mergeonly' # just the full merge, no premerge
515 mergeonly = b'mergeonly' # just the full merge, no premerge
515 fullmerge = b'fullmerge' # both premerge and merge
516 fullmerge = b'fullmerge' # both premerge and merge
516
517
517 def _extrasetup(
518 def _extrasetup(
518 self,
519 self,
519 name,
520 name,
520 func,
521 func,
521 mergetype,
522 mergetype,
522 onfailure=None,
523 onfailure=None,
523 precheck=None,
524 precheck=None,
524 binary=False,
525 binary=False,
525 symlink=False,
526 symlink=False,
526 ):
527 ):
527 func.mergetype = mergetype
528 func.mergetype = mergetype
528 func.onfailure = onfailure
529 func.onfailure = onfailure
529 func.precheck = precheck
530 func.precheck = precheck
530
531
531 binarycap = binary or mergetype == self.nomerge
532 binarycap = binary or mergetype == self.nomerge
532 symlinkcap = symlink or mergetype == self.nomerge
533 symlinkcap = symlink or mergetype == self.nomerge
533
534
534 # actual capabilities, which this internal merge tool has
535 # actual capabilities, which this internal merge tool has
535 func.capabilities = {b"binary": binarycap, b"symlink": symlinkcap}
536 func.capabilities = {b"binary": binarycap, b"symlink": symlinkcap}
537
538
539 class verify_check(_funcregistrarbase):
540 """Decorator to register a check for admin::verify
541
542 options is a list of (name, default value, help) to be passed to the check
543 """
544
545 def __init__(self, table=None, alias_table=None):
546 super().__init__(table)
547 if alias_table is None:
548 self._alias_table = {}
549 else:
550 self._alias_table = alias_table
551
552 def _extrasetup(
553 self,
554 name,
555 func,
556 alias: Optional[bytes] = None,
557 options: Optional[List[Tuple[bytes, Any, bytes]]] = None,
558 ):
559 func.alias = alias
560 func.options = options
561
562 if alias:
563 self._alias_table[alias] = name
@@ -1,455 +1,458 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 abort
3 abort
4 add
4 add
5 addremove
5 addremove
6 admin::verify
6 annotate
7 annotate
7 archive
8 archive
8 backout
9 backout
9 bisect
10 bisect
10 bookmarks
11 bookmarks
11 branch
12 branch
12 branches
13 branches
13 bundle
14 bundle
14 cat
15 cat
15 clone
16 clone
16 commit
17 commit
17 config
18 config
18 continue
19 continue
19 copy
20 copy
20 diff
21 diff
21 export
22 export
22 files
23 files
23 forget
24 forget
24 graft
25 graft
25 grep
26 grep
26 heads
27 heads
27 help
28 help
28 identify
29 identify
29 import
30 import
30 incoming
31 incoming
31 init
32 init
32 locate
33 locate
33 log
34 log
34 manifest
35 manifest
35 merge
36 merge
36 outgoing
37 outgoing
37 parents
38 parents
38 paths
39 paths
39 phase
40 phase
40 pull
41 pull
41 purge
42 purge
42 push
43 push
43 recover
44 recover
44 remove
45 remove
45 rename
46 rename
46 resolve
47 resolve
47 revert
48 revert
48 rollback
49 rollback
49 root
50 root
50 serve
51 serve
51 shelve
52 shelve
52 status
53 status
53 summary
54 summary
54 tag
55 tag
55 tags
56 tags
56 tip
57 tip
57 unbundle
58 unbundle
58 unshelve
59 unshelve
59 update
60 update
60 verify
61 verify
61 version
62 version
62
63
63 Show all commands that start with "a"
64 Show all commands that start with "a"
64 $ hg debugcomplete a
65 $ hg debugcomplete a
65 abort
66 abort
66 add
67 add
67 addremove
68 addremove
69 admin::verify
68 annotate
70 annotate
69 archive
71 archive
70
72
71 Do not show debug commands if there are other candidates
73 Do not show debug commands if there are other candidates
72 $ hg debugcomplete d
74 $ hg debugcomplete d
73 diff
75 diff
74
76
75 Show debug commands if there are no other candidates
77 Show debug commands if there are no other candidates
76 $ hg debugcomplete debug
78 $ hg debugcomplete debug
77 debug-delta-find
79 debug-delta-find
78 debug-repair-issue6528
80 debug-repair-issue6528
79 debug-revlog-index
81 debug-revlog-index
80 debug-revlog-stats
82 debug-revlog-stats
81 debug::stable-tail-sort
83 debug::stable-tail-sort
82 debug::stable-tail-sort-leaps
84 debug::stable-tail-sort-leaps
83 debugancestor
85 debugancestor
84 debugantivirusrunning
86 debugantivirusrunning
85 debugapplystreamclonebundle
87 debugapplystreamclonebundle
86 debugbackupbundle
88 debugbackupbundle
87 debugbuilddag
89 debugbuilddag
88 debugbundle
90 debugbundle
89 debugcapabilities
91 debugcapabilities
90 debugchangedfiles
92 debugchangedfiles
91 debugcheckstate
93 debugcheckstate
92 debugcolor
94 debugcolor
93 debugcommands
95 debugcommands
94 debugcomplete
96 debugcomplete
95 debugconfig
97 debugconfig
96 debugcreatestreamclonebundle
98 debugcreatestreamclonebundle
97 debugdag
99 debugdag
98 debugdata
100 debugdata
99 debugdate
101 debugdate
100 debugdeltachain
102 debugdeltachain
101 debugdirstate
103 debugdirstate
102 debugdirstateignorepatternshash
104 debugdirstateignorepatternshash
103 debugdiscovery
105 debugdiscovery
104 debugdownload
106 debugdownload
105 debugextensions
107 debugextensions
106 debugfileset
108 debugfileset
107 debugformat
109 debugformat
108 debugfsinfo
110 debugfsinfo
109 debuggetbundle
111 debuggetbundle
110 debugignore
112 debugignore
111 debugindexdot
113 debugindexdot
112 debugindexstats
114 debugindexstats
113 debuginstall
115 debuginstall
114 debugknown
116 debugknown
115 debuglabelcomplete
117 debuglabelcomplete
116 debuglocks
118 debuglocks
117 debugmanifestfulltextcache
119 debugmanifestfulltextcache
118 debugmergestate
120 debugmergestate
119 debugnamecomplete
121 debugnamecomplete
120 debugnodemap
122 debugnodemap
121 debugobsolete
123 debugobsolete
122 debugp1copies
124 debugp1copies
123 debugp2copies
125 debugp2copies
124 debugpathcomplete
126 debugpathcomplete
125 debugpathcopies
127 debugpathcopies
126 debugpeer
128 debugpeer
127 debugpickmergetool
129 debugpickmergetool
128 debugpushkey
130 debugpushkey
129 debugpvec
131 debugpvec
130 debugrebuilddirstate
132 debugrebuilddirstate
131 debugrebuildfncache
133 debugrebuildfncache
132 debugrename
134 debugrename
133 debugrequires
135 debugrequires
134 debugrevlog
136 debugrevlog
135 debugrevlogindex
137 debugrevlogindex
136 debugrevspec
138 debugrevspec
137 debugserve
139 debugserve
138 debugsetparents
140 debugsetparents
139 debugshell
141 debugshell
140 debugsidedata
142 debugsidedata
141 debugssl
143 debugssl
142 debugstrip
144 debugstrip
143 debugsub
145 debugsub
144 debugsuccessorssets
146 debugsuccessorssets
145 debugtagscache
147 debugtagscache
146 debugtemplate
148 debugtemplate
147 debuguigetpass
149 debuguigetpass
148 debuguiprompt
150 debuguiprompt
149 debugupdatecaches
151 debugupdatecaches
150 debugupgraderepo
152 debugupgraderepo
151 debugwalk
153 debugwalk
152 debugwhyunstable
154 debugwhyunstable
153 debugwireargs
155 debugwireargs
154 debugwireproto
156 debugwireproto
155
157
156 Do not show the alias of a debug command if there are other candidates
158 Do not show the alias of a debug command if there are other candidates
157 (this should hide rawcommit)
159 (this should hide rawcommit)
158 $ hg debugcomplete r
160 $ hg debugcomplete r
159 recover
161 recover
160 remove
162 remove
161 rename
163 rename
162 resolve
164 resolve
163 revert
165 revert
164 rollback
166 rollback
165 root
167 root
166 Show the alias of a debug command if there are no other candidates
168 Show the alias of a debug command if there are no other candidates
167 $ hg debugcomplete rawc
169 $ hg debugcomplete rawc
168
170
169
171
170 Show the global options
172 Show the global options
171 $ hg debugcomplete --options | sort
173 $ hg debugcomplete --options | sort
172 --color
174 --color
173 --config
175 --config
174 --cwd
176 --cwd
175 --debug
177 --debug
176 --debugger
178 --debugger
177 --encoding
179 --encoding
178 --encodingmode
180 --encodingmode
179 --help
181 --help
180 --hidden
182 --hidden
181 --noninteractive
183 --noninteractive
182 --pager
184 --pager
183 --profile
185 --profile
184 --quiet
186 --quiet
185 --repository
187 --repository
186 --time
188 --time
187 --traceback
189 --traceback
188 --verbose
190 --verbose
189 --version
191 --version
190 -R
192 -R
191 -h
193 -h
192 -q
194 -q
193 -v
195 -v
194 -y
196 -y
195
197
196 Show the options for the "serve" command
198 Show the options for the "serve" command
197 $ hg debugcomplete --options serve | sort
199 $ hg debugcomplete --options serve | sort
198 --accesslog
200 --accesslog
199 --address
201 --address
200 --certificate
202 --certificate
201 --cmdserver
203 --cmdserver
202 --color
204 --color
203 --config
205 --config
204 --cwd
206 --cwd
205 --daemon
207 --daemon
206 --daemon-postexec
208 --daemon-postexec
207 --debug
209 --debug
208 --debugger
210 --debugger
209 --encoding
211 --encoding
210 --encodingmode
212 --encodingmode
211 --errorlog
213 --errorlog
212 --help
214 --help
213 --hidden
215 --hidden
214 --ipv6
216 --ipv6
215 --name
217 --name
216 --noninteractive
218 --noninteractive
217 --pager
219 --pager
218 --pid-file
220 --pid-file
219 --port
221 --port
220 --prefix
222 --prefix
221 --print-url
223 --print-url
222 --profile
224 --profile
223 --quiet
225 --quiet
224 --repository
226 --repository
225 --stdio
227 --stdio
226 --style
228 --style
227 --subrepos
229 --subrepos
228 --templates
230 --templates
229 --time
231 --time
230 --traceback
232 --traceback
231 --verbose
233 --verbose
232 --version
234 --version
233 --web-conf
235 --web-conf
234 -6
236 -6
235 -A
237 -A
236 -E
238 -E
237 -R
239 -R
238 -S
240 -S
239 -a
241 -a
240 -d
242 -d
241 -h
243 -h
242 -n
244 -n
243 -p
245 -p
244 -q
246 -q
245 -t
247 -t
246 -v
248 -v
247 -y
249 -y
248
250
249 Show an error if we use --options with an ambiguous abbreviation
251 Show an error if we use --options with an ambiguous abbreviation
250 $ hg debugcomplete --options s
252 $ hg debugcomplete --options s
251 hg: command 's' is ambiguous:
253 hg: command 's' is ambiguous:
252 serve shelve showconfig status summary
254 serve shelve showconfig status summary
253 [10]
255 [10]
254
256
255 Show all commands + options
257 Show all commands + options
256 $ hg debugcommands
258 $ hg debugcommands
257 abort: dry-run
259 abort: dry-run
258 add: include, exclude, subrepos, dry-run
260 add: include, exclude, subrepos, dry-run
259 addremove: similarity, subrepos, include, exclude, dry-run
261 addremove: similarity, subrepos, include, exclude, dry-run
262 admin::verify: check, option
260 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template
263 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template
261 archive: no-decode, prefix, rev, type, subrepos, include, exclude
264 archive: no-decode, prefix, rev, type, subrepos, include, exclude
262 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
265 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
263 bisect: reset, good, bad, skip, extend, command, noupdate
266 bisect: reset, good, bad, skip, extend, command, noupdate
264 bookmarks: force, rev, delete, rename, inactive, list, template
267 bookmarks: force, rev, delete, rename, inactive, list, template
265 branch: force, clean, rev
268 branch: force, clean, rev
266 branches: active, closed, rev, template
269 branches: active, closed, rev, template
267 bundle: exact, force, rev, branch, base, all, type, ssh, remotecmd, insecure
270 bundle: exact, force, rev, branch, base, all, type, ssh, remotecmd, insecure
268 cat: output, rev, decode, include, exclude, template
271 cat: output, rev, decode, include, exclude, template
269 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
272 clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
270 commit: addremove, close-branch, amend, secret, draft, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
273 commit: addremove, close-branch, amend, secret, draft, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
271 config: untrusted, exp-all-known, edit, local, source, shared, non-shared, global, template
274 config: untrusted, exp-all-known, edit, local, source, shared, non-shared, global, template
272 continue: dry-run
275 continue: dry-run
273 copy: forget, after, at-rev, force, include, exclude, dry-run
276 copy: forget, after, at-rev, force, include, exclude, dry-run
274 debug-delta-find: changelog, manifest, dir, template, source
277 debug-delta-find: changelog, manifest, dir, template, source
275 debug-repair-issue6528: to-report, from-report, paranoid, dry-run
278 debug-repair-issue6528: to-report, from-report, paranoid, dry-run
276 debug-revlog-index: changelog, manifest, dir, template
279 debug-revlog-index: changelog, manifest, dir, template
277 debug-revlog-stats: changelog, manifest, filelogs, template
280 debug-revlog-stats: changelog, manifest, filelogs, template
278 debug::stable-tail-sort: template
281 debug::stable-tail-sort: template
279 debug::stable-tail-sort-leaps: template, specific
282 debug::stable-tail-sort-leaps: template, specific
280 debugancestor:
283 debugancestor:
281 debugantivirusrunning:
284 debugantivirusrunning:
282 debugapplystreamclonebundle:
285 debugapplystreamclonebundle:
283 debugbackupbundle: recover, patch, git, limit, no-merges, stat, graph, style, template
286 debugbackupbundle: recover, patch, git, limit, no-merges, stat, graph, style, template
284 debugbuilddag: mergeable-file, overwritten-file, new-file, from-existing
287 debugbuilddag: mergeable-file, overwritten-file, new-file, from-existing
285 debugbundle: all, part-type, spec
288 debugbundle: all, part-type, spec
286 debugcapabilities:
289 debugcapabilities:
287 debugchangedfiles: compute
290 debugchangedfiles: compute
288 debugcheckstate:
291 debugcheckstate:
289 debugcolor: style
292 debugcolor: style
290 debugcommands:
293 debugcommands:
291 debugcomplete: options
294 debugcomplete: options
292 debugcreatestreamclonebundle:
295 debugcreatestreamclonebundle:
293 debugdag: tags, branches, dots, spaces
296 debugdag: tags, branches, dots, spaces
294 debugdata: changelog, manifest, dir
297 debugdata: changelog, manifest, dir
295 debugdate: extended
298 debugdate: extended
296 debugdeltachain: changelog, manifest, dir, template
299 debugdeltachain: changelog, manifest, dir, template
297 debugdirstateignorepatternshash:
300 debugdirstateignorepatternshash:
298 debugdirstate: nodates, dates, datesort, docket, all
301 debugdirstate: nodates, dates, datesort, docket, all
299 debugdiscovery: old, nonheads, rev, seed, local-as-revs, remote-as-revs, ssh, remotecmd, insecure, template
302 debugdiscovery: old, nonheads, rev, seed, local-as-revs, remote-as-revs, ssh, remotecmd, insecure, template
300 debugdownload: output
303 debugdownload: output
301 debugextensions: template
304 debugextensions: template
302 debugfileset: rev, all-files, show-matcher, show-stage
305 debugfileset: rev, all-files, show-matcher, show-stage
303 debugformat: template
306 debugformat: template
304 debugfsinfo:
307 debugfsinfo:
305 debuggetbundle: head, common, type
308 debuggetbundle: head, common, type
306 debugignore:
309 debugignore:
307 debugindexdot: changelog, manifest, dir
310 debugindexdot: changelog, manifest, dir
308 debugindexstats:
311 debugindexstats:
309 debuginstall: template
312 debuginstall: template
310 debugknown:
313 debugknown:
311 debuglabelcomplete:
314 debuglabelcomplete:
312 debuglocks: force-free-lock, force-free-wlock, set-lock, set-wlock
315 debuglocks: force-free-lock, force-free-wlock, set-lock, set-wlock
313 debugmanifestfulltextcache: clear, add
316 debugmanifestfulltextcache: clear, add
314 debugmergestate: style, template
317 debugmergestate: style, template
315 debugnamecomplete:
318 debugnamecomplete:
316 debugnodemap: changelog, manifest, dir, dump-new, dump-disk, check, metadata
319 debugnodemap: changelog, manifest, dir, dump-new, dump-disk, check, metadata
317 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
320 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
318 debugp1copies: rev
321 debugp1copies: rev
319 debugp2copies: rev
322 debugp2copies: rev
320 debugpathcomplete: full, normal, added, removed
323 debugpathcomplete: full, normal, added, removed
321 debugpathcopies: include, exclude
324 debugpathcopies: include, exclude
322 debugpeer:
325 debugpeer:
323 debugpickmergetool: rev, changedelete, include, exclude, tool
326 debugpickmergetool: rev, changedelete, include, exclude, tool
324 debugpushkey:
327 debugpushkey:
325 debugpvec:
328 debugpvec:
326 debugrebuilddirstate: rev, minimal
329 debugrebuilddirstate: rev, minimal
327 debugrebuildfncache: only-data
330 debugrebuildfncache: only-data
328 debugrename: rev
331 debugrename: rev
329 debugrequires:
332 debugrequires:
330 debugrevlog: changelog, manifest, dir, dump
333 debugrevlog: changelog, manifest, dir, dump
331 debugrevlogindex: changelog, manifest, dir, format
334 debugrevlogindex: changelog, manifest, dir, format
332 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
335 debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
333 debugserve: sshstdio, logiofd, logiofile
336 debugserve: sshstdio, logiofd, logiofile
334 debugsetparents:
337 debugsetparents:
335 debugshell: command
338 debugshell: command
336 debugsidedata: changelog, manifest, dir
339 debugsidedata: changelog, manifest, dir
337 debugssl:
340 debugssl:
338 debugstrip: rev, force, no-backup, nobackup, , keep, bookmark, soft
341 debugstrip: rev, force, no-backup, nobackup, , keep, bookmark, soft
339 debugsub: rev
342 debugsub: rev
340 debugsuccessorssets: closest
343 debugsuccessorssets: closest
341 debugtagscache:
344 debugtagscache:
342 debugtemplate: rev, define
345 debugtemplate: rev, define
343 debuguigetpass: prompt
346 debuguigetpass: prompt
344 debuguiprompt: prompt
347 debuguiprompt: prompt
345 debugupdatecaches:
348 debugupdatecaches:
346 debugupgraderepo: optimize, run, backup, changelog, manifest, filelogs
349 debugupgraderepo: optimize, run, backup, changelog, manifest, filelogs
347 debugwalk: include, exclude
350 debugwalk: include, exclude
348 debugwhyunstable:
351 debugwhyunstable:
349 debugwireargs: three, four, five, ssh, remotecmd, insecure
352 debugwireargs: three, four, five, ssh, remotecmd, insecure
350 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
353 debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
351 diff: rev, from, to, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
354 diff: rev, from, to, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
352 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
355 export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
353 files: rev, print0, include, exclude, template, subrepos
356 files: rev, print0, include, exclude, template, subrepos
354 forget: interactive, include, exclude, dry-run
357 forget: interactive, include, exclude, dry-run
355 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
358 graft: rev, base, continue, stop, abort, edit, log, no-commit, force, currentdate, currentuser, date, user, tool, dry-run
356 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
359 grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, all-files, user, date, template, include, exclude
357 heads: rev, topo, active, closed, style, template
360 heads: rev, topo, active, closed, style, template
358 help: extension, command, keyword, system
361 help: extension, command, keyword, system
359 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
362 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure, template
360 import: strip, base, secret, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
363 import: strip, base, secret, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
361 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
364 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
362 init: ssh, remotecmd, insecure
365 init: ssh, remotecmd, insecure
363 locate: rev, print0, fullpath, include, exclude
366 locate: rev, print0, fullpath, include, exclude
364 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, bookmark, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
367 log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, bookmark, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
365 manifest: rev, all, template
368 manifest: rev, all, template
366 merge: force, rev, preview, abort, tool
369 merge: force, rev, preview, abort, tool
367 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
370 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
368 parents: rev, style, template
371 parents: rev, style, template
369 paths: template
372 paths: template
370 phase: public, draft, secret, force, rev
373 phase: public, draft, secret, force, rev
371 pull: update, force, confirm, rev, bookmark, branch, remote-hidden, ssh, remotecmd, insecure
374 pull: update, force, confirm, rev, bookmark, branch, remote-hidden, ssh, remotecmd, insecure
372 purge: abort-on-err, all, ignored, dirs, files, print, print0, confirm, include, exclude
375 purge: abort-on-err, all, ignored, dirs, files, print, print0, confirm, include, exclude
373 push: force, rev, bookmark, all-bookmarks, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
376 push: force, rev, bookmark, all-bookmarks, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure
374 recover: verify
377 recover: verify
375 remove: after, force, subrepos, include, exclude, dry-run
378 remove: after, force, subrepos, include, exclude, dry-run
376 rename: forget, after, at-rev, force, include, exclude, dry-run
379 rename: forget, after, at-rev, force, include, exclude, dry-run
377 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
380 resolve: all, list, mark, unmark, no-status, re-merge, tool, include, exclude, template
378 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
381 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
379 rollback: dry-run, force
382 rollback: dry-run, force
380 root: template
383 root: template
381 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate, print-url, subrepos
384 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate, print-url, subrepos
382 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
385 shelve: addremove, unknown, cleanup, date, delete, edit, keep, list, message, name, patch, interactive, stat, include, exclude
383 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
386 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, terse, copies, print0, rev, change, include, exclude, subrepos, template
384 summary: remote
387 summary: remote
385 tag: force, local, rev, remove, edit, message, date, user
388 tag: force, local, rev, remove, edit, message, date, user
386 tags: template
389 tags: template
387 tip: patch, git, style, template
390 tip: patch, git, style, template
388 unbundle: update
391 unbundle: update
389 unshelve: abort, continue, interactive, keep, name, tool, date
392 unshelve: abort, continue, interactive, keep, name, tool, date
390 update: clean, check, merge, date, rev, tool
393 update: clean, check, merge, date, rev, tool
391 verify: full
394 verify: full
392 version: template
395 version: template
393
396
394 $ hg init a
397 $ hg init a
395 $ cd a
398 $ cd a
396 $ echo fee > fee
399 $ echo fee > fee
397 $ hg ci -q -Amfee
400 $ hg ci -q -Amfee
398 $ hg tag fee
401 $ hg tag fee
399 $ mkdir fie
402 $ mkdir fie
400 $ echo dead > fie/dead
403 $ echo dead > fie/dead
401 $ echo live > fie/live
404 $ echo live > fie/live
402 $ hg bookmark fo
405 $ hg bookmark fo
403 $ hg branch -q fie
406 $ hg branch -q fie
404 $ hg ci -q -Amfie
407 $ hg ci -q -Amfie
405 $ echo fo > fo
408 $ echo fo > fo
406 $ hg branch -qf default
409 $ hg branch -qf default
407 $ hg ci -q -Amfo
410 $ hg ci -q -Amfo
408 $ echo Fum > Fum
411 $ echo Fum > Fum
409 $ hg ci -q -AmFum
412 $ hg ci -q -AmFum
410 $ hg bookmark Fum
413 $ hg bookmark Fum
411
414
412 Test debugpathcomplete
415 Test debugpathcomplete
413
416
414 $ hg debugpathcomplete f
417 $ hg debugpathcomplete f
415 fee
418 fee
416 fie
419 fie
417 fo
420 fo
418 $ hg debugpathcomplete -f f
421 $ hg debugpathcomplete -f f
419 fee
422 fee
420 fie/dead
423 fie/dead
421 fie/live
424 fie/live
422 fo
425 fo
423
426
424 $ hg rm Fum
427 $ hg rm Fum
425 $ hg debugpathcomplete -r F
428 $ hg debugpathcomplete -r F
426 Fum
429 Fum
427
430
428 Test debugnamecomplete
431 Test debugnamecomplete
429
432
430 $ hg debugnamecomplete
433 $ hg debugnamecomplete
431 Fum
434 Fum
432 default
435 default
433 fee
436 fee
434 fie
437 fie
435 fo
438 fo
436 tip
439 tip
437 $ hg debugnamecomplete f
440 $ hg debugnamecomplete f
438 fee
441 fee
439 fie
442 fie
440 fo
443 fo
441
444
442 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
445 Test debuglabelcomplete, a deprecated name for debugnamecomplete that is still
443 used for completions in some shells.
446 used for completions in some shells.
444
447
445 $ hg debuglabelcomplete
448 $ hg debuglabelcomplete
446 Fum
449 Fum
447 default
450 default
448 fee
451 fee
449 fie
452 fie
450 fo
453 fo
451 tip
454 tip
452 $ hg debuglabelcomplete f
455 $ hg debuglabelcomplete f
453 fee
456 fee
454 fie
457 fie
455 fo
458 fo
@@ -1,573 +1,577 b''
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo a > a
3 $ echo a > a
4 $ hg ci -A -d'1 0' -m a
4 $ hg ci -A -d'1 0' -m a
5 adding a
5 adding a
6
6
7 $ cd ..
7 $ cd ..
8
8
9 $ hg init b
9 $ hg init b
10 $ cd b
10 $ cd b
11 $ echo b > b
11 $ echo b > b
12 $ hg ci -A -d'1 0' -m b
12 $ hg ci -A -d'1 0' -m b
13 adding b
13 adding b
14
14
15 $ cd ..
15 $ cd ..
16
16
17 $ hg clone a c
17 $ hg clone a c
18 updating to branch default
18 updating to branch default
19 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
19 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 $ cd c
20 $ cd c
21 $ cat >> .hg/hgrc <<EOF
21 $ cat >> .hg/hgrc <<EOF
22 > [paths]
22 > [paths]
23 > relative = ../a
23 > relative = ../a
24 > EOF
24 > EOF
25 $ hg pull -f ../b
25 $ hg pull -f ../b
26 pulling from ../b
26 pulling from ../b
27 searching for changes
27 searching for changes
28 warning: repository is unrelated
28 warning: repository is unrelated
29 requesting all changes
29 requesting all changes
30 adding changesets
30 adding changesets
31 adding manifests
31 adding manifests
32 adding file changes
32 adding file changes
33 added 1 changesets with 1 changes to 1 files (+1 heads)
33 added 1 changesets with 1 changes to 1 files (+1 heads)
34 new changesets b6c483daf290
34 new changesets b6c483daf290
35 (run 'hg heads' to see heads, 'hg merge' to merge)
35 (run 'hg heads' to see heads, 'hg merge' to merge)
36 $ hg merge
36 $ hg merge
37 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
37 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 (branch merge, don't forget to commit)
38 (branch merge, don't forget to commit)
39
39
40 $ cd ..
40 $ cd ..
41
41
42 Testing -R/--repository:
42 Testing -R/--repository:
43
43
44 $ hg -R a tip
44 $ hg -R a tip
45 changeset: 0:8580ff50825a
45 changeset: 0:8580ff50825a
46 tag: tip
46 tag: tip
47 user: test
47 user: test
48 date: Thu Jan 01 00:00:01 1970 +0000
48 date: Thu Jan 01 00:00:01 1970 +0000
49 summary: a
49 summary: a
50
50
51 $ hg --repository b tip
51 $ hg --repository b tip
52 changeset: 0:b6c483daf290
52 changeset: 0:b6c483daf290
53 tag: tip
53 tag: tip
54 user: test
54 user: test
55 date: Thu Jan 01 00:00:01 1970 +0000
55 date: Thu Jan 01 00:00:01 1970 +0000
56 summary: b
56 summary: b
57
57
58
58
59 -R with a URL:
59 -R with a URL:
60
60
61 $ hg -R file:a identify
61 $ hg -R file:a identify
62 8580ff50825a tip
62 8580ff50825a tip
63 $ hg -R file://localhost/`pwd`/a/ identify
63 $ hg -R file://localhost/`pwd`/a/ identify
64 8580ff50825a tip
64 8580ff50825a tip
65
65
66 -R with path aliases:
66 -R with path aliases:
67
67
68 $ cd c
68 $ cd c
69 $ hg -R default identify
69 $ hg -R default identify
70 8580ff50825a tip
70 8580ff50825a tip
71 $ hg -R relative identify
71 $ hg -R relative identify
72 8580ff50825a tip
72 8580ff50825a tip
73 $ echo '[paths]' >> $HGRCPATH
73 $ echo '[paths]' >> $HGRCPATH
74 $ echo 'relativetohome = a' >> $HGRCPATH
74 $ echo 'relativetohome = a' >> $HGRCPATH
75 $ hg path | grep relativetohome
75 $ hg path | grep relativetohome
76 relativetohome = $TESTTMP/a
76 relativetohome = $TESTTMP/a
77 $ HOME=`pwd`/../ hg path | grep relativetohome
77 $ HOME=`pwd`/../ hg path | grep relativetohome
78 relativetohome = $TESTTMP/a
78 relativetohome = $TESTTMP/a
79 $ HOME=`pwd`/../ hg -R relativetohome identify
79 $ HOME=`pwd`/../ hg -R relativetohome identify
80 8580ff50825a tip
80 8580ff50825a tip
81 $ cd ..
81 $ cd ..
82
82
83 #if no-outer-repo
83 #if no-outer-repo
84
84
85 Implicit -R:
85 Implicit -R:
86
86
87 $ hg ann a/a
87 $ hg ann a/a
88 0: a
88 0: a
89 $ hg ann a/a a/a
89 $ hg ann a/a a/a
90 0: a
90 0: a
91 $ hg ann a/a b/b
91 $ hg ann a/a b/b
92 abort: no repository found in '$TESTTMP' (.hg not found)
92 abort: no repository found in '$TESTTMP' (.hg not found)
93 [10]
93 [10]
94 $ hg -R b ann a/a
94 $ hg -R b ann a/a
95 abort: a/a not under root '$TESTTMP/b'
95 abort: a/a not under root '$TESTTMP/b'
96 (consider using '--cwd b')
96 (consider using '--cwd b')
97 [255]
97 [255]
98 $ hg log
98 $ hg log
99 abort: no repository found in '$TESTTMP' (.hg not found)
99 abort: no repository found in '$TESTTMP' (.hg not found)
100 [10]
100 [10]
101
101
102 #endif
102 #endif
103
103
104 Abbreviation of long option:
104 Abbreviation of long option:
105
105
106 $ hg --repo c tip
106 $ hg --repo c tip
107 changeset: 1:b6c483daf290
107 changeset: 1:b6c483daf290
108 tag: tip
108 tag: tip
109 parent: -1:000000000000
109 parent: -1:000000000000
110 user: test
110 user: test
111 date: Thu Jan 01 00:00:01 1970 +0000
111 date: Thu Jan 01 00:00:01 1970 +0000
112 summary: b
112 summary: b
113
113
114
114
115 earlygetopt with duplicate options (36d23de02da1):
115 earlygetopt with duplicate options (36d23de02da1):
116
116
117 $ hg --cwd a --cwd b --cwd c tip
117 $ hg --cwd a --cwd b --cwd c tip
118 changeset: 1:b6c483daf290
118 changeset: 1:b6c483daf290
119 tag: tip
119 tag: tip
120 parent: -1:000000000000
120 parent: -1:000000000000
121 user: test
121 user: test
122 date: Thu Jan 01 00:00:01 1970 +0000
122 date: Thu Jan 01 00:00:01 1970 +0000
123 summary: b
123 summary: b
124
124
125 $ hg --repo c --repository b -R a tip
125 $ hg --repo c --repository b -R a tip
126 changeset: 0:8580ff50825a
126 changeset: 0:8580ff50825a
127 tag: tip
127 tag: tip
128 user: test
128 user: test
129 date: Thu Jan 01 00:00:01 1970 +0000
129 date: Thu Jan 01 00:00:01 1970 +0000
130 summary: a
130 summary: a
131
131
132
132
133 earlygetopt short option without following space:
133 earlygetopt short option without following space:
134
134
135 $ hg -q -Rb tip
135 $ hg -q -Rb tip
136 0:b6c483daf290
136 0:b6c483daf290
137
137
138 earlygetopt with illegal abbreviations:
138 earlygetopt with illegal abbreviations:
139
139
140 $ hg --confi "foo.bar=baz"
140 $ hg --confi "foo.bar=baz"
141 abort: option --config may not be abbreviated
141 abort: option --config may not be abbreviated
142 [10]
142 [10]
143 $ hg --cw a tip
143 $ hg --cw a tip
144 abort: option --cwd may not be abbreviated
144 abort: option --cwd may not be abbreviated
145 [10]
145 [10]
146 $ hg --rep a tip
146 $ hg --rep a tip
147 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
147 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
148 [10]
148 [10]
149 $ hg --repositor a tip
149 $ hg --repositor a tip
150 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
150 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
151 [10]
151 [10]
152 $ hg -qR a tip
152 $ hg -qR a tip
153 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
153 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
154 [10]
154 [10]
155 $ hg -qRa tip
155 $ hg -qRa tip
156 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
156 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo
157 [10]
157 [10]
158
158
159 Testing --cwd:
159 Testing --cwd:
160
160
161 $ hg --cwd a parents
161 $ hg --cwd a parents
162 changeset: 0:8580ff50825a
162 changeset: 0:8580ff50825a
163 tag: tip
163 tag: tip
164 user: test
164 user: test
165 date: Thu Jan 01 00:00:01 1970 +0000
165 date: Thu Jan 01 00:00:01 1970 +0000
166 summary: a
166 summary: a
167
167
168
168
169 Testing -y/--noninteractive - just be sure it is parsed:
169 Testing -y/--noninteractive - just be sure it is parsed:
170
170
171 $ hg --cwd a tip -q --noninteractive
171 $ hg --cwd a tip -q --noninteractive
172 0:8580ff50825a
172 0:8580ff50825a
173 $ hg --cwd a tip -q -y
173 $ hg --cwd a tip -q -y
174 0:8580ff50825a
174 0:8580ff50825a
175
175
176 Testing -q/--quiet:
176 Testing -q/--quiet:
177
177
178 $ hg -R a -q tip
178 $ hg -R a -q tip
179 0:8580ff50825a
179 0:8580ff50825a
180 $ hg -R b -q tip
180 $ hg -R b -q tip
181 0:b6c483daf290
181 0:b6c483daf290
182 $ hg -R c --quiet parents
182 $ hg -R c --quiet parents
183 0:8580ff50825a
183 0:8580ff50825a
184 1:b6c483daf290
184 1:b6c483daf290
185
185
186 Testing -v/--verbose:
186 Testing -v/--verbose:
187
187
188 $ hg --cwd c head -v
188 $ hg --cwd c head -v
189 changeset: 1:b6c483daf290
189 changeset: 1:b6c483daf290
190 tag: tip
190 tag: tip
191 parent: -1:000000000000
191 parent: -1:000000000000
192 user: test
192 user: test
193 date: Thu Jan 01 00:00:01 1970 +0000
193 date: Thu Jan 01 00:00:01 1970 +0000
194 files: b
194 files: b
195 description:
195 description:
196 b
196 b
197
197
198
198
199 changeset: 0:8580ff50825a
199 changeset: 0:8580ff50825a
200 user: test
200 user: test
201 date: Thu Jan 01 00:00:01 1970 +0000
201 date: Thu Jan 01 00:00:01 1970 +0000
202 files: a
202 files: a
203 description:
203 description:
204 a
204 a
205
205
206
206
207 $ hg --cwd b tip --verbose
207 $ hg --cwd b tip --verbose
208 changeset: 0:b6c483daf290
208 changeset: 0:b6c483daf290
209 tag: tip
209 tag: tip
210 user: test
210 user: test
211 date: Thu Jan 01 00:00:01 1970 +0000
211 date: Thu Jan 01 00:00:01 1970 +0000
212 files: b
212 files: b
213 description:
213 description:
214 b
214 b
215
215
216
216
217
217
218 Testing --config:
218 Testing --config:
219
219
220 $ hg --cwd c --config paths.quuxfoo=bar paths | grep quuxfoo > /dev/null && echo quuxfoo
220 $ hg --cwd c --config paths.quuxfoo=bar paths | grep quuxfoo > /dev/null && echo quuxfoo
221 quuxfoo
221 quuxfoo
222 TODO: add rhg support for detailed exit codes
222 TODO: add rhg support for detailed exit codes
223 $ hg --cwd c --config '' tip -q
223 $ hg --cwd c --config '' tip -q
224 abort: malformed --config option: '' (use --config section.name=value)
224 abort: malformed --config option: '' (use --config section.name=value)
225 [10]
225 [10]
226 $ hg --cwd c --config a.b tip -q
226 $ hg --cwd c --config a.b tip -q
227 abort: malformed --config option: 'a.b' (use --config section.name=value)
227 abort: malformed --config option: 'a.b' (use --config section.name=value)
228 [10]
228 [10]
229 $ hg --cwd c --config a tip -q
229 $ hg --cwd c --config a tip -q
230 abort: malformed --config option: 'a' (use --config section.name=value)
230 abort: malformed --config option: 'a' (use --config section.name=value)
231 [10]
231 [10]
232 $ hg --cwd c --config a.= tip -q
232 $ hg --cwd c --config a.= tip -q
233 abort: malformed --config option: 'a.=' (use --config section.name=value)
233 abort: malformed --config option: 'a.=' (use --config section.name=value)
234 [10]
234 [10]
235 $ hg --cwd c --config .b= tip -q
235 $ hg --cwd c --config .b= tip -q
236 abort: malformed --config option: '.b=' (use --config section.name=value)
236 abort: malformed --config option: '.b=' (use --config section.name=value)
237 [10]
237 [10]
238
238
239 Testing --debug:
239 Testing --debug:
240
240
241 $ hg --cwd c log --debug
241 $ hg --cwd c log --debug
242 changeset: 1:b6c483daf2907ce5825c0bb50f5716226281cc1a
242 changeset: 1:b6c483daf2907ce5825c0bb50f5716226281cc1a
243 tag: tip
243 tag: tip
244 phase: public
244 phase: public
245 parent: -1:0000000000000000000000000000000000000000
245 parent: -1:0000000000000000000000000000000000000000
246 parent: -1:0000000000000000000000000000000000000000
246 parent: -1:0000000000000000000000000000000000000000
247 manifest: 1:23226e7a252cacdc2d99e4fbdc3653441056de49
247 manifest: 1:23226e7a252cacdc2d99e4fbdc3653441056de49
248 user: test
248 user: test
249 date: Thu Jan 01 00:00:01 1970 +0000
249 date: Thu Jan 01 00:00:01 1970 +0000
250 files+: b
250 files+: b
251 extra: branch=default
251 extra: branch=default
252 description:
252 description:
253 b
253 b
254
254
255
255
256 changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab
256 changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab
257 phase: public
257 phase: public
258 parent: -1:0000000000000000000000000000000000000000
258 parent: -1:0000000000000000000000000000000000000000
259 parent: -1:0000000000000000000000000000000000000000
259 parent: -1:0000000000000000000000000000000000000000
260 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
260 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
261 user: test
261 user: test
262 date: Thu Jan 01 00:00:01 1970 +0000
262 date: Thu Jan 01 00:00:01 1970 +0000
263 files+: a
263 files+: a
264 extra: branch=default
264 extra: branch=default
265 description:
265 description:
266 a
266 a
267
267
268
268
269
269
270 Testing --traceback:
270 Testing --traceback:
271
271
272 #if no-chg no-rhg
272 #if no-chg no-rhg
273 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
273 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
274 Traceback (most recent call last):
274 Traceback (most recent call last):
275 Traceback (most recent call last):
275 Traceback (most recent call last):
276 #else
276 #else
277 Traceback for '--config' errors not supported with chg.
277 Traceback for '--config' errors not supported with chg.
278 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
278 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
279 [1]
279 [1]
280 #endif
280 #endif
281
281
282 Testing --time:
282 Testing --time:
283
283
284 $ hg --cwd a --time id
284 $ hg --cwd a --time id
285 8580ff50825a tip
285 8580ff50825a tip
286 time: real * (glob)
286 time: real * (glob)
287
287
288 Testing --version:
288 Testing --version:
289
289
290 $ hg --version -q
290 $ hg --version -q
291 Mercurial Distributed SCM * (glob)
291 Mercurial Distributed SCM * (glob)
292
292
293 hide outer repo
293 hide outer repo
294 $ hg init
294 $ hg init
295
295
296 Testing -h/--help:
296 Testing -h/--help:
297
297
298 #if no-extraextensions
298 #if no-extraextensions
299
299
300 $ hg -h
300 $ hg -h
301 Mercurial Distributed SCM
301 Mercurial Distributed SCM
302
302
303 list of commands:
303 list of commands:
304
304
305 Repository creation:
305 Repository creation:
306
306
307 clone make a copy of an existing repository
307 clone make a copy of an existing repository
308 init create a new repository in the given directory
308 init create a new repository in the given directory
309
309
310 Remote repository management:
310 Remote repository management:
311
311
312 incoming show new changesets found in source
312 incoming show new changesets found in source
313 outgoing show changesets not found in the destination
313 outgoing show changesets not found in the destination
314 paths show aliases for remote repositories
314 paths show aliases for remote repositories
315 pull pull changes from the specified source
315 pull pull changes from the specified source
316 push push changes to the specified destination
316 push push changes to the specified destination
317 serve start stand-alone webserver
317 serve start stand-alone webserver
318
318
319 Change creation:
319 Change creation:
320
320
321 commit commit the specified files or all outstanding changes
321 commit commit the specified files or all outstanding changes
322
322
323 Change manipulation:
323 Change manipulation:
324
324
325 backout reverse effect of earlier changeset
325 backout reverse effect of earlier changeset
326 graft copy changes from other branches onto the current branch
326 graft copy changes from other branches onto the current branch
327 merge merge another revision into working directory
327 merge merge another revision into working directory
328
328
329 Change organization:
329 Change organization:
330
330
331 bookmarks create a new bookmark or list existing bookmarks
331 bookmarks create a new bookmark or list existing bookmarks
332 branch set or show the current branch name
332 branch set or show the current branch name
333 branches list repository named branches
333 branches list repository named branches
334 phase set or show the current phase name
334 phase set or show the current phase name
335 tag add one or more tags for the current or given revision
335 tag add one or more tags for the current or given revision
336 tags list repository tags
336 tags list repository tags
337
337
338 File content management:
338 File content management:
339
339
340 annotate show changeset information by line for each file
340 annotate show changeset information by line for each file
341 cat output the current or given revision of files
341 cat output the current or given revision of files
342 copy mark files as copied for the next commit
342 copy mark files as copied for the next commit
343 diff diff repository (or selected files)
343 diff diff repository (or selected files)
344 grep search for a pattern in specified files
344 grep search for a pattern in specified files
345
345
346 Change navigation:
346 Change navigation:
347
347
348 bisect subdivision search of changesets
348 bisect subdivision search of changesets
349 heads show branch heads
349 heads show branch heads
350 identify identify the working directory or specified revision
350 identify identify the working directory or specified revision
351 log show revision history of entire repository or files
351 log show revision history of entire repository or files
352
352
353 Working directory management:
353 Working directory management:
354
354
355 add add the specified files on the next commit
355 add add the specified files on the next commit
356 addremove add all new files, delete all missing files
356 addremove add all new files, delete all missing files
357 files list tracked files
357 files list tracked files
358 forget forget the specified files on the next commit
358 forget forget the specified files on the next commit
359 purge removes files not tracked by Mercurial
359 purge removes files not tracked by Mercurial
360 remove remove the specified files on the next commit
360 remove remove the specified files on the next commit
361 rename rename files; equivalent of copy + remove
361 rename rename files; equivalent of copy + remove
362 resolve redo merges or set/view the merge status of files
362 resolve redo merges or set/view the merge status of files
363 revert restore files to their checkout state
363 revert restore files to their checkout state
364 root print the root (top) of the current working directory
364 root print the root (top) of the current working directory
365 shelve save and set aside changes from the working directory
365 shelve save and set aside changes from the working directory
366 status show changed files in the working directory
366 status show changed files in the working directory
367 summary summarize working directory state
367 summary summarize working directory state
368 unshelve restore a shelved change to the working directory
368 unshelve restore a shelved change to the working directory
369 update update working directory (or switch revisions)
369 update update working directory (or switch revisions)
370
370
371 Change import/export:
371 Change import/export:
372
372
373 archive create an unversioned archive of a repository revision
373 archive create an unversioned archive of a repository revision
374 bundle create a bundle file
374 bundle create a bundle file
375 export dump the header and diffs for one or more changesets
375 export dump the header and diffs for one or more changesets
376 import import an ordered set of patches
376 import import an ordered set of patches
377 unbundle apply one or more bundle files
377 unbundle apply one or more bundle files
378
378
379 Repository maintenance:
379 Repository maintenance:
380
380
381 admin::verify
382 verify the integrity of the repository
381 manifest output the current or given revision of the project manifest
383 manifest output the current or given revision of the project manifest
382 recover roll back an interrupted transaction
384 recover roll back an interrupted transaction
383 verify verify the integrity of the repository
385 verify verify the integrity of the repository
384
386
385 Help:
387 Help:
386
388
387 config show combined config settings from all hgrc files
389 config show combined config settings from all hgrc files
388 help show help for a given topic or a help overview
390 help show help for a given topic or a help overview
389 version output version and copyright information
391 version output version and copyright information
390
392
391 additional help topics:
393 additional help topics:
392
394
393 Mercurial identifiers:
395 Mercurial identifiers:
394
396
395 filesets Specifying File Sets
397 filesets Specifying File Sets
396 hgignore Syntax for Mercurial Ignore Files
398 hgignore Syntax for Mercurial Ignore Files
397 patterns File Name Patterns
399 patterns File Name Patterns
398 revisions Specifying Revisions
400 revisions Specifying Revisions
399 urls URL Paths
401 urls URL Paths
400
402
401 Mercurial output:
403 Mercurial output:
402
404
403 color Colorizing Outputs
405 color Colorizing Outputs
404 dates Date Formats
406 dates Date Formats
405 diffs Diff Formats
407 diffs Diff Formats
406 templating Template Usage
408 templating Template Usage
407
409
408 Mercurial configuration:
410 Mercurial configuration:
409
411
410 config Configuration Files
412 config Configuration Files
411 environment Environment Variables
413 environment Environment Variables
412 extensions Using Additional Features
414 extensions Using Additional Features
413 flags Command-line flags
415 flags Command-line flags
414 hgweb Configuring hgweb
416 hgweb Configuring hgweb
415 merge-tools Merge Tools
417 merge-tools Merge Tools
416 pager Pager Support
418 pager Pager Support
417 rust Rust in Mercurial
419 rust Rust in Mercurial
418
420
419 Concepts:
421 Concepts:
420
422
421 bundlespec Bundle File Formats
423 bundlespec Bundle File Formats
422 evolution Safely rewriting history (EXPERIMENTAL)
424 evolution Safely rewriting history (EXPERIMENTAL)
423 glossary Glossary
425 glossary Glossary
424 phases Working with Phases
426 phases Working with Phases
425 subrepos Subrepositories
427 subrepos Subrepositories
426
428
427 Miscellaneous:
429 Miscellaneous:
428
430
429 deprecated Deprecated Features
431 deprecated Deprecated Features
430 internals Technical implementation topics
432 internals Technical implementation topics
431 scripting Using Mercurial from scripts and automation
433 scripting Using Mercurial from scripts and automation
432
434
433 (use 'hg help -v' to show built-in aliases and global options)
435 (use 'hg help -v' to show built-in aliases and global options)
434
436
435 $ hg --help
437 $ hg --help
436 Mercurial Distributed SCM
438 Mercurial Distributed SCM
437
439
438 list of commands:
440 list of commands:
439
441
440 Repository creation:
442 Repository creation:
441
443
442 clone make a copy of an existing repository
444 clone make a copy of an existing repository
443 init create a new repository in the given directory
445 init create a new repository in the given directory
444
446
445 Remote repository management:
447 Remote repository management:
446
448
447 incoming show new changesets found in source
449 incoming show new changesets found in source
448 outgoing show changesets not found in the destination
450 outgoing show changesets not found in the destination
449 paths show aliases for remote repositories
451 paths show aliases for remote repositories
450 pull pull changes from the specified source
452 pull pull changes from the specified source
451 push push changes to the specified destination
453 push push changes to the specified destination
452 serve start stand-alone webserver
454 serve start stand-alone webserver
453
455
454 Change creation:
456 Change creation:
455
457
456 commit commit the specified files or all outstanding changes
458 commit commit the specified files or all outstanding changes
457
459
458 Change manipulation:
460 Change manipulation:
459
461
460 backout reverse effect of earlier changeset
462 backout reverse effect of earlier changeset
461 graft copy changes from other branches onto the current branch
463 graft copy changes from other branches onto the current branch
462 merge merge another revision into working directory
464 merge merge another revision into working directory
463
465
464 Change organization:
466 Change organization:
465
467
466 bookmarks create a new bookmark or list existing bookmarks
468 bookmarks create a new bookmark or list existing bookmarks
467 branch set or show the current branch name
469 branch set or show the current branch name
468 branches list repository named branches
470 branches list repository named branches
469 phase set or show the current phase name
471 phase set or show the current phase name
470 tag add one or more tags for the current or given revision
472 tag add one or more tags for the current or given revision
471 tags list repository tags
473 tags list repository tags
472
474
473 File content management:
475 File content management:
474
476
475 annotate show changeset information by line for each file
477 annotate show changeset information by line for each file
476 cat output the current or given revision of files
478 cat output the current or given revision of files
477 copy mark files as copied for the next commit
479 copy mark files as copied for the next commit
478 diff diff repository (or selected files)
480 diff diff repository (or selected files)
479 grep search for a pattern in specified files
481 grep search for a pattern in specified files
480
482
481 Change navigation:
483 Change navigation:
482
484
483 bisect subdivision search of changesets
485 bisect subdivision search of changesets
484 heads show branch heads
486 heads show branch heads
485 identify identify the working directory or specified revision
487 identify identify the working directory or specified revision
486 log show revision history of entire repository or files
488 log show revision history of entire repository or files
487
489
488 Working directory management:
490 Working directory management:
489
491
490 add add the specified files on the next commit
492 add add the specified files on the next commit
491 addremove add all new files, delete all missing files
493 addremove add all new files, delete all missing files
492 files list tracked files
494 files list tracked files
493 forget forget the specified files on the next commit
495 forget forget the specified files on the next commit
494 purge removes files not tracked by Mercurial
496 purge removes files not tracked by Mercurial
495 remove remove the specified files on the next commit
497 remove remove the specified files on the next commit
496 rename rename files; equivalent of copy + remove
498 rename rename files; equivalent of copy + remove
497 resolve redo merges or set/view the merge status of files
499 resolve redo merges or set/view the merge status of files
498 revert restore files to their checkout state
500 revert restore files to their checkout state
499 root print the root (top) of the current working directory
501 root print the root (top) of the current working directory
500 shelve save and set aside changes from the working directory
502 shelve save and set aside changes from the working directory
501 status show changed files in the working directory
503 status show changed files in the working directory
502 summary summarize working directory state
504 summary summarize working directory state
503 unshelve restore a shelved change to the working directory
505 unshelve restore a shelved change to the working directory
504 update update working directory (or switch revisions)
506 update update working directory (or switch revisions)
505
507
506 Change import/export:
508 Change import/export:
507
509
508 archive create an unversioned archive of a repository revision
510 archive create an unversioned archive of a repository revision
509 bundle create a bundle file
511 bundle create a bundle file
510 export dump the header and diffs for one or more changesets
512 export dump the header and diffs for one or more changesets
511 import import an ordered set of patches
513 import import an ordered set of patches
512 unbundle apply one or more bundle files
514 unbundle apply one or more bundle files
513
515
514 Repository maintenance:
516 Repository maintenance:
515
517
518 admin::verify
519 verify the integrity of the repository
516 manifest output the current or given revision of the project manifest
520 manifest output the current or given revision of the project manifest
517 recover roll back an interrupted transaction
521 recover roll back an interrupted transaction
518 verify verify the integrity of the repository
522 verify verify the integrity of the repository
519
523
520 Help:
524 Help:
521
525
522 config show combined config settings from all hgrc files
526 config show combined config settings from all hgrc files
523 help show help for a given topic or a help overview
527 help show help for a given topic or a help overview
524 version output version and copyright information
528 version output version and copyright information
525
529
526 additional help topics:
530 additional help topics:
527
531
528 Mercurial identifiers:
532 Mercurial identifiers:
529
533
530 filesets Specifying File Sets
534 filesets Specifying File Sets
531 hgignore Syntax for Mercurial Ignore Files
535 hgignore Syntax for Mercurial Ignore Files
532 patterns File Name Patterns
536 patterns File Name Patterns
533 revisions Specifying Revisions
537 revisions Specifying Revisions
534 urls URL Paths
538 urls URL Paths
535
539
536 Mercurial output:
540 Mercurial output:
537
541
538 color Colorizing Outputs
542 color Colorizing Outputs
539 dates Date Formats
543 dates Date Formats
540 diffs Diff Formats
544 diffs Diff Formats
541 templating Template Usage
545 templating Template Usage
542
546
543 Mercurial configuration:
547 Mercurial configuration:
544
548
545 config Configuration Files
549 config Configuration Files
546 environment Environment Variables
550 environment Environment Variables
547 extensions Using Additional Features
551 extensions Using Additional Features
548 flags Command-line flags
552 flags Command-line flags
549 hgweb Configuring hgweb
553 hgweb Configuring hgweb
550 merge-tools Merge Tools
554 merge-tools Merge Tools
551 pager Pager Support
555 pager Pager Support
552 rust Rust in Mercurial
556 rust Rust in Mercurial
553
557
554 Concepts:
558 Concepts:
555
559
556 bundlespec Bundle File Formats
560 bundlespec Bundle File Formats
557 evolution Safely rewriting history (EXPERIMENTAL)
561 evolution Safely rewriting history (EXPERIMENTAL)
558 glossary Glossary
562 glossary Glossary
559 phases Working with Phases
563 phases Working with Phases
560 subrepos Subrepositories
564 subrepos Subrepositories
561
565
562 Miscellaneous:
566 Miscellaneous:
563
567
564 deprecated Deprecated Features
568 deprecated Deprecated Features
565 internals Technical implementation topics
569 internals Technical implementation topics
566 scripting Using Mercurial from scripts and automation
570 scripting Using Mercurial from scripts and automation
567
571
568 (use 'hg help -v' to show built-in aliases and global options)
572 (use 'hg help -v' to show built-in aliases and global options)
569
573
570 #endif
574 #endif
571
575
572 Not tested: --debugger
576 Not tested: --debugger
573
577
@@ -1,265 +1,269 b''
1 Test hiding some commands (which also happens to hide an entire category).
1 Test hiding some commands (which also happens to hide an entire category).
2
2
3 $ hg --config help.hidden-command.clone=true \
3 $ hg --config help.hidden-command.clone=true \
4 > --config help.hidden-command.init=true help
4 > --config help.hidden-command.init=true help
5 Mercurial Distributed SCM
5 Mercurial Distributed SCM
6
6
7 list of commands:
7 list of commands:
8
8
9 Remote repository management:
9 Remote repository management:
10
10
11 incoming show new changesets found in source
11 incoming show new changesets found in source
12 outgoing show changesets not found in the destination
12 outgoing show changesets not found in the destination
13 paths show aliases for remote repositories
13 paths show aliases for remote repositories
14 pull pull changes from the specified source
14 pull pull changes from the specified source
15 push push changes to the specified destination
15 push push changes to the specified destination
16 serve start stand-alone webserver
16 serve start stand-alone webserver
17
17
18 Change creation:
18 Change creation:
19
19
20 commit commit the specified files or all outstanding changes
20 commit commit the specified files or all outstanding changes
21
21
22 Change manipulation:
22 Change manipulation:
23
23
24 backout reverse effect of earlier changeset
24 backout reverse effect of earlier changeset
25 graft copy changes from other branches onto the current branch
25 graft copy changes from other branches onto the current branch
26 merge merge another revision into working directory
26 merge merge another revision into working directory
27
27
28 Change organization:
28 Change organization:
29
29
30 bookmarks create a new bookmark or list existing bookmarks
30 bookmarks create a new bookmark or list existing bookmarks
31 branch set or show the current branch name
31 branch set or show the current branch name
32 branches list repository named branches
32 branches list repository named branches
33 phase set or show the current phase name
33 phase set or show the current phase name
34 tag add one or more tags for the current or given revision
34 tag add one or more tags for the current or given revision
35 tags list repository tags
35 tags list repository tags
36
36
37 File content management:
37 File content management:
38
38
39 annotate show changeset information by line for each file
39 annotate show changeset information by line for each file
40 cat output the current or given revision of files
40 cat output the current or given revision of files
41 copy mark files as copied for the next commit
41 copy mark files as copied for the next commit
42 diff diff repository (or selected files)
42 diff diff repository (or selected files)
43 grep search for a pattern in specified files
43 grep search for a pattern in specified files
44
44
45 Change navigation:
45 Change navigation:
46
46
47 bisect subdivision search of changesets
47 bisect subdivision search of changesets
48 heads show branch heads
48 heads show branch heads
49 identify identify the working directory or specified revision
49 identify identify the working directory or specified revision
50 log show revision history of entire repository or files
50 log show revision history of entire repository or files
51
51
52 Working directory management:
52 Working directory management:
53
53
54 add add the specified files on the next commit
54 add add the specified files on the next commit
55 addremove add all new files, delete all missing files
55 addremove add all new files, delete all missing files
56 files list tracked files
56 files list tracked files
57 forget forget the specified files on the next commit
57 forget forget the specified files on the next commit
58 purge removes files not tracked by Mercurial
58 purge removes files not tracked by Mercurial
59 remove remove the specified files on the next commit
59 remove remove the specified files on the next commit
60 rename rename files; equivalent of copy + remove
60 rename rename files; equivalent of copy + remove
61 resolve redo merges or set/view the merge status of files
61 resolve redo merges or set/view the merge status of files
62 revert restore files to their checkout state
62 revert restore files to their checkout state
63 root print the root (top) of the current working directory
63 root print the root (top) of the current working directory
64 shelve save and set aside changes from the working directory
64 shelve save and set aside changes from the working directory
65 status show changed files in the working directory
65 status show changed files in the working directory
66 summary summarize working directory state
66 summary summarize working directory state
67 unshelve restore a shelved change to the working directory
67 unshelve restore a shelved change to the working directory
68 update update working directory (or switch revisions)
68 update update working directory (or switch revisions)
69
69
70 Change import/export:
70 Change import/export:
71
71
72 archive create an unversioned archive of a repository revision
72 archive create an unversioned archive of a repository revision
73 bundle create a bundle file
73 bundle create a bundle file
74 export dump the header and diffs for one or more changesets
74 export dump the header and diffs for one or more changesets
75 import import an ordered set of patches
75 import import an ordered set of patches
76 unbundle apply one or more bundle files
76 unbundle apply one or more bundle files
77
77
78 Repository maintenance:
78 Repository maintenance:
79
79
80 admin::verify
81 verify the integrity of the repository
80 manifest output the current or given revision of the project manifest
82 manifest output the current or given revision of the project manifest
81 recover roll back an interrupted transaction
83 recover roll back an interrupted transaction
82 verify verify the integrity of the repository
84 verify verify the integrity of the repository
83
85
84 Help:
86 Help:
85
87
86 config show combined config settings from all hgrc files
88 config show combined config settings from all hgrc files
87 help show help for a given topic or a help overview
89 help show help for a given topic or a help overview
88 version output version and copyright information
90 version output version and copyright information
89
91
90 additional help topics:
92 additional help topics:
91
93
92 Mercurial identifiers:
94 Mercurial identifiers:
93
95
94 filesets Specifying File Sets
96 filesets Specifying File Sets
95 hgignore Syntax for Mercurial Ignore Files
97 hgignore Syntax for Mercurial Ignore Files
96 patterns File Name Patterns
98 patterns File Name Patterns
97 revisions Specifying Revisions
99 revisions Specifying Revisions
98 urls URL Paths
100 urls URL Paths
99
101
100 Mercurial output:
102 Mercurial output:
101
103
102 color Colorizing Outputs
104 color Colorizing Outputs
103 dates Date Formats
105 dates Date Formats
104 diffs Diff Formats
106 diffs Diff Formats
105 templating Template Usage
107 templating Template Usage
106
108
107 Mercurial configuration:
109 Mercurial configuration:
108
110
109 config Configuration Files
111 config Configuration Files
110 environment Environment Variables
112 environment Environment Variables
111 extensions Using Additional Features
113 extensions Using Additional Features
112 flags Command-line flags
114 flags Command-line flags
113 hgweb Configuring hgweb
115 hgweb Configuring hgweb
114 merge-tools Merge Tools
116 merge-tools Merge Tools
115 pager Pager Support
117 pager Pager Support
116 rust Rust in Mercurial
118 rust Rust in Mercurial
117
119
118 Concepts:
120 Concepts:
119
121
120 bundlespec Bundle File Formats
122 bundlespec Bundle File Formats
121 evolution Safely rewriting history (EXPERIMENTAL)
123 evolution Safely rewriting history (EXPERIMENTAL)
122 glossary Glossary
124 glossary Glossary
123 phases Working with Phases
125 phases Working with Phases
124 subrepos Subrepositories
126 subrepos Subrepositories
125
127
126 Miscellaneous:
128 Miscellaneous:
127
129
128 deprecated Deprecated Features
130 deprecated Deprecated Features
129 internals Technical implementation topics
131 internals Technical implementation topics
130 scripting Using Mercurial from scripts and automation
132 scripting Using Mercurial from scripts and automation
131
133
132 (use 'hg help -v' to show built-in aliases and global options)
134 (use 'hg help -v' to show built-in aliases and global options)
133
135
134 Test hiding some topics.
136 Test hiding some topics.
135
137
136 $ hg --config help.hidden-topic.deprecated=true \
138 $ hg --config help.hidden-topic.deprecated=true \
137 > --config help.hidden-topic.internals=true \
139 > --config help.hidden-topic.internals=true \
138 > --config help.hidden-topic.scripting=true help
140 > --config help.hidden-topic.scripting=true help
139 Mercurial Distributed SCM
141 Mercurial Distributed SCM
140
142
141 list of commands:
143 list of commands:
142
144
143 Repository creation:
145 Repository creation:
144
146
145 clone make a copy of an existing repository
147 clone make a copy of an existing repository
146 init create a new repository in the given directory
148 init create a new repository in the given directory
147
149
148 Remote repository management:
150 Remote repository management:
149
151
150 incoming show new changesets found in source
152 incoming show new changesets found in source
151 outgoing show changesets not found in the destination
153 outgoing show changesets not found in the destination
152 paths show aliases for remote repositories
154 paths show aliases for remote repositories
153 pull pull changes from the specified source
155 pull pull changes from the specified source
154 push push changes to the specified destination
156 push push changes to the specified destination
155 serve start stand-alone webserver
157 serve start stand-alone webserver
156
158
157 Change creation:
159 Change creation:
158
160
159 commit commit the specified files or all outstanding changes
161 commit commit the specified files or all outstanding changes
160
162
161 Change manipulation:
163 Change manipulation:
162
164
163 backout reverse effect of earlier changeset
165 backout reverse effect of earlier changeset
164 graft copy changes from other branches onto the current branch
166 graft copy changes from other branches onto the current branch
165 merge merge another revision into working directory
167 merge merge another revision into working directory
166
168
167 Change organization:
169 Change organization:
168
170
169 bookmarks create a new bookmark or list existing bookmarks
171 bookmarks create a new bookmark or list existing bookmarks
170 branch set or show the current branch name
172 branch set or show the current branch name
171 branches list repository named branches
173 branches list repository named branches
172 phase set or show the current phase name
174 phase set or show the current phase name
173 tag add one or more tags for the current or given revision
175 tag add one or more tags for the current or given revision
174 tags list repository tags
176 tags list repository tags
175
177
176 File content management:
178 File content management:
177
179
178 annotate show changeset information by line for each file
180 annotate show changeset information by line for each file
179 cat output the current or given revision of files
181 cat output the current or given revision of files
180 copy mark files as copied for the next commit
182 copy mark files as copied for the next commit
181 diff diff repository (or selected files)
183 diff diff repository (or selected files)
182 grep search for a pattern in specified files
184 grep search for a pattern in specified files
183
185
184 Change navigation:
186 Change navigation:
185
187
186 bisect subdivision search of changesets
188 bisect subdivision search of changesets
187 heads show branch heads
189 heads show branch heads
188 identify identify the working directory or specified revision
190 identify identify the working directory or specified revision
189 log show revision history of entire repository or files
191 log show revision history of entire repository or files
190
192
191 Working directory management:
193 Working directory management:
192
194
193 add add the specified files on the next commit
195 add add the specified files on the next commit
194 addremove add all new files, delete all missing files
196 addremove add all new files, delete all missing files
195 files list tracked files
197 files list tracked files
196 forget forget the specified files on the next commit
198 forget forget the specified files on the next commit
197 purge removes files not tracked by Mercurial
199 purge removes files not tracked by Mercurial
198 remove remove the specified files on the next commit
200 remove remove the specified files on the next commit
199 rename rename files; equivalent of copy + remove
201 rename rename files; equivalent of copy + remove
200 resolve redo merges or set/view the merge status of files
202 resolve redo merges or set/view the merge status of files
201 revert restore files to their checkout state
203 revert restore files to their checkout state
202 root print the root (top) of the current working directory
204 root print the root (top) of the current working directory
203 shelve save and set aside changes from the working directory
205 shelve save and set aside changes from the working directory
204 status show changed files in the working directory
206 status show changed files in the working directory
205 summary summarize working directory state
207 summary summarize working directory state
206 unshelve restore a shelved change to the working directory
208 unshelve restore a shelved change to the working directory
207 update update working directory (or switch revisions)
209 update update working directory (or switch revisions)
208
210
209 Change import/export:
211 Change import/export:
210
212
211 archive create an unversioned archive of a repository revision
213 archive create an unversioned archive of a repository revision
212 bundle create a bundle file
214 bundle create a bundle file
213 export dump the header and diffs for one or more changesets
215 export dump the header and diffs for one or more changesets
214 import import an ordered set of patches
216 import import an ordered set of patches
215 unbundle apply one or more bundle files
217 unbundle apply one or more bundle files
216
218
217 Repository maintenance:
219 Repository maintenance:
218
220
221 admin::verify
222 verify the integrity of the repository
219 manifest output the current or given revision of the project manifest
223 manifest output the current or given revision of the project manifest
220 recover roll back an interrupted transaction
224 recover roll back an interrupted transaction
221 verify verify the integrity of the repository
225 verify verify the integrity of the repository
222
226
223 Help:
227 Help:
224
228
225 config show combined config settings from all hgrc files
229 config show combined config settings from all hgrc files
226 help show help for a given topic or a help overview
230 help show help for a given topic or a help overview
227 version output version and copyright information
231 version output version and copyright information
228
232
229 additional help topics:
233 additional help topics:
230
234
231 Mercurial identifiers:
235 Mercurial identifiers:
232
236
233 filesets Specifying File Sets
237 filesets Specifying File Sets
234 hgignore Syntax for Mercurial Ignore Files
238 hgignore Syntax for Mercurial Ignore Files
235 patterns File Name Patterns
239 patterns File Name Patterns
236 revisions Specifying Revisions
240 revisions Specifying Revisions
237 urls URL Paths
241 urls URL Paths
238
242
239 Mercurial output:
243 Mercurial output:
240
244
241 color Colorizing Outputs
245 color Colorizing Outputs
242 dates Date Formats
246 dates Date Formats
243 diffs Diff Formats
247 diffs Diff Formats
244 templating Template Usage
248 templating Template Usage
245
249
246 Mercurial configuration:
250 Mercurial configuration:
247
251
248 config Configuration Files
252 config Configuration Files
249 environment Environment Variables
253 environment Environment Variables
250 extensions Using Additional Features
254 extensions Using Additional Features
251 flags Command-line flags
255 flags Command-line flags
252 hgweb Configuring hgweb
256 hgweb Configuring hgweb
253 merge-tools Merge Tools
257 merge-tools Merge Tools
254 pager Pager Support
258 pager Pager Support
255 rust Rust in Mercurial
259 rust Rust in Mercurial
256
260
257 Concepts:
261 Concepts:
258
262
259 bundlespec Bundle File Formats
263 bundlespec Bundle File Formats
260 evolution Safely rewriting history (EXPERIMENTAL)
264 evolution Safely rewriting history (EXPERIMENTAL)
261 glossary Glossary
265 glossary Glossary
262 phases Working with Phases
266 phases Working with Phases
263 subrepos Subrepositories
267 subrepos Subrepositories
264
268
265 (use 'hg help -v' to show built-in aliases and global options)
269 (use 'hg help -v' to show built-in aliases and global options)
@@ -1,4085 +1,4106 b''
1 Short help:
1 Short help:
2
2
3 $ hg
3 $ hg
4 Mercurial Distributed SCM
4 Mercurial Distributed SCM
5
5
6 basic commands:
6 basic commands:
7
7
8 add add the specified files on the next commit
8 add add the specified files on the next commit
9 annotate show changeset information by line for each file
9 annotate show changeset information by line for each file
10 clone make a copy of an existing repository
10 clone make a copy of an existing repository
11 commit commit the specified files or all outstanding changes
11 commit commit the specified files or all outstanding changes
12 diff diff repository (or selected files)
12 diff diff repository (or selected files)
13 export dump the header and diffs for one or more changesets
13 export dump the header and diffs for one or more changesets
14 forget forget the specified files on the next commit
14 forget forget the specified files on the next commit
15 init create a new repository in the given directory
15 init create a new repository in the given directory
16 log show revision history of entire repository or files
16 log show revision history of entire repository or files
17 merge merge another revision into working directory
17 merge merge another revision into working directory
18 pull pull changes from the specified source
18 pull pull changes from the specified source
19 push push changes to the specified destination
19 push push changes to the specified destination
20 remove remove the specified files on the next commit
20 remove remove the specified files on the next commit
21 serve start stand-alone webserver
21 serve start stand-alone webserver
22 status show changed files in the working directory
22 status show changed files in the working directory
23 summary summarize working directory state
23 summary summarize working directory state
24 update update working directory (or switch revisions)
24 update update working directory (or switch revisions)
25
25
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
27
27
28 $ hg -q
28 $ hg -q
29 add add the specified files on the next commit
29 add add the specified files on the next commit
30 annotate show changeset information by line for each file
30 annotate show changeset information by line for each file
31 clone make a copy of an existing repository
31 clone make a copy of an existing repository
32 commit commit the specified files or all outstanding changes
32 commit commit the specified files or all outstanding changes
33 diff diff repository (or selected files)
33 diff diff repository (or selected files)
34 export dump the header and diffs for one or more changesets
34 export dump the header and diffs for one or more changesets
35 forget forget the specified files on the next commit
35 forget forget the specified files on the next commit
36 init create a new repository in the given directory
36 init create a new repository in the given directory
37 log show revision history of entire repository or files
37 log show revision history of entire repository or files
38 merge merge another revision into working directory
38 merge merge another revision into working directory
39 pull pull changes from the specified source
39 pull pull changes from the specified source
40 push push changes to the specified destination
40 push push changes to the specified destination
41 remove remove the specified files on the next commit
41 remove remove the specified files on the next commit
42 serve start stand-alone webserver
42 serve start stand-alone webserver
43 status show changed files in the working directory
43 status show changed files in the working directory
44 summary summarize working directory state
44 summary summarize working directory state
45 update update working directory (or switch revisions)
45 update update working directory (or switch revisions)
46
46
47 Extra extensions will be printed in help output in a non-reliable order since
47 Extra extensions will be printed in help output in a non-reliable order since
48 the extension is unknown.
48 the extension is unknown.
49 #if no-extraextensions
49 #if no-extraextensions
50
50
51 $ hg help
51 $ hg help
52 Mercurial Distributed SCM
52 Mercurial Distributed SCM
53
53
54 list of commands:
54 list of commands:
55
55
56 Repository creation:
56 Repository creation:
57
57
58 clone make a copy of an existing repository
58 clone make a copy of an existing repository
59 init create a new repository in the given directory
59 init create a new repository in the given directory
60
60
61 Remote repository management:
61 Remote repository management:
62
62
63 incoming show new changesets found in source
63 incoming show new changesets found in source
64 outgoing show changesets not found in the destination
64 outgoing show changesets not found in the destination
65 paths show aliases for remote repositories
65 paths show aliases for remote repositories
66 pull pull changes from the specified source
66 pull pull changes from the specified source
67 push push changes to the specified destination
67 push push changes to the specified destination
68 serve start stand-alone webserver
68 serve start stand-alone webserver
69
69
70 Change creation:
70 Change creation:
71
71
72 commit commit the specified files or all outstanding changes
72 commit commit the specified files or all outstanding changes
73
73
74 Change manipulation:
74 Change manipulation:
75
75
76 backout reverse effect of earlier changeset
76 backout reverse effect of earlier changeset
77 graft copy changes from other branches onto the current branch
77 graft copy changes from other branches onto the current branch
78 merge merge another revision into working directory
78 merge merge another revision into working directory
79
79
80 Change organization:
80 Change organization:
81
81
82 bookmarks create a new bookmark or list existing bookmarks
82 bookmarks create a new bookmark or list existing bookmarks
83 branch set or show the current branch name
83 branch set or show the current branch name
84 branches list repository named branches
84 branches list repository named branches
85 phase set or show the current phase name
85 phase set or show the current phase name
86 tag add one or more tags for the current or given revision
86 tag add one or more tags for the current or given revision
87 tags list repository tags
87 tags list repository tags
88
88
89 File content management:
89 File content management:
90
90
91 annotate show changeset information by line for each file
91 annotate show changeset information by line for each file
92 cat output the current or given revision of files
92 cat output the current or given revision of files
93 copy mark files as copied for the next commit
93 copy mark files as copied for the next commit
94 diff diff repository (or selected files)
94 diff diff repository (or selected files)
95 grep search for a pattern in specified files
95 grep search for a pattern in specified files
96
96
97 Change navigation:
97 Change navigation:
98
98
99 bisect subdivision search of changesets
99 bisect subdivision search of changesets
100 heads show branch heads
100 heads show branch heads
101 identify identify the working directory or specified revision
101 identify identify the working directory or specified revision
102 log show revision history of entire repository or files
102 log show revision history of entire repository or files
103
103
104 Working directory management:
104 Working directory management:
105
105
106 add add the specified files on the next commit
106 add add the specified files on the next commit
107 addremove add all new files, delete all missing files
107 addremove add all new files, delete all missing files
108 files list tracked files
108 files list tracked files
109 forget forget the specified files on the next commit
109 forget forget the specified files on the next commit
110 purge removes files not tracked by Mercurial
110 purge removes files not tracked by Mercurial
111 remove remove the specified files on the next commit
111 remove remove the specified files on the next commit
112 rename rename files; equivalent of copy + remove
112 rename rename files; equivalent of copy + remove
113 resolve redo merges or set/view the merge status of files
113 resolve redo merges or set/view the merge status of files
114 revert restore files to their checkout state
114 revert restore files to their checkout state
115 root print the root (top) of the current working directory
115 root print the root (top) of the current working directory
116 shelve save and set aside changes from the working directory
116 shelve save and set aside changes from the working directory
117 status show changed files in the working directory
117 status show changed files in the working directory
118 summary summarize working directory state
118 summary summarize working directory state
119 unshelve restore a shelved change to the working directory
119 unshelve restore a shelved change to the working directory
120 update update working directory (or switch revisions)
120 update update working directory (or switch revisions)
121
121
122 Change import/export:
122 Change import/export:
123
123
124 archive create an unversioned archive of a repository revision
124 archive create an unversioned archive of a repository revision
125 bundle create a bundle file
125 bundle create a bundle file
126 export dump the header and diffs for one or more changesets
126 export dump the header and diffs for one or more changesets
127 import import an ordered set of patches
127 import import an ordered set of patches
128 unbundle apply one or more bundle files
128 unbundle apply one or more bundle files
129
129
130 Repository maintenance:
130 Repository maintenance:
131
131
132 admin::verify
133 verify the integrity of the repository
132 manifest output the current or given revision of the project manifest
134 manifest output the current or given revision of the project manifest
133 recover roll back an interrupted transaction
135 recover roll back an interrupted transaction
134 verify verify the integrity of the repository
136 verify verify the integrity of the repository
135
137
136 Help:
138 Help:
137
139
138 config show combined config settings from all hgrc files
140 config show combined config settings from all hgrc files
139 help show help for a given topic or a help overview
141 help show help for a given topic or a help overview
140 version output version and copyright information
142 version output version and copyright information
141
143
142 additional help topics:
144 additional help topics:
143
145
144 Mercurial identifiers:
146 Mercurial identifiers:
145
147
146 filesets Specifying File Sets
148 filesets Specifying File Sets
147 hgignore Syntax for Mercurial Ignore Files
149 hgignore Syntax for Mercurial Ignore Files
148 patterns File Name Patterns
150 patterns File Name Patterns
149 revisions Specifying Revisions
151 revisions Specifying Revisions
150 urls URL Paths
152 urls URL Paths
151
153
152 Mercurial output:
154 Mercurial output:
153
155
154 color Colorizing Outputs
156 color Colorizing Outputs
155 dates Date Formats
157 dates Date Formats
156 diffs Diff Formats
158 diffs Diff Formats
157 templating Template Usage
159 templating Template Usage
158
160
159 Mercurial configuration:
161 Mercurial configuration:
160
162
161 config Configuration Files
163 config Configuration Files
162 environment Environment Variables
164 environment Environment Variables
163 extensions Using Additional Features
165 extensions Using Additional Features
164 flags Command-line flags
166 flags Command-line flags
165 hgweb Configuring hgweb
167 hgweb Configuring hgweb
166 merge-tools Merge Tools
168 merge-tools Merge Tools
167 pager Pager Support
169 pager Pager Support
168 rust Rust in Mercurial
170 rust Rust in Mercurial
169
171
170 Concepts:
172 Concepts:
171
173
172 bundlespec Bundle File Formats
174 bundlespec Bundle File Formats
173 evolution Safely rewriting history (EXPERIMENTAL)
175 evolution Safely rewriting history (EXPERIMENTAL)
174 glossary Glossary
176 glossary Glossary
175 phases Working with Phases
177 phases Working with Phases
176 subrepos Subrepositories
178 subrepos Subrepositories
177
179
178 Miscellaneous:
180 Miscellaneous:
179
181
180 deprecated Deprecated Features
182 deprecated Deprecated Features
181 internals Technical implementation topics
183 internals Technical implementation topics
182 scripting Using Mercurial from scripts and automation
184 scripting Using Mercurial from scripts and automation
183
185
184 (use 'hg help -v' to show built-in aliases and global options)
186 (use 'hg help -v' to show built-in aliases and global options)
185
187
186 $ hg -q help
188 $ hg -q help
187 Repository creation:
189 Repository creation:
188
190
189 clone make a copy of an existing repository
191 clone make a copy of an existing repository
190 init create a new repository in the given directory
192 init create a new repository in the given directory
191
193
192 Remote repository management:
194 Remote repository management:
193
195
194 incoming show new changesets found in source
196 incoming show new changesets found in source
195 outgoing show changesets not found in the destination
197 outgoing show changesets not found in the destination
196 paths show aliases for remote repositories
198 paths show aliases for remote repositories
197 pull pull changes from the specified source
199 pull pull changes from the specified source
198 push push changes to the specified destination
200 push push changes to the specified destination
199 serve start stand-alone webserver
201 serve start stand-alone webserver
200
202
201 Change creation:
203 Change creation:
202
204
203 commit commit the specified files or all outstanding changes
205 commit commit the specified files or all outstanding changes
204
206
205 Change manipulation:
207 Change manipulation:
206
208
207 backout reverse effect of earlier changeset
209 backout reverse effect of earlier changeset
208 graft copy changes from other branches onto the current branch
210 graft copy changes from other branches onto the current branch
209 merge merge another revision into working directory
211 merge merge another revision into working directory
210
212
211 Change organization:
213 Change organization:
212
214
213 bookmarks create a new bookmark or list existing bookmarks
215 bookmarks create a new bookmark or list existing bookmarks
214 branch set or show the current branch name
216 branch set or show the current branch name
215 branches list repository named branches
217 branches list repository named branches
216 phase set or show the current phase name
218 phase set or show the current phase name
217 tag add one or more tags for the current or given revision
219 tag add one or more tags for the current or given revision
218 tags list repository tags
220 tags list repository tags
219
221
220 File content management:
222 File content management:
221
223
222 annotate show changeset information by line for each file
224 annotate show changeset information by line for each file
223 cat output the current or given revision of files
225 cat output the current or given revision of files
224 copy mark files as copied for the next commit
226 copy mark files as copied for the next commit
225 diff diff repository (or selected files)
227 diff diff repository (or selected files)
226 grep search for a pattern in specified files
228 grep search for a pattern in specified files
227
229
228 Change navigation:
230 Change navigation:
229
231
230 bisect subdivision search of changesets
232 bisect subdivision search of changesets
231 heads show branch heads
233 heads show branch heads
232 identify identify the working directory or specified revision
234 identify identify the working directory or specified revision
233 log show revision history of entire repository or files
235 log show revision history of entire repository or files
234
236
235 Working directory management:
237 Working directory management:
236
238
237 add add the specified files on the next commit
239 add add the specified files on the next commit
238 addremove add all new files, delete all missing files
240 addremove add all new files, delete all missing files
239 files list tracked files
241 files list tracked files
240 forget forget the specified files on the next commit
242 forget forget the specified files on the next commit
241 purge removes files not tracked by Mercurial
243 purge removes files not tracked by Mercurial
242 remove remove the specified files on the next commit
244 remove remove the specified files on the next commit
243 rename rename files; equivalent of copy + remove
245 rename rename files; equivalent of copy + remove
244 resolve redo merges or set/view the merge status of files
246 resolve redo merges or set/view the merge status of files
245 revert restore files to their checkout state
247 revert restore files to their checkout state
246 root print the root (top) of the current working directory
248 root print the root (top) of the current working directory
247 shelve save and set aside changes from the working directory
249 shelve save and set aside changes from the working directory
248 status show changed files in the working directory
250 status show changed files in the working directory
249 summary summarize working directory state
251 summary summarize working directory state
250 unshelve restore a shelved change to the working directory
252 unshelve restore a shelved change to the working directory
251 update update working directory (or switch revisions)
253 update update working directory (or switch revisions)
252
254
253 Change import/export:
255 Change import/export:
254
256
255 archive create an unversioned archive of a repository revision
257 archive create an unversioned archive of a repository revision
256 bundle create a bundle file
258 bundle create a bundle file
257 export dump the header and diffs for one or more changesets
259 export dump the header and diffs for one or more changesets
258 import import an ordered set of patches
260 import import an ordered set of patches
259 unbundle apply one or more bundle files
261 unbundle apply one or more bundle files
260
262
261 Repository maintenance:
263 Repository maintenance:
262
264
265 admin::verify
266 verify the integrity of the repository
263 manifest output the current or given revision of the project manifest
267 manifest output the current or given revision of the project manifest
264 recover roll back an interrupted transaction
268 recover roll back an interrupted transaction
265 verify verify the integrity of the repository
269 verify verify the integrity of the repository
266
270
267 Help:
271 Help:
268
272
269 config show combined config settings from all hgrc files
273 config show combined config settings from all hgrc files
270 help show help for a given topic or a help overview
274 help show help for a given topic or a help overview
271 version output version and copyright information
275 version output version and copyright information
272
276
273 additional help topics:
277 additional help topics:
274
278
275 Mercurial identifiers:
279 Mercurial identifiers:
276
280
277 filesets Specifying File Sets
281 filesets Specifying File Sets
278 hgignore Syntax for Mercurial Ignore Files
282 hgignore Syntax for Mercurial Ignore Files
279 patterns File Name Patterns
283 patterns File Name Patterns
280 revisions Specifying Revisions
284 revisions Specifying Revisions
281 urls URL Paths
285 urls URL Paths
282
286
283 Mercurial output:
287 Mercurial output:
284
288
285 color Colorizing Outputs
289 color Colorizing Outputs
286 dates Date Formats
290 dates Date Formats
287 diffs Diff Formats
291 diffs Diff Formats
288 templating Template Usage
292 templating Template Usage
289
293
290 Mercurial configuration:
294 Mercurial configuration:
291
295
292 config Configuration Files
296 config Configuration Files
293 environment Environment Variables
297 environment Environment Variables
294 extensions Using Additional Features
298 extensions Using Additional Features
295 flags Command-line flags
299 flags Command-line flags
296 hgweb Configuring hgweb
300 hgweb Configuring hgweb
297 merge-tools Merge Tools
301 merge-tools Merge Tools
298 pager Pager Support
302 pager Pager Support
299 rust Rust in Mercurial
303 rust Rust in Mercurial
300
304
301 Concepts:
305 Concepts:
302
306
303 bundlespec Bundle File Formats
307 bundlespec Bundle File Formats
304 evolution Safely rewriting history (EXPERIMENTAL)
308 evolution Safely rewriting history (EXPERIMENTAL)
305 glossary Glossary
309 glossary Glossary
306 phases Working with Phases
310 phases Working with Phases
307 subrepos Subrepositories
311 subrepos Subrepositories
308
312
309 Miscellaneous:
313 Miscellaneous:
310
314
311 deprecated Deprecated Features
315 deprecated Deprecated Features
312 internals Technical implementation topics
316 internals Technical implementation topics
313 scripting Using Mercurial from scripts and automation
317 scripting Using Mercurial from scripts and automation
314
318
315 Test extension help:
319 Test extension help:
316 $ hg help extensions --config extensions.rebase= --config extensions.children=
320 $ hg help extensions --config extensions.rebase= --config extensions.children=
317 Using Additional Features
321 Using Additional Features
318 """""""""""""""""""""""""
322 """""""""""""""""""""""""
319
323
320 Mercurial has the ability to add new features through the use of
324 Mercurial has the ability to add new features through the use of
321 extensions. Extensions may add new commands, add options to existing
325 extensions. Extensions may add new commands, add options to existing
322 commands, change the default behavior of commands, or implement hooks.
326 commands, change the default behavior of commands, or implement hooks.
323
327
324 To enable the "foo" extension, either shipped with Mercurial or in the
328 To enable the "foo" extension, either shipped with Mercurial or in the
325 Python search path, create an entry for it in your configuration file,
329 Python search path, create an entry for it in your configuration file,
326 like this:
330 like this:
327
331
328 [extensions]
332 [extensions]
329 foo =
333 foo =
330
334
331 You may also specify the full path to an extension:
335 You may also specify the full path to an extension:
332
336
333 [extensions]
337 [extensions]
334 myfeature = ~/.hgext/myfeature.py
338 myfeature = ~/.hgext/myfeature.py
335
339
336 See 'hg help config' for more information on configuration files.
340 See 'hg help config' for more information on configuration files.
337
341
338 Extensions are not loaded by default for a variety of reasons: they can
342 Extensions are not loaded by default for a variety of reasons: they can
339 increase startup overhead; they may be meant for advanced usage only; they
343 increase startup overhead; they may be meant for advanced usage only; they
340 may provide potentially dangerous abilities (such as letting you destroy
344 may provide potentially dangerous abilities (such as letting you destroy
341 or modify history); they might not be ready for prime time; or they may
345 or modify history); they might not be ready for prime time; or they may
342 alter some usual behaviors of stock Mercurial. It is thus up to the user
346 alter some usual behaviors of stock Mercurial. It is thus up to the user
343 to activate extensions as needed.
347 to activate extensions as needed.
344
348
345 To explicitly disable an extension enabled in a configuration file of
349 To explicitly disable an extension enabled in a configuration file of
346 broader scope, prepend its path with !:
350 broader scope, prepend its path with !:
347
351
348 [extensions]
352 [extensions]
349 # disabling extension bar residing in /path/to/extension/bar.py
353 # disabling extension bar residing in /path/to/extension/bar.py
350 bar = !/path/to/extension/bar.py
354 bar = !/path/to/extension/bar.py
351 # ditto, but no path was supplied for extension baz
355 # ditto, but no path was supplied for extension baz
352 baz = !
356 baz = !
353
357
354 enabled extensions:
358 enabled extensions:
355
359
356 children command to display child changesets (DEPRECATED)
360 children command to display child changesets (DEPRECATED)
357 rebase command to move sets of revisions to a different ancestor
361 rebase command to move sets of revisions to a different ancestor
358
362
359 disabled extensions:
363 disabled extensions:
360
364
361 acl hooks for controlling repository access
365 acl hooks for controlling repository access
362 blackbox log repository events to a blackbox for debugging
366 blackbox log repository events to a blackbox for debugging
363 bugzilla hooks for integrating with the Bugzilla bug tracker
367 bugzilla hooks for integrating with the Bugzilla bug tracker
364 censor erase file content at a given revision
368 censor erase file content at a given revision
365 churn command to display statistics about repository history
369 churn command to display statistics about repository history
366 clonebundles advertise pre-generated bundles to seed clones
370 clonebundles advertise pre-generated bundles to seed clones
367 closehead close arbitrary heads without checking them out first
371 closehead close arbitrary heads without checking them out first
368 convert import revisions from foreign VCS repositories into
372 convert import revisions from foreign VCS repositories into
369 Mercurial
373 Mercurial
370 eol automatically manage newlines in repository files
374 eol automatically manage newlines in repository files
371 extdiff command to allow external programs to compare revisions
375 extdiff command to allow external programs to compare revisions
372 factotum http authentication with factotum
376 factotum http authentication with factotum
373 fastexport export repositories as git fast-import stream
377 fastexport export repositories as git fast-import stream
374 githelp try mapping git commands to Mercurial commands
378 githelp try mapping git commands to Mercurial commands
375 gpg commands to sign and verify changesets
379 gpg commands to sign and verify changesets
376 hgk browse the repository in a graphical way
380 hgk browse the repository in a graphical way
377 highlight syntax highlighting for hgweb (requires Pygments)
381 highlight syntax highlighting for hgweb (requires Pygments)
378 histedit interactive history editing
382 histedit interactive history editing
379 keyword expand keywords in tracked files
383 keyword expand keywords in tracked files
380 largefiles track large binary files
384 largefiles track large binary files
381 mq manage a stack of patches
385 mq manage a stack of patches
382 notify hooks for sending email push notifications
386 notify hooks for sending email push notifications
383 patchbomb command to send changesets as (a series of) patch emails
387 patchbomb command to send changesets as (a series of) patch emails
384 relink recreates hardlinks between repository clones
388 relink recreates hardlinks between repository clones
385 schemes extend schemes with shortcuts to repository swarms
389 schemes extend schemes with shortcuts to repository swarms
386 share share a common history between several working directories
390 share share a common history between several working directories
387 transplant command to transplant changesets from another branch
391 transplant command to transplant changesets from another branch
388 win32mbcs allow the use of MBCS paths with problematic encodings
392 win32mbcs allow the use of MBCS paths with problematic encodings
389 zeroconf discover and advertise repositories on the local network
393 zeroconf discover and advertise repositories on the local network
390
394
391 #endif
395 #endif
392
396
393 Verify that deprecated extensions are included if --verbose:
397 Verify that deprecated extensions are included if --verbose:
394
398
395 $ hg -v help extensions | grep children
399 $ hg -v help extensions | grep children
396 children command to display child changesets (DEPRECATED)
400 children command to display child changesets (DEPRECATED)
397
401
398 Verify that extension keywords appear in help templates
402 Verify that extension keywords appear in help templates
399
403
400 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
404 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
401
405
402 Test short command list with verbose option
406 Test short command list with verbose option
403
407
404 $ hg -v help shortlist
408 $ hg -v help shortlist
405 Mercurial Distributed SCM
409 Mercurial Distributed SCM
406
410
407 basic commands:
411 basic commands:
408
412
409 abort abort an unfinished operation (EXPERIMENTAL)
413 abort abort an unfinished operation (EXPERIMENTAL)
410 add add the specified files on the next commit
414 add add the specified files on the next commit
411 annotate, blame
415 annotate, blame
412 show changeset information by line for each file
416 show changeset information by line for each file
413 clone make a copy of an existing repository
417 clone make a copy of an existing repository
414 commit, ci commit the specified files or all outstanding changes
418 commit, ci commit the specified files or all outstanding changes
415 continue resumes an interrupted operation (EXPERIMENTAL)
419 continue resumes an interrupted operation (EXPERIMENTAL)
416 diff diff repository (or selected files)
420 diff diff repository (or selected files)
417 export dump the header and diffs for one or more changesets
421 export dump the header and diffs for one or more changesets
418 forget forget the specified files on the next commit
422 forget forget the specified files on the next commit
419 init create a new repository in the given directory
423 init create a new repository in the given directory
420 log, history show revision history of entire repository or files
424 log, history show revision history of entire repository or files
421 merge merge another revision into working directory
425 merge merge another revision into working directory
422 pull pull changes from the specified source
426 pull pull changes from the specified source
423 push push changes to the specified destination
427 push push changes to the specified destination
424 remove, rm remove the specified files on the next commit
428 remove, rm remove the specified files on the next commit
425 serve start stand-alone webserver
429 serve start stand-alone webserver
426 status, st show changed files in the working directory
430 status, st show changed files in the working directory
427 summary, sum summarize working directory state
431 summary, sum summarize working directory state
428 update, up, checkout, co
432 update, up, checkout, co
429 update working directory (or switch revisions)
433 update working directory (or switch revisions)
430
434
431 global options ([+] can be repeated):
435 global options ([+] can be repeated):
432
436
433 -R --repository REPO repository root directory or name of overlay bundle
437 -R --repository REPO repository root directory or name of overlay bundle
434 file
438 file
435 --cwd DIR change working directory
439 --cwd DIR change working directory
436 -y --noninteractive do not prompt, automatically pick the first choice for
440 -y --noninteractive do not prompt, automatically pick the first choice for
437 all prompts
441 all prompts
438 -q --quiet suppress output
442 -q --quiet suppress output
439 -v --verbose enable additional output
443 -v --verbose enable additional output
440 --color TYPE when to colorize (boolean, always, auto, never, or
444 --color TYPE when to colorize (boolean, always, auto, never, or
441 debug)
445 debug)
442 --config CONFIG [+] set/override config option (use 'section.name=value')
446 --config CONFIG [+] set/override config option (use 'section.name=value')
443 --debug enable debugging output
447 --debug enable debugging output
444 --debugger start debugger
448 --debugger start debugger
445 --encoding ENCODE set the charset encoding (default: ascii)
449 --encoding ENCODE set the charset encoding (default: ascii)
446 --encodingmode MODE set the charset encoding mode (default: strict)
450 --encodingmode MODE set the charset encoding mode (default: strict)
447 --traceback always print a traceback on exception
451 --traceback always print a traceback on exception
448 --time time how long the command takes
452 --time time how long the command takes
449 --profile print command execution profile
453 --profile print command execution profile
450 --version output version information and exit
454 --version output version information and exit
451 -h --help display help and exit
455 -h --help display help and exit
452 --hidden consider hidden changesets
456 --hidden consider hidden changesets
453 --pager TYPE when to paginate (boolean, always, auto, or never)
457 --pager TYPE when to paginate (boolean, always, auto, or never)
454 (default: auto)
458 (default: auto)
455
459
456 (use 'hg help' for the full list of commands)
460 (use 'hg help' for the full list of commands)
457
461
458 $ hg add -h
462 $ hg add -h
459 hg add [OPTION]... [FILE]...
463 hg add [OPTION]... [FILE]...
460
464
461 add the specified files on the next commit
465 add the specified files on the next commit
462
466
463 Schedule files to be version controlled and added to the repository.
467 Schedule files to be version controlled and added to the repository.
464
468
465 The files will be added to the repository at the next commit. To undo an
469 The files will be added to the repository at the next commit. To undo an
466 add before that, see 'hg forget'.
470 add before that, see 'hg forget'.
467
471
468 If no names are given, add all files to the repository (except files
472 If no names are given, add all files to the repository (except files
469 matching ".hgignore").
473 matching ".hgignore").
470
474
471 Returns 0 if all files are successfully added.
475 Returns 0 if all files are successfully added.
472
476
473 options ([+] can be repeated):
477 options ([+] can be repeated):
474
478
475 -I --include PATTERN [+] include names matching the given patterns
479 -I --include PATTERN [+] include names matching the given patterns
476 -X --exclude PATTERN [+] exclude names matching the given patterns
480 -X --exclude PATTERN [+] exclude names matching the given patterns
477 -S --subrepos recurse into subrepositories
481 -S --subrepos recurse into subrepositories
478 -n --dry-run do not perform actions, just print output
482 -n --dry-run do not perform actions, just print output
479
483
480 (some details hidden, use --verbose to show complete help)
484 (some details hidden, use --verbose to show complete help)
481
485
482 Verbose help for add
486 Verbose help for add
483
487
484 $ hg add -hv
488 $ hg add -hv
485 hg add [OPTION]... [FILE]...
489 hg add [OPTION]... [FILE]...
486
490
487 add the specified files on the next commit
491 add the specified files on the next commit
488
492
489 Schedule files to be version controlled and added to the repository.
493 Schedule files to be version controlled and added to the repository.
490
494
491 The files will be added to the repository at the next commit. To undo an
495 The files will be added to the repository at the next commit. To undo an
492 add before that, see 'hg forget'.
496 add before that, see 'hg forget'.
493
497
494 If no names are given, add all files to the repository (except files
498 If no names are given, add all files to the repository (except files
495 matching ".hgignore").
499 matching ".hgignore").
496
500
497 Examples:
501 Examples:
498
502
499 - New (unknown) files are added automatically by 'hg add':
503 - New (unknown) files are added automatically by 'hg add':
500
504
501 $ ls
505 $ ls
502 foo.c
506 foo.c
503 $ hg status
507 $ hg status
504 ? foo.c
508 ? foo.c
505 $ hg add
509 $ hg add
506 adding foo.c
510 adding foo.c
507 $ hg status
511 $ hg status
508 A foo.c
512 A foo.c
509
513
510 - Specific files to be added can be specified:
514 - Specific files to be added can be specified:
511
515
512 $ ls
516 $ ls
513 bar.c foo.c
517 bar.c foo.c
514 $ hg status
518 $ hg status
515 ? bar.c
519 ? bar.c
516 ? foo.c
520 ? foo.c
517 $ hg add bar.c
521 $ hg add bar.c
518 $ hg status
522 $ hg status
519 A bar.c
523 A bar.c
520 ? foo.c
524 ? foo.c
521
525
522 Returns 0 if all files are successfully added.
526 Returns 0 if all files are successfully added.
523
527
524 options ([+] can be repeated):
528 options ([+] can be repeated):
525
529
526 -I --include PATTERN [+] include names matching the given patterns
530 -I --include PATTERN [+] include names matching the given patterns
527 -X --exclude PATTERN [+] exclude names matching the given patterns
531 -X --exclude PATTERN [+] exclude names matching the given patterns
528 -S --subrepos recurse into subrepositories
532 -S --subrepos recurse into subrepositories
529 -n --dry-run do not perform actions, just print output
533 -n --dry-run do not perform actions, just print output
530
534
531 global options ([+] can be repeated):
535 global options ([+] can be repeated):
532
536
533 -R --repository REPO repository root directory or name of overlay bundle
537 -R --repository REPO repository root directory or name of overlay bundle
534 file
538 file
535 --cwd DIR change working directory
539 --cwd DIR change working directory
536 -y --noninteractive do not prompt, automatically pick the first choice for
540 -y --noninteractive do not prompt, automatically pick the first choice for
537 all prompts
541 all prompts
538 -q --quiet suppress output
542 -q --quiet suppress output
539 -v --verbose enable additional output
543 -v --verbose enable additional output
540 --color TYPE when to colorize (boolean, always, auto, never, or
544 --color TYPE when to colorize (boolean, always, auto, never, or
541 debug)
545 debug)
542 --config CONFIG [+] set/override config option (use 'section.name=value')
546 --config CONFIG [+] set/override config option (use 'section.name=value')
543 --debug enable debugging output
547 --debug enable debugging output
544 --debugger start debugger
548 --debugger start debugger
545 --encoding ENCODE set the charset encoding (default: ascii)
549 --encoding ENCODE set the charset encoding (default: ascii)
546 --encodingmode MODE set the charset encoding mode (default: strict)
550 --encodingmode MODE set the charset encoding mode (default: strict)
547 --traceback always print a traceback on exception
551 --traceback always print a traceback on exception
548 --time time how long the command takes
552 --time time how long the command takes
549 --profile print command execution profile
553 --profile print command execution profile
550 --version output version information and exit
554 --version output version information and exit
551 -h --help display help and exit
555 -h --help display help and exit
552 --hidden consider hidden changesets
556 --hidden consider hidden changesets
553 --pager TYPE when to paginate (boolean, always, auto, or never)
557 --pager TYPE when to paginate (boolean, always, auto, or never)
554 (default: auto)
558 (default: auto)
555
559
556 Test the textwidth config option
560 Test the textwidth config option
557
561
558 $ hg root -h --config ui.textwidth=50
562 $ hg root -h --config ui.textwidth=50
559 hg root
563 hg root
560
564
561 print the root (top) of the current working
565 print the root (top) of the current working
562 directory
566 directory
563
567
564 Print the root directory of the current
568 Print the root directory of the current
565 repository.
569 repository.
566
570
567 Returns 0 on success.
571 Returns 0 on success.
568
572
569 options:
573 options:
570
574
571 -T --template TEMPLATE display with template
575 -T --template TEMPLATE display with template
572
576
573 (some details hidden, use --verbose to show
577 (some details hidden, use --verbose to show
574 complete help)
578 complete help)
575
579
576 Test help option with version option
580 Test help option with version option
577
581
578 $ hg add -h --version
582 $ hg add -h --version
579 Mercurial Distributed SCM (version *) (glob)
583 Mercurial Distributed SCM (version *) (glob)
580 (see https://mercurial-scm.org for more information)
584 (see https://mercurial-scm.org for more information)
581
585
582 Copyright (C) 2005-* Olivia Mackall and others (glob)
586 Copyright (C) 2005-* Olivia Mackall and others (glob)
583 This is free software; see the source for copying conditions. There is NO
587 This is free software; see the source for copying conditions. There is NO
584 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
588 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
585
589
586 $ hg add --skjdfks
590 $ hg add --skjdfks
587 hg add: option --skjdfks not recognized
591 hg add: option --skjdfks not recognized
588 hg add [OPTION]... [FILE]...
592 hg add [OPTION]... [FILE]...
589
593
590 add the specified files on the next commit
594 add the specified files on the next commit
591
595
592 options ([+] can be repeated):
596 options ([+] can be repeated):
593
597
594 -I --include PATTERN [+] include names matching the given patterns
598 -I --include PATTERN [+] include names matching the given patterns
595 -X --exclude PATTERN [+] exclude names matching the given patterns
599 -X --exclude PATTERN [+] exclude names matching the given patterns
596 -S --subrepos recurse into subrepositories
600 -S --subrepos recurse into subrepositories
597 -n --dry-run do not perform actions, just print output
601 -n --dry-run do not perform actions, just print output
598
602
599 (use 'hg add -h' to show more help)
603 (use 'hg add -h' to show more help)
600 [10]
604 [10]
601
605
602 Test ambiguous command help
606 Test ambiguous command help
603
607
604 $ hg help ad
608 $ hg help ad
605 list of commands:
609 list of commands:
606
610
611 Working directory management:
612
607 add add the specified files on the next commit
613 add add the specified files on the next commit
608 addremove add all new files, delete all missing files
614 addremove add all new files, delete all missing files
609
615
616 Repository maintenance:
617
618 admin::verify
619 verify the integrity of the repository
620
610 (use 'hg help -v ad' to show built-in aliases and global options)
621 (use 'hg help -v ad' to show built-in aliases and global options)
611
622
612 Test command without options
623 Test command without options
613
624
614 $ hg help verify
625 $ hg help verify
615 hg verify
626 hg verify
616
627
617 verify the integrity of the repository
628 verify the integrity of the repository
618
629
619 Verify the integrity of the current repository.
630 Verify the integrity of the current repository.
620
631
621 This will perform an extensive check of the repository's integrity,
632 This will perform an extensive check of the repository's integrity,
622 validating the hashes and checksums of each entry in the changelog,
633 validating the hashes and checksums of each entry in the changelog,
623 manifest, and tracked files, as well as the integrity of their crosslinks
634 manifest, and tracked files, as well as the integrity of their crosslinks
624 and indices.
635 and indices.
625
636
626 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
637 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
627 information about recovery from corruption of the repository.
638 information about recovery from corruption of the repository.
628
639
640 For an alternative UI with a lot more control over the verification
641 process and better error reporting, try 'hg help admin::verify'.
642
629 Returns 0 on success, 1 if errors are encountered.
643 Returns 0 on success, 1 if errors are encountered.
630
644
631 options:
645 options:
632
646
633 (some details hidden, use --verbose to show complete help)
647 (some details hidden, use --verbose to show complete help)
634
648
635 $ hg help diff
649 $ hg help diff
636 hg diff [OPTION]... ([-c REV] | [--from REV1] [--to REV2]) [FILE]...
650 hg diff [OPTION]... ([-c REV] | [--from REV1] [--to REV2]) [FILE]...
637
651
638 diff repository (or selected files)
652 diff repository (or selected files)
639
653
640 Show differences between revisions for the specified files.
654 Show differences between revisions for the specified files.
641
655
642 Differences between files are shown using the unified diff format.
656 Differences between files are shown using the unified diff format.
643
657
644 Note:
658 Note:
645 'hg diff' may generate unexpected results for merges, as it will
659 'hg diff' may generate unexpected results for merges, as it will
646 default to comparing against the working directory's first parent
660 default to comparing against the working directory's first parent
647 changeset if no revisions are specified. To diff against the conflict
661 changeset if no revisions are specified. To diff against the conflict
648 regions, you can use '--config diff.merge=yes'.
662 regions, you can use '--config diff.merge=yes'.
649
663
650 By default, the working directory files are compared to its first parent.
664 By default, the working directory files are compared to its first parent.
651 To see the differences from another revision, use --from. To see the
665 To see the differences from another revision, use --from. To see the
652 difference to another revision, use --to. For example, 'hg diff --from .^'
666 difference to another revision, use --to. For example, 'hg diff --from .^'
653 will show the differences from the working copy's grandparent to the
667 will show the differences from the working copy's grandparent to the
654 working copy, 'hg diff --to .' will show the diff from the working copy to
668 working copy, 'hg diff --to .' will show the diff from the working copy to
655 its parent (i.e. the reverse of the default), and 'hg diff --from 1.0 --to
669 its parent (i.e. the reverse of the default), and 'hg diff --from 1.0 --to
656 1.2' will show the diff between those two revisions.
670 1.2' will show the diff between those two revisions.
657
671
658 Alternatively you can specify -c/--change with a revision to see the
672 Alternatively you can specify -c/--change with a revision to see the
659 changes in that changeset relative to its first parent (i.e. 'hg diff -c
673 changes in that changeset relative to its first parent (i.e. 'hg diff -c
660 42' is equivalent to 'hg diff --from 42^ --to 42')
674 42' is equivalent to 'hg diff --from 42^ --to 42')
661
675
662 Without the -a/--text option, diff will avoid generating diffs of files it
676 Without the -a/--text option, diff will avoid generating diffs of files it
663 detects as binary. With -a, diff will generate a diff anyway, probably
677 detects as binary. With -a, diff will generate a diff anyway, probably
664 with undesirable results.
678 with undesirable results.
665
679
666 Use the -g/--git option to generate diffs in the git extended diff format.
680 Use the -g/--git option to generate diffs in the git extended diff format.
667 For more information, read 'hg help diffs'.
681 For more information, read 'hg help diffs'.
668
682
669 Returns 0 on success.
683 Returns 0 on success.
670
684
671 options ([+] can be repeated):
685 options ([+] can be repeated):
672
686
673 --from REV1 revision to diff from
687 --from REV1 revision to diff from
674 --to REV2 revision to diff to
688 --to REV2 revision to diff to
675 -c --change REV change made by revision
689 -c --change REV change made by revision
676 -a --text treat all files as text
690 -a --text treat all files as text
677 -g --git use git extended diff format
691 -g --git use git extended diff format
678 --binary generate binary diffs in git mode (default)
692 --binary generate binary diffs in git mode (default)
679 --nodates omit dates from diff headers
693 --nodates omit dates from diff headers
680 --noprefix omit a/ and b/ prefixes from filenames
694 --noprefix omit a/ and b/ prefixes from filenames
681 -p --show-function show which function each change is in
695 -p --show-function show which function each change is in
682 --reverse produce a diff that undoes the changes
696 --reverse produce a diff that undoes the changes
683 -w --ignore-all-space ignore white space when comparing lines
697 -w --ignore-all-space ignore white space when comparing lines
684 -b --ignore-space-change ignore changes in the amount of white space
698 -b --ignore-space-change ignore changes in the amount of white space
685 -B --ignore-blank-lines ignore changes whose lines are all blank
699 -B --ignore-blank-lines ignore changes whose lines are all blank
686 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
700 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
687 -U --unified NUM number of lines of context to show
701 -U --unified NUM number of lines of context to show
688 --stat output diffstat-style summary of changes
702 --stat output diffstat-style summary of changes
689 --root DIR produce diffs relative to subdirectory
703 --root DIR produce diffs relative to subdirectory
690 -I --include PATTERN [+] include names matching the given patterns
704 -I --include PATTERN [+] include names matching the given patterns
691 -X --exclude PATTERN [+] exclude names matching the given patterns
705 -X --exclude PATTERN [+] exclude names matching the given patterns
692 -S --subrepos recurse into subrepositories
706 -S --subrepos recurse into subrepositories
693
707
694 (some details hidden, use --verbose to show complete help)
708 (some details hidden, use --verbose to show complete help)
695
709
696 $ hg help status
710 $ hg help status
697 hg status [OPTION]... [FILE]...
711 hg status [OPTION]... [FILE]...
698
712
699 aliases: st
713 aliases: st
700
714
701 show changed files in the working directory
715 show changed files in the working directory
702
716
703 Show status of files in the repository. If names are given, only files
717 Show status of files in the repository. If names are given, only files
704 that match are shown. Files that are clean or ignored or the source of a
718 that match are shown. Files that are clean or ignored or the source of a
705 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
719 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
706 -C/--copies or -A/--all are given. Unless options described with "show
720 -C/--copies or -A/--all are given. Unless options described with "show
707 only ..." are given, the options -mardu are used.
721 only ..." are given, the options -mardu are used.
708
722
709 Option -q/--quiet hides untracked (unknown and ignored) files unless
723 Option -q/--quiet hides untracked (unknown and ignored) files unless
710 explicitly requested with -u/--unknown or -i/--ignored.
724 explicitly requested with -u/--unknown or -i/--ignored.
711
725
712 Note:
726 Note:
713 'hg status' may appear to disagree with diff if permissions have
727 'hg status' may appear to disagree with diff if permissions have
714 changed or a merge has occurred. The standard diff format does not
728 changed or a merge has occurred. The standard diff format does not
715 report permission changes and diff only reports changes relative to one
729 report permission changes and diff only reports changes relative to one
716 merge parent.
730 merge parent.
717
731
718 If one revision is given, it is used as the base revision. If two
732 If one revision is given, it is used as the base revision. If two
719 revisions are given, the differences between them are shown. The --change
733 revisions are given, the differences between them are shown. The --change
720 option can also be used as a shortcut to list the changed files of a
734 option can also be used as a shortcut to list the changed files of a
721 revision from its first parent.
735 revision from its first parent.
722
736
723 The codes used to show the status of files are:
737 The codes used to show the status of files are:
724
738
725 M = modified
739 M = modified
726 A = added
740 A = added
727 R = removed
741 R = removed
728 C = clean
742 C = clean
729 ! = missing (deleted by non-hg command, but still tracked)
743 ! = missing (deleted by non-hg command, but still tracked)
730 ? = not tracked
744 ? = not tracked
731 I = ignored
745 I = ignored
732 = origin of the previous file (with --copies)
746 = origin of the previous file (with --copies)
733
747
734 Returns 0 on success.
748 Returns 0 on success.
735
749
736 options ([+] can be repeated):
750 options ([+] can be repeated):
737
751
738 -A --all show status of all files
752 -A --all show status of all files
739 -m --modified show only modified files
753 -m --modified show only modified files
740 -a --added show only added files
754 -a --added show only added files
741 -r --removed show only removed files
755 -r --removed show only removed files
742 -d --deleted show only missing files
756 -d --deleted show only missing files
743 -c --clean show only files without changes
757 -c --clean show only files without changes
744 -u --unknown show only unknown (not tracked) files
758 -u --unknown show only unknown (not tracked) files
745 -i --ignored show only ignored files
759 -i --ignored show only ignored files
746 -n --no-status hide status prefix
760 -n --no-status hide status prefix
747 -C --copies show source of copied files
761 -C --copies show source of copied files
748 -0 --print0 end filenames with NUL, for use with xargs
762 -0 --print0 end filenames with NUL, for use with xargs
749 --rev REV [+] show difference from revision
763 --rev REV [+] show difference from revision
750 --change REV list the changed files of a revision
764 --change REV list the changed files of a revision
751 -I --include PATTERN [+] include names matching the given patterns
765 -I --include PATTERN [+] include names matching the given patterns
752 -X --exclude PATTERN [+] exclude names matching the given patterns
766 -X --exclude PATTERN [+] exclude names matching the given patterns
753 -S --subrepos recurse into subrepositories
767 -S --subrepos recurse into subrepositories
754 -T --template TEMPLATE display with template
768 -T --template TEMPLATE display with template
755
769
756 (some details hidden, use --verbose to show complete help)
770 (some details hidden, use --verbose to show complete help)
757
771
758 $ hg -q help status
772 $ hg -q help status
759 hg status [OPTION]... [FILE]...
773 hg status [OPTION]... [FILE]...
760
774
761 show changed files in the working directory
775 show changed files in the working directory
762
776
763 $ hg help foo
777 $ hg help foo
764 abort: no such help topic: foo
778 abort: no such help topic: foo
765 (try 'hg help --keyword foo')
779 (try 'hg help --keyword foo')
766 [10]
780 [10]
767
781
768 $ hg skjdfks
782 $ hg skjdfks
769 hg: unknown command 'skjdfks'
783 hg: unknown command 'skjdfks'
770 (use 'hg help' for a list of commands)
784 (use 'hg help' for a list of commands)
771 [10]
785 [10]
772
786
773 Typoed command gives suggestion
787 Typoed command gives suggestion
774 $ hg puls
788 $ hg puls
775 hg: unknown command 'puls'
789 hg: unknown command 'puls'
776 (did you mean one of pull, push?)
790 (did you mean one of pull, push?)
777 [10]
791 [10]
778
792
779 Not enabled extension gets suggested
793 Not enabled extension gets suggested
780
794
781 $ hg rebase
795 $ hg rebase
782 hg: unknown command 'rebase'
796 hg: unknown command 'rebase'
783 'rebase' is provided by the following extension:
797 'rebase' is provided by the following extension:
784
798
785 rebase command to move sets of revisions to a different ancestor
799 rebase command to move sets of revisions to a different ancestor
786
800
787 (use 'hg help extensions' for information on enabling extensions)
801 (use 'hg help extensions' for information on enabling extensions)
788 [10]
802 [10]
789
803
790 Disabled extension gets suggested
804 Disabled extension gets suggested
791 $ hg --config extensions.rebase=! rebase
805 $ hg --config extensions.rebase=! rebase
792 hg: unknown command 'rebase'
806 hg: unknown command 'rebase'
793 'rebase' is provided by the following extension:
807 'rebase' is provided by the following extension:
794
808
795 rebase command to move sets of revisions to a different ancestor
809 rebase command to move sets of revisions to a different ancestor
796
810
797 (use 'hg help extensions' for information on enabling extensions)
811 (use 'hg help extensions' for information on enabling extensions)
798 [10]
812 [10]
799
813
800 Checking that help adapts based on the config:
814 Checking that help adapts based on the config:
801
815
802 $ hg help diff --config ui.tweakdefaults=true | grep -E -e '^ *(-g|config)'
816 $ hg help diff --config ui.tweakdefaults=true | grep -E -e '^ *(-g|config)'
803 -g --[no-]git use git extended diff format (default: on from
817 -g --[no-]git use git extended diff format (default: on from
804 config)
818 config)
805
819
806 Make sure that we don't run afoul of the help system thinking that
820 Make sure that we don't run afoul of the help system thinking that
807 this is a section and erroring out weirdly.
821 this is a section and erroring out weirdly.
808
822
809 $ hg .log
823 $ hg .log
810 hg: unknown command '.log'
824 hg: unknown command '.log'
811 (did you mean log?)
825 (did you mean log?)
812 [10]
826 [10]
813
827
814 $ hg log.
828 $ hg log.
815 hg: unknown command 'log.'
829 hg: unknown command 'log.'
816 (did you mean log?)
830 (did you mean log?)
817 [10]
831 [10]
818 $ hg pu.lh
832 $ hg pu.lh
819 hg: unknown command 'pu.lh'
833 hg: unknown command 'pu.lh'
820 (did you mean one of pull, push?)
834 (did you mean one of pull, push?)
821 [10]
835 [10]
822
836
823 $ cat > helpext.py <<EOF
837 $ cat > helpext.py <<EOF
824 > import os
838 > import os
825 > from mercurial import commands, fancyopts, registrar
839 > from mercurial import commands, fancyopts, registrar
826 >
840 >
827 > def func(arg):
841 > def func(arg):
828 > return '%sfoo' % arg
842 > return '%sfoo' % arg
829 > class customopt(fancyopts.customopt):
843 > class customopt(fancyopts.customopt):
830 > def newstate(self, oldstate, newparam, abort):
844 > def newstate(self, oldstate, newparam, abort):
831 > return '%sbar' % oldstate
845 > return '%sbar' % oldstate
832 > cmdtable = {}
846 > cmdtable = {}
833 > command = registrar.command(cmdtable)
847 > command = registrar.command(cmdtable)
834 >
848 >
835 > @command(b'nohelp',
849 > @command(b'nohelp',
836 > [(b'', b'longdesc', 3, b'x'*67),
850 > [(b'', b'longdesc', 3, b'x'*67),
837 > (b'n', b'', None, b'normal desc'),
851 > (b'n', b'', None, b'normal desc'),
838 > (b'', b'newline', b'', b'line1\nline2'),
852 > (b'', b'newline', b'', b'line1\nline2'),
839 > (b'', b'default-off', False, b'enable X'),
853 > (b'', b'default-off', False, b'enable X'),
840 > (b'', b'default-on', True, b'enable Y'),
854 > (b'', b'default-on', True, b'enable Y'),
841 > (b'', b'callableopt', func, b'adds foo'),
855 > (b'', b'callableopt', func, b'adds foo'),
842 > (b'', b'customopt', customopt(''), b'adds bar'),
856 > (b'', b'customopt', customopt(''), b'adds bar'),
843 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
857 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
844 > b'hg nohelp',
858 > b'hg nohelp',
845 > norepo=True)
859 > norepo=True)
846 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
860 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
847 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
861 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
848 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
862 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
849 > def nohelp(ui, *args, **kwargs):
863 > def nohelp(ui, *args, **kwargs):
850 > pass
864 > pass
851 >
865 >
852 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
866 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
853 > def hashelp(ui, *args, **kwargs):
867 > def hashelp(ui, *args, **kwargs):
854 > """Extension command's help"""
868 > """Extension command's help"""
855 >
869 >
856 > def uisetup(ui):
870 > def uisetup(ui):
857 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
871 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
858 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
872 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
859 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
873 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
860 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
874 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
861 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
875 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
862 >
876 >
863 > EOF
877 > EOF
864 $ echo '[extensions]' >> $HGRCPATH
878 $ echo '[extensions]' >> $HGRCPATH
865 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
879 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
866
880
867 Test for aliases
881 Test for aliases
868
882
869 $ hg help | grep hgalias
883 $ hg help | grep hgalias
870 hgalias My doc
884 hgalias My doc
871
885
872 $ hg help hgalias
886 $ hg help hgalias
873 hg hgalias [--remote]
887 hg hgalias [--remote]
874
888
875 alias for: hg summary
889 alias for: hg summary
876
890
877 My doc
891 My doc
878
892
879 defined by: helpext
893 defined by: helpext
880
894
881 options:
895 options:
882
896
883 --remote check for push and pull
897 --remote check for push and pull
884
898
885 (some details hidden, use --verbose to show complete help)
899 (some details hidden, use --verbose to show complete help)
886 $ hg help hgaliasnodoc
900 $ hg help hgaliasnodoc
887 hg hgaliasnodoc [--remote]
901 hg hgaliasnodoc [--remote]
888
902
889 alias for: hg summary
903 alias for: hg summary
890
904
891 summarize working directory state
905 summarize working directory state
892
906
893 This generates a brief summary of the working directory state, including
907 This generates a brief summary of the working directory state, including
894 parents, branch, commit status, phase and available updates.
908 parents, branch, commit status, phase and available updates.
895
909
896 With the --remote option, this will check the default paths for incoming
910 With the --remote option, this will check the default paths for incoming
897 and outgoing changes. This can be time-consuming.
911 and outgoing changes. This can be time-consuming.
898
912
899 Returns 0 on success.
913 Returns 0 on success.
900
914
901 defined by: helpext
915 defined by: helpext
902
916
903 options:
917 options:
904
918
905 --remote check for push and pull
919 --remote check for push and pull
906
920
907 (some details hidden, use --verbose to show complete help)
921 (some details hidden, use --verbose to show complete help)
908
922
909 $ hg help shellalias
923 $ hg help shellalias
910 hg shellalias
924 hg shellalias
911
925
912 shell alias for: echo hi
926 shell alias for: echo hi
913
927
914 (no help text available)
928 (no help text available)
915
929
916 defined by: helpext
930 defined by: helpext
917
931
918 (some details hidden, use --verbose to show complete help)
932 (some details hidden, use --verbose to show complete help)
919
933
920 Test command with no help text
934 Test command with no help text
921
935
922 $ hg help nohelp
936 $ hg help nohelp
923 hg nohelp
937 hg nohelp
924
938
925 (no help text available)
939 (no help text available)
926
940
927 options:
941 options:
928
942
929 --longdesc VALUE
943 --longdesc VALUE
930 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
944 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
931 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
945 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
932 -n -- normal desc
946 -n -- normal desc
933 --newline VALUE line1 line2
947 --newline VALUE line1 line2
934 --default-off enable X
948 --default-off enable X
935 --[no-]default-on enable Y (default: on)
949 --[no-]default-on enable Y (default: on)
936 --callableopt VALUE adds foo
950 --callableopt VALUE adds foo
937 --customopt VALUE adds bar
951 --customopt VALUE adds bar
938 --customopt-withdefault VALUE adds bar (default: foo)
952 --customopt-withdefault VALUE adds bar (default: foo)
939
953
940 (some details hidden, use --verbose to show complete help)
954 (some details hidden, use --verbose to show complete help)
941
955
942 Test that default list of commands includes extension commands that have help,
956 Test that default list of commands includes extension commands that have help,
943 but not those that don't, except in verbose mode, when a keyword is passed, or
957 but not those that don't, except in verbose mode, when a keyword is passed, or
944 when help about the extension is requested.
958 when help about the extension is requested.
945
959
946 #if no-extraextensions
960 #if no-extraextensions
947
961
948 $ hg help | grep hashelp
962 $ hg help | grep hashelp
949 hashelp Extension command's help
963 hashelp Extension command's help
950 $ hg help | grep nohelp
964 $ hg help | grep nohelp
951 [1]
965 [1]
952 $ hg help -v | grep nohelp
966 $ hg help -v | grep nohelp
953 nohelp (no help text available)
967 nohelp (no help text available)
954
968
955 $ hg help -k nohelp
969 $ hg help -k nohelp
956 Commands:
970 Commands:
957
971
958 nohelp hg nohelp
972 nohelp hg nohelp
959
973
960 Extension Commands:
974 Extension Commands:
961
975
962 nohelp (no help text available)
976 nohelp (no help text available)
963
977
964 $ hg help helpext
978 $ hg help helpext
965 helpext extension - no help text available
979 helpext extension - no help text available
966
980
967 list of commands:
981 list of commands:
968
982
969 hashelp Extension command's help
983 hashelp Extension command's help
970 nohelp (no help text available)
984 nohelp (no help text available)
971
985
972 (use 'hg help -v helpext' to show built-in aliases and global options)
986 (use 'hg help -v helpext' to show built-in aliases and global options)
973
987
974 #endif
988 #endif
975
989
976 Test list of internal help commands
990 Test list of internal help commands
977
991
978 $ hg help debug
992 $ hg help debug
979 debug commands (internal and unsupported):
993 debug commands (internal and unsupported):
980
994
981 debug-delta-find
995 debug-delta-find
982 display the computation to get to a valid delta for storing REV
996 display the computation to get to a valid delta for storing REV
983 debug-repair-issue6528
997 debug-repair-issue6528
984 find affected revisions and repair them. See issue6528 for more
998 find affected revisions and repair them. See issue6528 for more
985 details.
999 details.
986 debug-revlog-index
1000 debug-revlog-index
987 dump index data for a revlog
1001 dump index data for a revlog
988 debug-revlog-stats
1002 debug-revlog-stats
989 display statistics about revlogs in the store
1003 display statistics about revlogs in the store
990 debug::stable-tail-sort
1004 debug::stable-tail-sort
991 display the stable-tail sort of the ancestors of a given node
1005 display the stable-tail sort of the ancestors of a given node
992 debug::stable-tail-sort-leaps
1006 debug::stable-tail-sort-leaps
993 display the leaps in the stable-tail sort of a node, one per
1007 display the leaps in the stable-tail sort of a node, one per
994 line
1008 line
995 debugancestor
1009 debugancestor
996 find the ancestor revision of two revisions in a given index
1010 find the ancestor revision of two revisions in a given index
997 debugantivirusrunning
1011 debugantivirusrunning
998 attempt to trigger an antivirus scanner to see if one is active
1012 attempt to trigger an antivirus scanner to see if one is active
999 debugapplystreamclonebundle
1013 debugapplystreamclonebundle
1000 apply a stream clone bundle file
1014 apply a stream clone bundle file
1001 debugbackupbundle
1015 debugbackupbundle
1002 lists the changesets available in backup bundles
1016 lists the changesets available in backup bundles
1003 debugbuilddag
1017 debugbuilddag
1004 builds a repo with a given DAG from scratch in the current
1018 builds a repo with a given DAG from scratch in the current
1005 empty repo
1019 empty repo
1006 debugbundle lists the contents of a bundle
1020 debugbundle lists the contents of a bundle
1007 debugcapabilities
1021 debugcapabilities
1008 lists the capabilities of a remote peer
1022 lists the capabilities of a remote peer
1009 debugchangedfiles
1023 debugchangedfiles
1010 list the stored files changes for a revision
1024 list the stored files changes for a revision
1011 debugcheckstate
1025 debugcheckstate
1012 validate the correctness of the current dirstate
1026 validate the correctness of the current dirstate
1013 debugcolor show available color, effects or style
1027 debugcolor show available color, effects or style
1014 debugcommands
1028 debugcommands
1015 list all available commands and options
1029 list all available commands and options
1016 debugcomplete
1030 debugcomplete
1017 returns the completion list associated with the given command
1031 returns the completion list associated with the given command
1018 debugcreatestreamclonebundle
1032 debugcreatestreamclonebundle
1019 create a stream clone bundle file
1033 create a stream clone bundle file
1020 debugdag format the changelog or an index DAG as a concise textual
1034 debugdag format the changelog or an index DAG as a concise textual
1021 description
1035 description
1022 debugdata dump the contents of a data file revision
1036 debugdata dump the contents of a data file revision
1023 debugdate parse and display a date
1037 debugdate parse and display a date
1024 debugdeltachain
1038 debugdeltachain
1025 dump information about delta chains in a revlog
1039 dump information about delta chains in a revlog
1026 debugdirstate
1040 debugdirstate
1027 show the contents of the current dirstate
1041 show the contents of the current dirstate
1028 debugdirstateignorepatternshash
1042 debugdirstateignorepatternshash
1029 show the hash of ignore patterns stored in dirstate if v2,
1043 show the hash of ignore patterns stored in dirstate if v2,
1030 debugdiscovery
1044 debugdiscovery
1031 runs the changeset discovery protocol in isolation
1045 runs the changeset discovery protocol in isolation
1032 debugdownload
1046 debugdownload
1033 download a resource using Mercurial logic and config
1047 download a resource using Mercurial logic and config
1034 debugextensions
1048 debugextensions
1035 show information about active extensions
1049 show information about active extensions
1036 debugfileset parse and apply a fileset specification
1050 debugfileset parse and apply a fileset specification
1037 debugformat display format information about the current repository
1051 debugformat display format information about the current repository
1038 debugfsinfo show information detected about current filesystem
1052 debugfsinfo show information detected about current filesystem
1039 debuggetbundle
1053 debuggetbundle
1040 retrieves a bundle from a repo
1054 retrieves a bundle from a repo
1041 debugignore display the combined ignore pattern and information about
1055 debugignore display the combined ignore pattern and information about
1042 ignored files
1056 ignored files
1043 debugindexdot
1057 debugindexdot
1044 dump an index DAG as a graphviz dot file
1058 dump an index DAG as a graphviz dot file
1045 debugindexstats
1059 debugindexstats
1046 show stats related to the changelog index
1060 show stats related to the changelog index
1047 debuginstall test Mercurial installation
1061 debuginstall test Mercurial installation
1048 debugknown test whether node ids are known to a repo
1062 debugknown test whether node ids are known to a repo
1049 debuglocks show or modify state of locks
1063 debuglocks show or modify state of locks
1050 debugmanifestfulltextcache
1064 debugmanifestfulltextcache
1051 show, clear or amend the contents of the manifest fulltext
1065 show, clear or amend the contents of the manifest fulltext
1052 cache
1066 cache
1053 debugmergestate
1067 debugmergestate
1054 print merge state
1068 print merge state
1055 debugnamecomplete
1069 debugnamecomplete
1056 complete "names" - tags, open branch names, bookmark names
1070 complete "names" - tags, open branch names, bookmark names
1057 debugnodemap write and inspect on disk nodemap
1071 debugnodemap write and inspect on disk nodemap
1058 debugobsolete
1072 debugobsolete
1059 create arbitrary obsolete marker
1073 create arbitrary obsolete marker
1060 debugoptADV (no help text available)
1074 debugoptADV (no help text available)
1061 debugoptDEP (no help text available)
1075 debugoptDEP (no help text available)
1062 debugoptEXP (no help text available)
1076 debugoptEXP (no help text available)
1063 debugp1copies
1077 debugp1copies
1064 dump copy information compared to p1
1078 dump copy information compared to p1
1065 debugp2copies
1079 debugp2copies
1066 dump copy information compared to p2
1080 dump copy information compared to p2
1067 debugpathcomplete
1081 debugpathcomplete
1068 complete part or all of a tracked path
1082 complete part or all of a tracked path
1069 debugpathcopies
1083 debugpathcopies
1070 show copies between two revisions
1084 show copies between two revisions
1071 debugpeer establish a connection to a peer repository
1085 debugpeer establish a connection to a peer repository
1072 debugpickmergetool
1086 debugpickmergetool
1073 examine which merge tool is chosen for specified file
1087 examine which merge tool is chosen for specified file
1074 debugpushkey access the pushkey key/value protocol
1088 debugpushkey access the pushkey key/value protocol
1075 debugpvec (no help text available)
1089 debugpvec (no help text available)
1076 debugrebuilddirstate
1090 debugrebuilddirstate
1077 rebuild the dirstate as it would look like for the given
1091 rebuild the dirstate as it would look like for the given
1078 revision
1092 revision
1079 debugrebuildfncache
1093 debugrebuildfncache
1080 rebuild the fncache file
1094 rebuild the fncache file
1081 debugrename dump rename information
1095 debugrename dump rename information
1082 debugrequires
1096 debugrequires
1083 print the current repo requirements
1097 print the current repo requirements
1084 debugrevlog show data and statistics about a revlog
1098 debugrevlog show data and statistics about a revlog
1085 debugrevlogindex
1099 debugrevlogindex
1086 dump the contents of a revlog index
1100 dump the contents of a revlog index
1087 debugrevspec parse and apply a revision specification
1101 debugrevspec parse and apply a revision specification
1088 debugserve run a server with advanced settings
1102 debugserve run a server with advanced settings
1089 debugsetparents
1103 debugsetparents
1090 manually set the parents of the current working directory
1104 manually set the parents of the current working directory
1091 (DANGEROUS)
1105 (DANGEROUS)
1092 debugshell run an interactive Python interpreter
1106 debugshell run an interactive Python interpreter
1093 debugsidedata
1107 debugsidedata
1094 dump the side data for a cl/manifest/file revision
1108 dump the side data for a cl/manifest/file revision
1095 debugssl test a secure connection to a server
1109 debugssl test a secure connection to a server
1096 debugstrip strip changesets and all their descendants from the repository
1110 debugstrip strip changesets and all their descendants from the repository
1097 debugsub (no help text available)
1111 debugsub (no help text available)
1098 debugsuccessorssets
1112 debugsuccessorssets
1099 show set of successors for revision
1113 show set of successors for revision
1100 debugtagscache
1114 debugtagscache
1101 display the contents of .hg/cache/hgtagsfnodes1
1115 display the contents of .hg/cache/hgtagsfnodes1
1102 debugtemplate
1116 debugtemplate
1103 parse and apply a template
1117 parse and apply a template
1104 debuguigetpass
1118 debuguigetpass
1105 show prompt to type password
1119 show prompt to type password
1106 debuguiprompt
1120 debuguiprompt
1107 show plain prompt
1121 show plain prompt
1108 debugupdatecaches
1122 debugupdatecaches
1109 warm all known caches in the repository
1123 warm all known caches in the repository
1110 debugupgraderepo
1124 debugupgraderepo
1111 upgrade a repository to use different features
1125 upgrade a repository to use different features
1112 debugwalk show how files match on given patterns
1126 debugwalk show how files match on given patterns
1113 debugwhyunstable
1127 debugwhyunstable
1114 explain instabilities of a changeset
1128 explain instabilities of a changeset
1115 debugwireargs
1129 debugwireargs
1116 (no help text available)
1130 (no help text available)
1117 debugwireproto
1131 debugwireproto
1118 send wire protocol commands to a server
1132 send wire protocol commands to a server
1119
1133
1120 (use 'hg help -v debug' to show built-in aliases and global options)
1134 (use 'hg help -v debug' to show built-in aliases and global options)
1121
1135
1122 internals topic renders index of available sub-topics
1136 internals topic renders index of available sub-topics
1123
1137
1124 $ hg help internals
1138 $ hg help internals
1125 Technical implementation topics
1139 Technical implementation topics
1126 """""""""""""""""""""""""""""""
1140 """""""""""""""""""""""""""""""
1127
1141
1128 To access a subtopic, use "hg help internals.{subtopic-name}"
1142 To access a subtopic, use "hg help internals.{subtopic-name}"
1129
1143
1130 bid-merge Bid Merge Algorithm
1144 bid-merge Bid Merge Algorithm
1131 bundle2 Bundle2
1145 bundle2 Bundle2
1132 bundles Bundles
1146 bundles Bundles
1133 cbor CBOR
1147 cbor CBOR
1134 censor Censor
1148 censor Censor
1135 changegroups Changegroups
1149 changegroups Changegroups
1136 config Config Registrar
1150 config Config Registrar
1137 dirstate-v2 dirstate-v2 file format
1151 dirstate-v2 dirstate-v2 file format
1138 extensions Extension API
1152 extensions Extension API
1139 mergestate Mergestate
1153 mergestate Mergestate
1140 requirements Repository Requirements
1154 requirements Repository Requirements
1141 revlogs Revision Logs
1155 revlogs Revision Logs
1142 wireprotocol Wire Protocol
1156 wireprotocol Wire Protocol
1143 wireprotocolrpc
1157 wireprotocolrpc
1144 Wire Protocol RPC
1158 Wire Protocol RPC
1145 wireprotocolv2
1159 wireprotocolv2
1146 Wire Protocol Version 2
1160 Wire Protocol Version 2
1147
1161
1148 sub-topics can be accessed
1162 sub-topics can be accessed
1149
1163
1150 $ hg help internals.changegroups
1164 $ hg help internals.changegroups
1151 Changegroups
1165 Changegroups
1152 """"""""""""
1166 """"""""""""
1153
1167
1154 Changegroups are representations of repository revlog data, specifically
1168 Changegroups are representations of repository revlog data, specifically
1155 the changelog data, root/flat manifest data, treemanifest data, and
1169 the changelog data, root/flat manifest data, treemanifest data, and
1156 filelogs.
1170 filelogs.
1157
1171
1158 There are 4 versions of changegroups: "1", "2", "3" and "4". From a high-
1172 There are 4 versions of changegroups: "1", "2", "3" and "4". From a high-
1159 level, versions "1" and "2" are almost exactly the same, with the only
1173 level, versions "1" and "2" are almost exactly the same, with the only
1160 difference being an additional item in the *delta header*. Version "3"
1174 difference being an additional item in the *delta header*. Version "3"
1161 adds support for storage flags in the *delta header* and optionally
1175 adds support for storage flags in the *delta header* and optionally
1162 exchanging treemanifests (enabled by setting an option on the
1176 exchanging treemanifests (enabled by setting an option on the
1163 "changegroup" part in the bundle2). Version "4" adds support for
1177 "changegroup" part in the bundle2). Version "4" adds support for
1164 exchanging sidedata (additional revision metadata not part of the digest).
1178 exchanging sidedata (additional revision metadata not part of the digest).
1165
1179
1166 Changegroups when not exchanging treemanifests consist of 3 logical
1180 Changegroups when not exchanging treemanifests consist of 3 logical
1167 segments:
1181 segments:
1168
1182
1169 +---------------------------------+
1183 +---------------------------------+
1170 | | | |
1184 | | | |
1171 | changeset | manifest | filelogs |
1185 | changeset | manifest | filelogs |
1172 | | | |
1186 | | | |
1173 | | | |
1187 | | | |
1174 +---------------------------------+
1188 +---------------------------------+
1175
1189
1176 When exchanging treemanifests, there are 4 logical segments:
1190 When exchanging treemanifests, there are 4 logical segments:
1177
1191
1178 +-------------------------------------------------+
1192 +-------------------------------------------------+
1179 | | | | |
1193 | | | | |
1180 | changeset | root | treemanifests | filelogs |
1194 | changeset | root | treemanifests | filelogs |
1181 | | manifest | | |
1195 | | manifest | | |
1182 | | | | |
1196 | | | | |
1183 +-------------------------------------------------+
1197 +-------------------------------------------------+
1184
1198
1185 The principle building block of each segment is a *chunk*. A *chunk* is a
1199 The principle building block of each segment is a *chunk*. A *chunk* is a
1186 framed piece of data:
1200 framed piece of data:
1187
1201
1188 +---------------------------------------+
1202 +---------------------------------------+
1189 | | |
1203 | | |
1190 | length | data |
1204 | length | data |
1191 | (4 bytes) | (<length - 4> bytes) |
1205 | (4 bytes) | (<length - 4> bytes) |
1192 | | |
1206 | | |
1193 +---------------------------------------+
1207 +---------------------------------------+
1194
1208
1195 All integers are big-endian signed integers. Each chunk starts with a
1209 All integers are big-endian signed integers. Each chunk starts with a
1196 32-bit integer indicating the length of the entire chunk (including the
1210 32-bit integer indicating the length of the entire chunk (including the
1197 length field itself).
1211 length field itself).
1198
1212
1199 There is a special case chunk that has a value of 0 for the length
1213 There is a special case chunk that has a value of 0 for the length
1200 ("0x00000000"). We call this an *empty chunk*.
1214 ("0x00000000"). We call this an *empty chunk*.
1201
1215
1202 Delta Groups
1216 Delta Groups
1203 ============
1217 ============
1204
1218
1205 A *delta group* expresses the content of a revlog as a series of deltas,
1219 A *delta group* expresses the content of a revlog as a series of deltas,
1206 or patches against previous revisions.
1220 or patches against previous revisions.
1207
1221
1208 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1222 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1209 to signal the end of the delta group:
1223 to signal the end of the delta group:
1210
1224
1211 +------------------------------------------------------------------------+
1225 +------------------------------------------------------------------------+
1212 | | | | | |
1226 | | | | | |
1213 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1227 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1214 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1228 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1215 | | | | | |
1229 | | | | | |
1216 +------------------------------------------------------------------------+
1230 +------------------------------------------------------------------------+
1217
1231
1218 Each *chunk*'s data consists of the following:
1232 Each *chunk*'s data consists of the following:
1219
1233
1220 +---------------------------------------+
1234 +---------------------------------------+
1221 | | |
1235 | | |
1222 | delta header | delta data |
1236 | delta header | delta data |
1223 | (various by version) | (various) |
1237 | (various by version) | (various) |
1224 | | |
1238 | | |
1225 +---------------------------------------+
1239 +---------------------------------------+
1226
1240
1227 The *delta data* is a series of *delta*s that describe a diff from an
1241 The *delta data* is a series of *delta*s that describe a diff from an
1228 existing entry (either that the recipient already has, or previously
1242 existing entry (either that the recipient already has, or previously
1229 specified in the bundle/changegroup).
1243 specified in the bundle/changegroup).
1230
1244
1231 The *delta header* is different between versions "1", "2", "3" and "4" of
1245 The *delta header* is different between versions "1", "2", "3" and "4" of
1232 the changegroup format.
1246 the changegroup format.
1233
1247
1234 Version 1 (headerlen=80):
1248 Version 1 (headerlen=80):
1235
1249
1236 +------------------------------------------------------+
1250 +------------------------------------------------------+
1237 | | | | |
1251 | | | | |
1238 | node | p1 node | p2 node | link node |
1252 | node | p1 node | p2 node | link node |
1239 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1253 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1240 | | | | |
1254 | | | | |
1241 +------------------------------------------------------+
1255 +------------------------------------------------------+
1242
1256
1243 Version 2 (headerlen=100):
1257 Version 2 (headerlen=100):
1244
1258
1245 +------------------------------------------------------------------+
1259 +------------------------------------------------------------------+
1246 | | | | | |
1260 | | | | | |
1247 | node | p1 node | p2 node | base node | link node |
1261 | node | p1 node | p2 node | base node | link node |
1248 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1262 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1249 | | | | | |
1263 | | | | | |
1250 +------------------------------------------------------------------+
1264 +------------------------------------------------------------------+
1251
1265
1252 Version 3 (headerlen=102):
1266 Version 3 (headerlen=102):
1253
1267
1254 +------------------------------------------------------------------------------+
1268 +------------------------------------------------------------------------------+
1255 | | | | | | |
1269 | | | | | | |
1256 | node | p1 node | p2 node | base node | link node | flags |
1270 | node | p1 node | p2 node | base node | link node | flags |
1257 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1271 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1258 | | | | | | |
1272 | | | | | | |
1259 +------------------------------------------------------------------------------+
1273 +------------------------------------------------------------------------------+
1260
1274
1261 Version 4 (headerlen=103):
1275 Version 4 (headerlen=103):
1262
1276
1263 +------------------------------------------------------------------------------+----------+
1277 +------------------------------------------------------------------------------+----------+
1264 | | | | | | | |
1278 | | | | | | | |
1265 | node | p1 node | p2 node | base node | link node | flags | pflags |
1279 | node | p1 node | p2 node | base node | link node | flags | pflags |
1266 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) | (1 byte) |
1280 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) | (1 byte) |
1267 | | | | | | | |
1281 | | | | | | | |
1268 +------------------------------------------------------------------------------+----------+
1282 +------------------------------------------------------------------------------+----------+
1269
1283
1270 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1284 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1271 contain a series of *delta*s, densely packed (no separators). These deltas
1285 contain a series of *delta*s, densely packed (no separators). These deltas
1272 describe a diff from an existing entry (either that the recipient already
1286 describe a diff from an existing entry (either that the recipient already
1273 has, or previously specified in the bundle/changegroup). The format is
1287 has, or previously specified in the bundle/changegroup). The format is
1274 described more fully in "hg help internals.bdiff", but briefly:
1288 described more fully in "hg help internals.bdiff", but briefly:
1275
1289
1276 +---------------------------------------------------------------+
1290 +---------------------------------------------------------------+
1277 | | | | |
1291 | | | | |
1278 | start offset | end offset | new length | content |
1292 | start offset | end offset | new length | content |
1279 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1293 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1280 | | | | |
1294 | | | | |
1281 +---------------------------------------------------------------+
1295 +---------------------------------------------------------------+
1282
1296
1283 Please note that the length field in the delta data does *not* include
1297 Please note that the length field in the delta data does *not* include
1284 itself.
1298 itself.
1285
1299
1286 In version 1, the delta is always applied against the previous node from
1300 In version 1, the delta is always applied against the previous node from
1287 the changegroup or the first parent if this is the first entry in the
1301 the changegroup or the first parent if this is the first entry in the
1288 changegroup.
1302 changegroup.
1289
1303
1290 In version 2 and up, the delta base node is encoded in the entry in the
1304 In version 2 and up, the delta base node is encoded in the entry in the
1291 changegroup. This allows the delta to be expressed against any parent,
1305 changegroup. This allows the delta to be expressed against any parent,
1292 which can result in smaller deltas and more efficient encoding of data.
1306 which can result in smaller deltas and more efficient encoding of data.
1293
1307
1294 The *flags* field holds bitwise flags affecting the processing of revision
1308 The *flags* field holds bitwise flags affecting the processing of revision
1295 data. The following flags are defined:
1309 data. The following flags are defined:
1296
1310
1297 32768
1311 32768
1298 Censored revision. The revision's fulltext has been replaced by censor
1312 Censored revision. The revision's fulltext has been replaced by censor
1299 metadata. May only occur on file revisions.
1313 metadata. May only occur on file revisions.
1300
1314
1301 16384
1315 16384
1302 Ellipsis revision. Revision hash does not match data (likely due to
1316 Ellipsis revision. Revision hash does not match data (likely due to
1303 rewritten parents).
1317 rewritten parents).
1304
1318
1305 8192
1319 8192
1306 Externally stored. The revision fulltext contains "key:value" "\n"
1320 Externally stored. The revision fulltext contains "key:value" "\n"
1307 delimited metadata defining an object stored elsewhere. Used by the LFS
1321 delimited metadata defining an object stored elsewhere. Used by the LFS
1308 extension.
1322 extension.
1309
1323
1310 4096
1324 4096
1311 Contains copy information. This revision changes files in a way that
1325 Contains copy information. This revision changes files in a way that
1312 could affect copy tracing. This does *not* affect changegroup handling,
1326 could affect copy tracing. This does *not* affect changegroup handling,
1313 but is relevant for other parts of Mercurial.
1327 but is relevant for other parts of Mercurial.
1314
1328
1315 For historical reasons, the integer values are identical to revlog version
1329 For historical reasons, the integer values are identical to revlog version
1316 1 per-revision storage flags and correspond to bits being set in this
1330 1 per-revision storage flags and correspond to bits being set in this
1317 2-byte field. Bits were allocated starting from the most-significant bit,
1331 2-byte field. Bits were allocated starting from the most-significant bit,
1318 hence the reverse ordering and allocation of these flags.
1332 hence the reverse ordering and allocation of these flags.
1319
1333
1320 The *pflags* (protocol flags) field holds bitwise flags affecting the
1334 The *pflags* (protocol flags) field holds bitwise flags affecting the
1321 protocol itself. They are first in the header since they may affect the
1335 protocol itself. They are first in the header since they may affect the
1322 handling of the rest of the fields in a future version. They are defined
1336 handling of the rest of the fields in a future version. They are defined
1323 as such:
1337 as such:
1324
1338
1325 1 indicates whether to read a chunk of sidedata (of variable length) right
1339 1 indicates whether to read a chunk of sidedata (of variable length) right
1326 after the revision flags.
1340 after the revision flags.
1327
1341
1328 Changeset Segment
1342 Changeset Segment
1329 =================
1343 =================
1330
1344
1331 The *changeset segment* consists of a single *delta group* holding
1345 The *changeset segment* consists of a single *delta group* holding
1332 changelog data. The *empty chunk* at the end of the *delta group* denotes
1346 changelog data. The *empty chunk* at the end of the *delta group* denotes
1333 the boundary to the *manifest segment*.
1347 the boundary to the *manifest segment*.
1334
1348
1335 Manifest Segment
1349 Manifest Segment
1336 ================
1350 ================
1337
1351
1338 The *manifest segment* consists of a single *delta group* holding manifest
1352 The *manifest segment* consists of a single *delta group* holding manifest
1339 data. If treemanifests are in use, it contains only the manifest for the
1353 data. If treemanifests are in use, it contains only the manifest for the
1340 root directory of the repository. Otherwise, it contains the entire
1354 root directory of the repository. Otherwise, it contains the entire
1341 manifest data. The *empty chunk* at the end of the *delta group* denotes
1355 manifest data. The *empty chunk* at the end of the *delta group* denotes
1342 the boundary to the next segment (either the *treemanifests segment* or
1356 the boundary to the next segment (either the *treemanifests segment* or
1343 the *filelogs segment*, depending on version and the request options).
1357 the *filelogs segment*, depending on version and the request options).
1344
1358
1345 Treemanifests Segment
1359 Treemanifests Segment
1346 ---------------------
1360 ---------------------
1347
1361
1348 The *treemanifests segment* only exists in changegroup version "3" and
1362 The *treemanifests segment* only exists in changegroup version "3" and
1349 "4", and only if the 'treemanifest' param is part of the bundle2
1363 "4", and only if the 'treemanifest' param is part of the bundle2
1350 changegroup part (it is not possible to use changegroup version 3 or 4
1364 changegroup part (it is not possible to use changegroup version 3 or 4
1351 outside of bundle2). Aside from the filenames in the *treemanifests
1365 outside of bundle2). Aside from the filenames in the *treemanifests
1352 segment* containing a trailing "/" character, it behaves identically to
1366 segment* containing a trailing "/" character, it behaves identically to
1353 the *filelogs segment* (see below). The final sub-segment is followed by
1367 the *filelogs segment* (see below). The final sub-segment is followed by
1354 an *empty chunk* (logically, a sub-segment with filename size 0). This
1368 an *empty chunk* (logically, a sub-segment with filename size 0). This
1355 denotes the boundary to the *filelogs segment*.
1369 denotes the boundary to the *filelogs segment*.
1356
1370
1357 Filelogs Segment
1371 Filelogs Segment
1358 ================
1372 ================
1359
1373
1360 The *filelogs segment* consists of multiple sub-segments, each
1374 The *filelogs segment* consists of multiple sub-segments, each
1361 corresponding to an individual file whose data is being described:
1375 corresponding to an individual file whose data is being described:
1362
1376
1363 +--------------------------------------------------+
1377 +--------------------------------------------------+
1364 | | | | | |
1378 | | | | | |
1365 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1379 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1366 | | | | | (4 bytes) |
1380 | | | | | (4 bytes) |
1367 | | | | | |
1381 | | | | | |
1368 +--------------------------------------------------+
1382 +--------------------------------------------------+
1369
1383
1370 The final filelog sub-segment is followed by an *empty chunk* (logically,
1384 The final filelog sub-segment is followed by an *empty chunk* (logically,
1371 a sub-segment with filename size 0). This denotes the end of the segment
1385 a sub-segment with filename size 0). This denotes the end of the segment
1372 and of the overall changegroup.
1386 and of the overall changegroup.
1373
1387
1374 Each filelog sub-segment consists of the following:
1388 Each filelog sub-segment consists of the following:
1375
1389
1376 +------------------------------------------------------+
1390 +------------------------------------------------------+
1377 | | | |
1391 | | | |
1378 | filename length | filename | delta group |
1392 | filename length | filename | delta group |
1379 | (4 bytes) | (<length - 4> bytes) | (various) |
1393 | (4 bytes) | (<length - 4> bytes) | (various) |
1380 | | | |
1394 | | | |
1381 +------------------------------------------------------+
1395 +------------------------------------------------------+
1382
1396
1383 That is, a *chunk* consisting of the filename (not terminated or padded)
1397 That is, a *chunk* consisting of the filename (not terminated or padded)
1384 followed by N chunks constituting the *delta group* for this file. The
1398 followed by N chunks constituting the *delta group* for this file. The
1385 *empty chunk* at the end of each *delta group* denotes the boundary to the
1399 *empty chunk* at the end of each *delta group* denotes the boundary to the
1386 next filelog sub-segment.
1400 next filelog sub-segment.
1387
1401
1388 non-existent subtopics print an error
1402 non-existent subtopics print an error
1389
1403
1390 $ hg help internals.foo
1404 $ hg help internals.foo
1391 abort: no such help topic: internals.foo
1405 abort: no such help topic: internals.foo
1392 (try 'hg help --keyword foo')
1406 (try 'hg help --keyword foo')
1393 [10]
1407 [10]
1394
1408
1395 test advanced, deprecated and experimental options are hidden in command help
1409 test advanced, deprecated and experimental options are hidden in command help
1396 $ hg help debugoptADV
1410 $ hg help debugoptADV
1397 hg debugoptADV
1411 hg debugoptADV
1398
1412
1399 (no help text available)
1413 (no help text available)
1400
1414
1401 options:
1415 options:
1402
1416
1403 (some details hidden, use --verbose to show complete help)
1417 (some details hidden, use --verbose to show complete help)
1404 $ hg help debugoptDEP
1418 $ hg help debugoptDEP
1405 hg debugoptDEP
1419 hg debugoptDEP
1406
1420
1407 (no help text available)
1421 (no help text available)
1408
1422
1409 options:
1423 options:
1410
1424
1411 (some details hidden, use --verbose to show complete help)
1425 (some details hidden, use --verbose to show complete help)
1412
1426
1413 $ hg help debugoptEXP
1427 $ hg help debugoptEXP
1414 hg debugoptEXP
1428 hg debugoptEXP
1415
1429
1416 (no help text available)
1430 (no help text available)
1417
1431
1418 options:
1432 options:
1419
1433
1420 (some details hidden, use --verbose to show complete help)
1434 (some details hidden, use --verbose to show complete help)
1421
1435
1422 test advanced, deprecated and experimental options are shown with -v
1436 test advanced, deprecated and experimental options are shown with -v
1423 $ hg help -v debugoptADV | grep aopt
1437 $ hg help -v debugoptADV | grep aopt
1424 --aopt option is (ADVANCED)
1438 --aopt option is (ADVANCED)
1425 $ hg help -v debugoptDEP | grep dopt
1439 $ hg help -v debugoptDEP | grep dopt
1426 --dopt option is (DEPRECATED)
1440 --dopt option is (DEPRECATED)
1427 $ hg help -v debugoptEXP | grep eopt
1441 $ hg help -v debugoptEXP | grep eopt
1428 --eopt option is (EXPERIMENTAL)
1442 --eopt option is (EXPERIMENTAL)
1429
1443
1430 #if gettext
1444 #if gettext
1431 test deprecated option is hidden with translation with untranslated description
1445 test deprecated option is hidden with translation with untranslated description
1432 (use many globy for not failing on changed transaction)
1446 (use many globy for not failing on changed transaction)
1433 $ LANGUAGE=sv hg help debugoptDEP
1447 $ LANGUAGE=sv hg help debugoptDEP
1434 hg debugoptDEP
1448 hg debugoptDEP
1435
1449
1436 (*) (glob)
1450 (*) (glob)
1437
1451
1438 options:
1452 options:
1439
1453
1440 (some details hidden, use --verbose to show complete help)
1454 (some details hidden, use --verbose to show complete help)
1441 #endif
1455 #endif
1442
1456
1443 Test commands that collide with topics (issue4240)
1457 Test commands that collide with topics (issue4240)
1444
1458
1445 $ hg config -hq
1459 $ hg config -hq
1446 hg config [-u] [NAME]...
1460 hg config [-u] [NAME]...
1447
1461
1448 show combined config settings from all hgrc files
1462 show combined config settings from all hgrc files
1449 $ hg showconfig -hq
1463 $ hg showconfig -hq
1450 hg config [-u] [NAME]...
1464 hg config [-u] [NAME]...
1451
1465
1452 show combined config settings from all hgrc files
1466 show combined config settings from all hgrc files
1453
1467
1454 Test a help topic
1468 Test a help topic
1455
1469
1456 $ hg help dates
1470 $ hg help dates
1457 Date Formats
1471 Date Formats
1458 """"""""""""
1472 """"""""""""
1459
1473
1460 Some commands allow the user to specify a date, e.g.:
1474 Some commands allow the user to specify a date, e.g.:
1461
1475
1462 - backout, commit, import, tag: Specify the commit date.
1476 - backout, commit, import, tag: Specify the commit date.
1463 - log, revert, update: Select revision(s) by date.
1477 - log, revert, update: Select revision(s) by date.
1464
1478
1465 Many date formats are valid. Here are some examples:
1479 Many date formats are valid. Here are some examples:
1466
1480
1467 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1481 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1468 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1482 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1469 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1483 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1470 - "Dec 6" (midnight)
1484 - "Dec 6" (midnight)
1471 - "13:18" (today assumed)
1485 - "13:18" (today assumed)
1472 - "3:39" (3:39AM assumed)
1486 - "3:39" (3:39AM assumed)
1473 - "3:39pm" (15:39)
1487 - "3:39pm" (15:39)
1474 - "2006-12-06 13:18:29" (ISO 8601 format)
1488 - "2006-12-06 13:18:29" (ISO 8601 format)
1475 - "2006-12-6 13:18"
1489 - "2006-12-6 13:18"
1476 - "2006-12-6"
1490 - "2006-12-6"
1477 - "12-6"
1491 - "12-6"
1478 - "12/6"
1492 - "12/6"
1479 - "12/6/6" (Dec 6 2006)
1493 - "12/6/6" (Dec 6 2006)
1480 - "today" (midnight)
1494 - "today" (midnight)
1481 - "yesterday" (midnight)
1495 - "yesterday" (midnight)
1482 - "now" - right now
1496 - "now" - right now
1483
1497
1484 Lastly, there is Mercurial's internal format:
1498 Lastly, there is Mercurial's internal format:
1485
1499
1486 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1500 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1487
1501
1488 This is the internal representation format for dates. The first number is
1502 This is the internal representation format for dates. The first number is
1489 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1503 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1490 is the offset of the local timezone, in seconds west of UTC (negative if
1504 is the offset of the local timezone, in seconds west of UTC (negative if
1491 the timezone is east of UTC).
1505 the timezone is east of UTC).
1492
1506
1493 The log command also accepts date ranges:
1507 The log command also accepts date ranges:
1494
1508
1495 - "<DATE" - at or before a given date/time
1509 - "<DATE" - at or before a given date/time
1496 - ">DATE" - on or after a given date/time
1510 - ">DATE" - on or after a given date/time
1497 - "DATE to DATE" - a date range, inclusive
1511 - "DATE to DATE" - a date range, inclusive
1498 - "-DAYS" - within a given number of days from today
1512 - "-DAYS" - within a given number of days from today
1499
1513
1500 Test repeated config section name
1514 Test repeated config section name
1501
1515
1502 $ hg help config.host
1516 $ hg help config.host
1503 "http_proxy.host"
1517 "http_proxy.host"
1504 Host name and (optional) port of the proxy server, for example
1518 Host name and (optional) port of the proxy server, for example
1505 "myproxy:8000".
1519 "myproxy:8000".
1506
1520
1507 "smtp.host"
1521 "smtp.host"
1508 Host name of mail server, e.g. "mail.example.com".
1522 Host name of mail server, e.g. "mail.example.com".
1509
1523
1510
1524
1511 Test section name with dot
1525 Test section name with dot
1512
1526
1513 $ hg help config.ui.username
1527 $ hg help config.ui.username
1514 "ui.username"
1528 "ui.username"
1515 The committer of a changeset created when running "commit". Typically
1529 The committer of a changeset created when running "commit". Typically
1516 a person's name and email address, e.g. "Fred Widget
1530 a person's name and email address, e.g. "Fred Widget
1517 <fred@example.com>". Environment variables in the username are
1531 <fred@example.com>". Environment variables in the username are
1518 expanded.
1532 expanded.
1519
1533
1520 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1534 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1521 empty, e.g. if the system admin set "username =" in the system hgrc,
1535 empty, e.g. if the system admin set "username =" in the system hgrc,
1522 it has to be specified manually or in a different hgrc file)
1536 it has to be specified manually or in a different hgrc file)
1523
1537
1524
1538
1525 $ hg help config.annotate.git
1539 $ hg help config.annotate.git
1526 abort: help section not found: config.annotate.git
1540 abort: help section not found: config.annotate.git
1527 [10]
1541 [10]
1528
1542
1529 $ hg help config.update.check
1543 $ hg help config.update.check
1530 "commands.update.check"
1544 "commands.update.check"
1531 Determines what level of checking 'hg update' will perform before
1545 Determines what level of checking 'hg update' will perform before
1532 moving to a destination revision. Valid values are "abort", "none",
1546 moving to a destination revision. Valid values are "abort", "none",
1533 "linear", and "noconflict".
1547 "linear", and "noconflict".
1534
1548
1535 - "abort" always fails if the working directory has uncommitted
1549 - "abort" always fails if the working directory has uncommitted
1536 changes.
1550 changes.
1537 - "none" performs no checking, and may result in a merge with
1551 - "none" performs no checking, and may result in a merge with
1538 uncommitted changes.
1552 uncommitted changes.
1539 - "linear" allows any update as long as it follows a straight line in
1553 - "linear" allows any update as long as it follows a straight line in
1540 the revision history, and may trigger a merge with uncommitted
1554 the revision history, and may trigger a merge with uncommitted
1541 changes.
1555 changes.
1542 - "noconflict" will allow any update which would not trigger a merge
1556 - "noconflict" will allow any update which would not trigger a merge
1543 with uncommitted changes, if any are present.
1557 with uncommitted changes, if any are present.
1544
1558
1545 (default: "linear")
1559 (default: "linear")
1546
1560
1547
1561
1548 $ hg help config.commands.update.check
1562 $ hg help config.commands.update.check
1549 "commands.update.check"
1563 "commands.update.check"
1550 Determines what level of checking 'hg update' will perform before
1564 Determines what level of checking 'hg update' will perform before
1551 moving to a destination revision. Valid values are "abort", "none",
1565 moving to a destination revision. Valid values are "abort", "none",
1552 "linear", and "noconflict".
1566 "linear", and "noconflict".
1553
1567
1554 - "abort" always fails if the working directory has uncommitted
1568 - "abort" always fails if the working directory has uncommitted
1555 changes.
1569 changes.
1556 - "none" performs no checking, and may result in a merge with
1570 - "none" performs no checking, and may result in a merge with
1557 uncommitted changes.
1571 uncommitted changes.
1558 - "linear" allows any update as long as it follows a straight line in
1572 - "linear" allows any update as long as it follows a straight line in
1559 the revision history, and may trigger a merge with uncommitted
1573 the revision history, and may trigger a merge with uncommitted
1560 changes.
1574 changes.
1561 - "noconflict" will allow any update which would not trigger a merge
1575 - "noconflict" will allow any update which would not trigger a merge
1562 with uncommitted changes, if any are present.
1576 with uncommitted changes, if any are present.
1563
1577
1564 (default: "linear")
1578 (default: "linear")
1565
1579
1566
1580
1567 $ hg help config.ommands.update.check
1581 $ hg help config.ommands.update.check
1568 abort: help section not found: config.ommands.update.check
1582 abort: help section not found: config.ommands.update.check
1569 [10]
1583 [10]
1570
1584
1571 Unrelated trailing paragraphs shouldn't be included
1585 Unrelated trailing paragraphs shouldn't be included
1572
1586
1573 $ hg help config.extramsg | grep '^$'
1587 $ hg help config.extramsg | grep '^$'
1574
1588
1575
1589
1576 Test capitalized section name
1590 Test capitalized section name
1577
1591
1578 $ hg help scripting.HGPLAIN > /dev/null
1592 $ hg help scripting.HGPLAIN > /dev/null
1579
1593
1580 Help subsection:
1594 Help subsection:
1581
1595
1582 $ hg help config.charsets |grep "Email example:" > /dev/null
1596 $ hg help config.charsets |grep "Email example:" > /dev/null
1583 [1]
1597 [1]
1584
1598
1585 Show nested definitions
1599 Show nested definitions
1586 ("profiling.type"[break]"ls"[break]"stat"[break])
1600 ("profiling.type"[break]"ls"[break]"stat"[break])
1587
1601
1588 $ hg help config.type | grep -E '^$'|wc -l
1602 $ hg help config.type | grep -E '^$'|wc -l
1589 \s*3 (re)
1603 \s*3 (re)
1590
1604
1591 $ hg help config.profiling.type.ls
1605 $ hg help config.profiling.type.ls
1592 "profiling.type.ls"
1606 "profiling.type.ls"
1593 Use Python's built-in instrumenting profiler. This profiler works on
1607 Use Python's built-in instrumenting profiler. This profiler works on
1594 all platforms, but each line number it reports is the first line of
1608 all platforms, but each line number it reports is the first line of
1595 a function. This restriction makes it difficult to identify the
1609 a function. This restriction makes it difficult to identify the
1596 expensive parts of a non-trivial function.
1610 expensive parts of a non-trivial function.
1597
1611
1598
1612
1599 Separate sections from subsections
1613 Separate sections from subsections
1600
1614
1601 $ hg help config.format | grep -E '^ ("|-)|^\s*$' | uniq
1615 $ hg help config.format | grep -E '^ ("|-)|^\s*$' | uniq
1602 "format"
1616 "format"
1603 --------
1617 --------
1604
1618
1605 "usegeneraldelta"
1619 "usegeneraldelta"
1606
1620
1607 "dotencode"
1621 "dotencode"
1608
1622
1609 "usefncache"
1623 "usefncache"
1610
1624
1611 "use-dirstate-v2"
1625 "use-dirstate-v2"
1612
1626
1613 "use-dirstate-v2.automatic-upgrade-of-mismatching-repositories"
1627 "use-dirstate-v2.automatic-upgrade-of-mismatching-repositories"
1614
1628
1615 "use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet"
1629 "use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet"
1616
1630
1617 "use-dirstate-tracked-hint"
1631 "use-dirstate-tracked-hint"
1618
1632
1619 "use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories"
1633 "use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories"
1620
1634
1621 "use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet"
1635 "use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet"
1622
1636
1623 "use-persistent-nodemap"
1637 "use-persistent-nodemap"
1624
1638
1625 "use-share-safe"
1639 "use-share-safe"
1626
1640
1627 "use-share-safe.automatic-upgrade-of-mismatching-repositories"
1641 "use-share-safe.automatic-upgrade-of-mismatching-repositories"
1628
1642
1629 "use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet"
1643 "use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet"
1630
1644
1631 "usestore"
1645 "usestore"
1632
1646
1633 "sparse-revlog"
1647 "sparse-revlog"
1634
1648
1635 "revlog-compression"
1649 "revlog-compression"
1636
1650
1637 "bookmarks-in-store"
1651 "bookmarks-in-store"
1638
1652
1639 "profiling"
1653 "profiling"
1640 -----------
1654 -----------
1641
1655
1642 "format"
1656 "format"
1643
1657
1644 "progress"
1658 "progress"
1645 ----------
1659 ----------
1646
1660
1647 "format"
1661 "format"
1648
1662
1649
1663
1650 Last item in help config.*:
1664 Last item in help config.*:
1651
1665
1652 $ hg help config.`hg help config|grep '^ "'| \
1666 $ hg help config.`hg help config|grep '^ "'| \
1653 > tail -1|sed 's![ "]*!!g'`| \
1667 > tail -1|sed 's![ "]*!!g'`| \
1654 > grep 'hg help -c config' > /dev/null
1668 > grep 'hg help -c config' > /dev/null
1655 [1]
1669 [1]
1656
1670
1657 note to use help -c for general hg help config:
1671 note to use help -c for general hg help config:
1658
1672
1659 $ hg help config |grep 'hg help -c config' > /dev/null
1673 $ hg help config |grep 'hg help -c config' > /dev/null
1660
1674
1661 Test templating help
1675 Test templating help
1662
1676
1663 $ hg help templating | grep -E '(desc|diffstat|firstline|nonempty) '
1677 $ hg help templating | grep -E '(desc|diffstat|firstline|nonempty) '
1664 desc String. The text of the changeset description.
1678 desc String. The text of the changeset description.
1665 diffstat String. Statistics of changes with the following format:
1679 diffstat String. Statistics of changes with the following format:
1666 firstline Any text. Returns the first line of text.
1680 firstline Any text. Returns the first line of text.
1667 nonempty Any text. Returns '(none)' if the string is empty.
1681 nonempty Any text. Returns '(none)' if the string is empty.
1668
1682
1669 Test deprecated items
1683 Test deprecated items
1670
1684
1671 $ hg help -v templating | grep currentbookmark
1685 $ hg help -v templating | grep currentbookmark
1672 currentbookmark
1686 currentbookmark
1673 $ hg help templating | (grep currentbookmark || true)
1687 $ hg help templating | (grep currentbookmark || true)
1674
1688
1675 Test help hooks
1689 Test help hooks
1676
1690
1677 $ cat > helphook1.py <<EOF
1691 $ cat > helphook1.py <<EOF
1678 > from mercurial import help
1692 > from mercurial import help
1679 >
1693 >
1680 > def rewrite(ui, topic, doc):
1694 > def rewrite(ui, topic, doc):
1681 > return doc + b'\nhelphook1\n'
1695 > return doc + b'\nhelphook1\n'
1682 >
1696 >
1683 > def extsetup(ui):
1697 > def extsetup(ui):
1684 > help.addtopichook(b'revisions', rewrite)
1698 > help.addtopichook(b'revisions', rewrite)
1685 > EOF
1699 > EOF
1686 $ cat > helphook2.py <<EOF
1700 $ cat > helphook2.py <<EOF
1687 > from mercurial import help
1701 > from mercurial import help
1688 >
1702 >
1689 > def rewrite(ui, topic, doc):
1703 > def rewrite(ui, topic, doc):
1690 > return doc + b'\nhelphook2\n'
1704 > return doc + b'\nhelphook2\n'
1691 >
1705 >
1692 > def extsetup(ui):
1706 > def extsetup(ui):
1693 > help.addtopichook(b'revisions', rewrite)
1707 > help.addtopichook(b'revisions', rewrite)
1694 > EOF
1708 > EOF
1695 $ echo '[extensions]' >> $HGRCPATH
1709 $ echo '[extensions]' >> $HGRCPATH
1696 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1710 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1697 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1711 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1698 $ hg help revsets | grep helphook
1712 $ hg help revsets | grep helphook
1699 helphook1
1713 helphook1
1700 helphook2
1714 helphook2
1701
1715
1702 help -c should only show debug --debug
1716 help -c should only show debug --debug
1703
1717
1704 $ hg help -c --debug|grep -E debug|wc -l|grep -E '^\s*0\s*$'
1718 $ hg help -c --debug|grep -E debug|wc -l|grep -E '^\s*0\s*$'
1705 [1]
1719 [1]
1706
1720
1707 help -c should only show deprecated for -v
1721 help -c should only show deprecated for -v
1708
1722
1709 $ hg help -c -v|grep -E DEPRECATED|wc -l|grep -E '^\s*0\s*$'
1723 $ hg help -c -v|grep -E DEPRECATED|wc -l|grep -E '^\s*0\s*$'
1710 [1]
1724 [1]
1711
1725
1712 Test -s / --system
1726 Test -s / --system
1713
1727
1714 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1728 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1715 > wc -l | sed -e 's/ //g'
1729 > wc -l | sed -e 's/ //g'
1716 0
1730 0
1717 $ hg help config.files --system unix | grep 'USER' | \
1731 $ hg help config.files --system unix | grep 'USER' | \
1718 > wc -l | sed -e 's/ //g'
1732 > wc -l | sed -e 's/ //g'
1719 0
1733 0
1720
1734
1721 Test -e / -c / -k combinations
1735 Test -e / -c / -k combinations
1722
1736
1723 $ hg help -c|grep -E '^[A-Z].*:|^ debug'
1737 $ hg help -c|grep -E '^[A-Z].*:|^ debug'
1724 Commands:
1738 Commands:
1725 $ hg help -e|grep -E '^[A-Z].*:|^ debug'
1739 $ hg help -e|grep -E '^[A-Z].*:|^ debug'
1726 Extensions:
1740 Extensions:
1727 $ hg help -k|grep -E '^[A-Z].*:|^ debug'
1741 $ hg help -k|grep -E '^[A-Z].*:|^ debug'
1728 Topics:
1742 Topics:
1729 Commands:
1743 Commands:
1730 Extensions:
1744 Extensions:
1731 Extension Commands:
1745 Extension Commands:
1732 $ hg help -c schemes
1746 $ hg help -c schemes
1733 abort: no such help topic: schemes
1747 abort: no such help topic: schemes
1734 (try 'hg help --keyword schemes')
1748 (try 'hg help --keyword schemes')
1735 [10]
1749 [10]
1736 $ hg help -e schemes |head -1
1750 $ hg help -e schemes |head -1
1737 schemes extension - extend schemes with shortcuts to repository swarms
1751 schemes extension - extend schemes with shortcuts to repository swarms
1738 $ hg help -c -k dates |grep -E '^(Topics|Extensions|Commands):'
1752 $ hg help -c -k dates |grep -E '^(Topics|Extensions|Commands):'
1739 Commands:
1753 Commands:
1740 $ hg help -e -k a |grep -E '^(Topics|Extensions|Commands):'
1754 $ hg help -e -k a |grep -E '^(Topics|Extensions|Commands):'
1741 Extensions:
1755 Extensions:
1742 $ hg help -e -c -k date |grep -E '^(Topics|Extensions|Commands):'
1756 $ hg help -e -c -k date |grep -E '^(Topics|Extensions|Commands):'
1743 Extensions:
1757 Extensions:
1744 Commands:
1758 Commands:
1745 $ hg help -c commit > /dev/null
1759 $ hg help -c commit > /dev/null
1746 $ hg help -e -c commit > /dev/null
1760 $ hg help -e -c commit > /dev/null
1747 $ hg help -e commit
1761 $ hg help -e commit
1748 abort: no such help topic: commit
1762 abort: no such help topic: commit
1749 (try 'hg help --keyword commit')
1763 (try 'hg help --keyword commit')
1750 [10]
1764 [10]
1751
1765
1752 Test keyword search help
1766 Test keyword search help
1753
1767
1754 $ cat > prefixedname.py <<EOF
1768 $ cat > prefixedname.py <<EOF
1755 > '''matched against word "clone"
1769 > '''matched against word "clone"
1756 > '''
1770 > '''
1757 > EOF
1771 > EOF
1758 $ echo '[extensions]' >> $HGRCPATH
1772 $ echo '[extensions]' >> $HGRCPATH
1759 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1773 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1760 $ hg help -k clone
1774 $ hg help -k clone
1761 Topics:
1775 Topics:
1762
1776
1763 config Configuration Files
1777 config Configuration Files
1764 extensions Using Additional Features
1778 extensions Using Additional Features
1765 glossary Glossary
1779 glossary Glossary
1766 phases Working with Phases
1780 phases Working with Phases
1767 subrepos Subrepositories
1781 subrepos Subrepositories
1768 urls URL Paths
1782 urls URL Paths
1769
1783
1770 Commands:
1784 Commands:
1771
1785
1772 bookmarks create a new bookmark or list existing bookmarks
1786 bookmarks create a new bookmark or list existing bookmarks
1773 clone make a copy of an existing repository
1787 clone make a copy of an existing repository
1774 paths show aliases for remote repositories
1788 paths show aliases for remote repositories
1775 pull pull changes from the specified source
1789 pull pull changes from the specified source
1776 update update working directory (or switch revisions)
1790 update update working directory (or switch revisions)
1777
1791
1778 Extensions:
1792 Extensions:
1779
1793
1780 clonebundles advertise pre-generated bundles to seed clones
1794 clonebundles advertise pre-generated bundles to seed clones
1781 narrow create clones which fetch history data for subset of files
1795 narrow create clones which fetch history data for subset of files
1782 (EXPERIMENTAL)
1796 (EXPERIMENTAL)
1783 prefixedname matched against word "clone"
1797 prefixedname matched against word "clone"
1784 relink recreates hardlinks between repository clones
1798 relink recreates hardlinks between repository clones
1785
1799
1786 Extension Commands:
1800 Extension Commands:
1787
1801
1788 admin::clone-bundles-clear remove existing clone bundle caches
1802 admin::clone-bundles-clear remove existing clone bundle caches
1789 admin::clone-bundles-refresh generate clone bundles according to the
1803 admin::clone-bundles-refresh generate clone bundles according to the
1790 configuration
1804 configuration
1791 qclone clone main and patch repository at same time
1805 qclone clone main and patch repository at same time
1792
1806
1793 Test unfound topic
1807 Test unfound topic
1794
1808
1795 $ hg help nonexistingtopicthatwillneverexisteverever
1809 $ hg help nonexistingtopicthatwillneverexisteverever
1796 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1810 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1797 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1811 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1798 [10]
1812 [10]
1799
1813
1800 Test unfound keyword
1814 Test unfound keyword
1801
1815
1802 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1816 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1803 abort: no matches
1817 abort: no matches
1804 (try 'hg help' for a list of topics)
1818 (try 'hg help' for a list of topics)
1805 [10]
1819 [10]
1806
1820
1807 Test omit indicating for help
1821 Test omit indicating for help
1808
1822
1809 $ cat > addverboseitems.py <<EOF
1823 $ cat > addverboseitems.py <<EOF
1810 > r'''extension to test omit indicating.
1824 > r'''extension to test omit indicating.
1811 >
1825 >
1812 > This paragraph is never omitted (for extension)
1826 > This paragraph is never omitted (for extension)
1813 >
1827 >
1814 > .. container:: verbose
1828 > .. container:: verbose
1815 >
1829 >
1816 > This paragraph is omitted,
1830 > This paragraph is omitted,
1817 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1831 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1818 >
1832 >
1819 > This paragraph is never omitted, too (for extension)
1833 > This paragraph is never omitted, too (for extension)
1820 > '''
1834 > '''
1821 > from mercurial import commands, help
1835 > from mercurial import commands, help
1822 > testtopic = br"""This paragraph is never omitted (for topic).
1836 > testtopic = br"""This paragraph is never omitted (for topic).
1823 >
1837 >
1824 > .. container:: verbose
1838 > .. container:: verbose
1825 >
1839 >
1826 > This paragraph is omitted,
1840 > This paragraph is omitted,
1827 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1841 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1828 >
1842 >
1829 > This paragraph is never omitted, too (for topic)
1843 > This paragraph is never omitted, too (for topic)
1830 > """
1844 > """
1831 > def extsetup(ui):
1845 > def extsetup(ui):
1832 > help.helptable.append(([b"topic-containing-verbose"],
1846 > help.helptable.append(([b"topic-containing-verbose"],
1833 > b"This is the topic to test omit indicating.",
1847 > b"This is the topic to test omit indicating.",
1834 > lambda ui: testtopic))
1848 > lambda ui: testtopic))
1835 > EOF
1849 > EOF
1836 $ echo '[extensions]' >> $HGRCPATH
1850 $ echo '[extensions]' >> $HGRCPATH
1837 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1851 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1838 $ hg help addverboseitems
1852 $ hg help addverboseitems
1839 addverboseitems extension - extension to test omit indicating.
1853 addverboseitems extension - extension to test omit indicating.
1840
1854
1841 This paragraph is never omitted (for extension)
1855 This paragraph is never omitted (for extension)
1842
1856
1843 This paragraph is never omitted, too (for extension)
1857 This paragraph is never omitted, too (for extension)
1844
1858
1845 (some details hidden, use --verbose to show complete help)
1859 (some details hidden, use --verbose to show complete help)
1846
1860
1847 no commands defined
1861 no commands defined
1848 $ hg help -v addverboseitems
1862 $ hg help -v addverboseitems
1849 addverboseitems extension - extension to test omit indicating.
1863 addverboseitems extension - extension to test omit indicating.
1850
1864
1851 This paragraph is never omitted (for extension)
1865 This paragraph is never omitted (for extension)
1852
1866
1853 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1867 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1854 extension)
1868 extension)
1855
1869
1856 This paragraph is never omitted, too (for extension)
1870 This paragraph is never omitted, too (for extension)
1857
1871
1858 no commands defined
1872 no commands defined
1859 $ hg help topic-containing-verbose
1873 $ hg help topic-containing-verbose
1860 This is the topic to test omit indicating.
1874 This is the topic to test omit indicating.
1861 """"""""""""""""""""""""""""""""""""""""""
1875 """"""""""""""""""""""""""""""""""""""""""
1862
1876
1863 This paragraph is never omitted (for topic).
1877 This paragraph is never omitted (for topic).
1864
1878
1865 This paragraph is never omitted, too (for topic)
1879 This paragraph is never omitted, too (for topic)
1866
1880
1867 (some details hidden, use --verbose to show complete help)
1881 (some details hidden, use --verbose to show complete help)
1868 $ hg help -v topic-containing-verbose
1882 $ hg help -v topic-containing-verbose
1869 This is the topic to test omit indicating.
1883 This is the topic to test omit indicating.
1870 """"""""""""""""""""""""""""""""""""""""""
1884 """"""""""""""""""""""""""""""""""""""""""
1871
1885
1872 This paragraph is never omitted (for topic).
1886 This paragraph is never omitted (for topic).
1873
1887
1874 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1888 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1875 topic)
1889 topic)
1876
1890
1877 This paragraph is never omitted, too (for topic)
1891 This paragraph is never omitted, too (for topic)
1878
1892
1879 Test section lookup
1893 Test section lookup
1880
1894
1881 $ hg help revset.merge
1895 $ hg help revset.merge
1882 "merge()"
1896 "merge()"
1883 Changeset is a merge changeset.
1897 Changeset is a merge changeset.
1884
1898
1885 $ hg help glossary.dag
1899 $ hg help glossary.dag
1886 DAG
1900 DAG
1887 The repository of changesets of a distributed version control system
1901 The repository of changesets of a distributed version control system
1888 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1902 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1889 of nodes and edges, where nodes correspond to changesets and edges
1903 of nodes and edges, where nodes correspond to changesets and edges
1890 imply a parent -> child relation. This graph can be visualized by
1904 imply a parent -> child relation. This graph can be visualized by
1891 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1905 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1892 limited by the requirement for children to have at most two parents.
1906 limited by the requirement for children to have at most two parents.
1893
1907
1894
1908
1895 $ hg help hgrc.paths
1909 $ hg help hgrc.paths
1896 "paths"
1910 "paths"
1897 -------
1911 -------
1898
1912
1899 Assigns symbolic names and behavior to repositories.
1913 Assigns symbolic names and behavior to repositories.
1900
1914
1901 Options are symbolic names defining the URL or directory that is the
1915 Options are symbolic names defining the URL or directory that is the
1902 location of the repository. Example:
1916 location of the repository. Example:
1903
1917
1904 [paths]
1918 [paths]
1905 my_server = https://example.com/my_repo
1919 my_server = https://example.com/my_repo
1906 local_path = /home/me/repo
1920 local_path = /home/me/repo
1907
1921
1908 These symbolic names can be used from the command line. To pull from
1922 These symbolic names can be used from the command line. To pull from
1909 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1923 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1910 local_path'. You can check 'hg help urls' for details about valid URLs.
1924 local_path'. You can check 'hg help urls' for details about valid URLs.
1911
1925
1912 Options containing colons (":") denote sub-options that can influence
1926 Options containing colons (":") denote sub-options that can influence
1913 behavior for that specific path. Example:
1927 behavior for that specific path. Example:
1914
1928
1915 [paths]
1929 [paths]
1916 my_server = https://example.com/my_path
1930 my_server = https://example.com/my_path
1917 my_server:pushurl = ssh://example.com/my_path
1931 my_server:pushurl = ssh://example.com/my_path
1918
1932
1919 Paths using the 'path://otherpath' scheme will inherit the sub-options
1933 Paths using the 'path://otherpath' scheme will inherit the sub-options
1920 value from the path they point to.
1934 value from the path they point to.
1921
1935
1922 The following sub-options can be defined:
1936 The following sub-options can be defined:
1923
1937
1924 "multi-urls"
1938 "multi-urls"
1925 A boolean option. When enabled the value of the '[paths]' entry will be
1939 A boolean option. When enabled the value of the '[paths]' entry will be
1926 parsed as a list and the alias will resolve to multiple destination. If
1940 parsed as a list and the alias will resolve to multiple destination. If
1927 some of the list entry use the 'path://' syntax, the suboption will be
1941 some of the list entry use the 'path://' syntax, the suboption will be
1928 inherited individually.
1942 inherited individually.
1929
1943
1930 "pushurl"
1944 "pushurl"
1931 The URL to use for push operations. If not defined, the location
1945 The URL to use for push operations. If not defined, the location
1932 defined by the path's main entry is used.
1946 defined by the path's main entry is used.
1933
1947
1934 "pushrev"
1948 "pushrev"
1935 A revset defining which revisions to push by default.
1949 A revset defining which revisions to push by default.
1936
1950
1937 When 'hg push' is executed without a "-r" argument, the revset defined
1951 When 'hg push' is executed without a "-r" argument, the revset defined
1938 by this sub-option is evaluated to determine what to push.
1952 by this sub-option is evaluated to determine what to push.
1939
1953
1940 For example, a value of "." will push the working directory's revision
1954 For example, a value of "." will push the working directory's revision
1941 by default.
1955 by default.
1942
1956
1943 Revsets specifying bookmarks will not result in the bookmark being
1957 Revsets specifying bookmarks will not result in the bookmark being
1944 pushed.
1958 pushed.
1945
1959
1946 "bookmarks.mode"
1960 "bookmarks.mode"
1947 How bookmark will be dealt during the exchange. It support the following
1961 How bookmark will be dealt during the exchange. It support the following
1948 value
1962 value
1949
1963
1950 - "default": the default behavior, local and remote bookmarks are
1964 - "default": the default behavior, local and remote bookmarks are
1951 "merged" on push/pull.
1965 "merged" on push/pull.
1952 - "mirror": when pulling, replace local bookmarks by remote bookmarks.
1966 - "mirror": when pulling, replace local bookmarks by remote bookmarks.
1953 This is useful to replicate a repository, or as an optimization.
1967 This is useful to replicate a repository, or as an optimization.
1954 - "ignore": ignore bookmarks during exchange. (This currently only
1968 - "ignore": ignore bookmarks during exchange. (This currently only
1955 affect pulling)
1969 affect pulling)
1956
1970
1957 The following special named paths exist:
1971 The following special named paths exist:
1958
1972
1959 "default"
1973 "default"
1960 The URL or directory to use when no source or remote is specified.
1974 The URL or directory to use when no source or remote is specified.
1961
1975
1962 'hg clone' will automatically define this path to the location the
1976 'hg clone' will automatically define this path to the location the
1963 repository was cloned from.
1977 repository was cloned from.
1964
1978
1965 "default-push"
1979 "default-push"
1966 (deprecated) The URL or directory for the default 'hg push' location.
1980 (deprecated) The URL or directory for the default 'hg push' location.
1967 "default:pushurl" should be used instead.
1981 "default:pushurl" should be used instead.
1968
1982
1969 $ hg help glossary.mcguffin
1983 $ hg help glossary.mcguffin
1970 abort: help section not found: glossary.mcguffin
1984 abort: help section not found: glossary.mcguffin
1971 [10]
1985 [10]
1972
1986
1973 $ hg help glossary.mc.guffin
1987 $ hg help glossary.mc.guffin
1974 abort: help section not found: glossary.mc.guffin
1988 abort: help section not found: glossary.mc.guffin
1975 [10]
1989 [10]
1976
1990
1977 $ hg help template.files
1991 $ hg help template.files
1978 files List of strings. All files modified, added, or removed by
1992 files List of strings. All files modified, added, or removed by
1979 this changeset.
1993 this changeset.
1980 files(pattern)
1994 files(pattern)
1981 All files of the current changeset matching the pattern. See
1995 All files of the current changeset matching the pattern. See
1982 'hg help patterns'.
1996 'hg help patterns'.
1983
1997
1984 Test section lookup by translated message
1998 Test section lookup by translated message
1985
1999
1986 str.lower() instead of encoding.lower(str) on translated message might
2000 str.lower() instead of encoding.lower(str) on translated message might
1987 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
2001 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1988 as the second or later byte of multi-byte character.
2002 as the second or later byte of multi-byte character.
1989
2003
1990 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
2004 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1991 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
2005 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1992 replacement makes message meaningless.
2006 replacement makes message meaningless.
1993
2007
1994 This tests that section lookup by translated string isn't broken by
2008 This tests that section lookup by translated string isn't broken by
1995 such str.lower().
2009 such str.lower().
1996
2010
1997 $ "$PYTHON" <<EOF
2011 $ "$PYTHON" <<EOF
1998 > def escape(s):
2012 > def escape(s):
1999 > return b''.join(br'\\u%x' % ord(uc) for uc in s.decode('cp932'))
2013 > return b''.join(br'\\u%x' % ord(uc) for uc in s.decode('cp932'))
2000 > # translation of "record" in ja_JP.cp932
2014 > # translation of "record" in ja_JP.cp932
2001 > upper = b"\x8bL\x98^"
2015 > upper = b"\x8bL\x98^"
2002 > # str.lower()-ed section name should be treated as different one
2016 > # str.lower()-ed section name should be treated as different one
2003 > lower = b"\x8bl\x98^"
2017 > lower = b"\x8bl\x98^"
2004 > with open('ambiguous.py', 'wb') as fp:
2018 > with open('ambiguous.py', 'wb') as fp:
2005 > fp.write(b"""# ambiguous section names in ja_JP.cp932
2019 > fp.write(b"""# ambiguous section names in ja_JP.cp932
2006 > u'''summary of extension
2020 > u'''summary of extension
2007 >
2021 >
2008 > %s
2022 > %s
2009 > ----
2023 > ----
2010 >
2024 >
2011 > Upper name should show only this message
2025 > Upper name should show only this message
2012 >
2026 >
2013 > %s
2027 > %s
2014 > ----
2028 > ----
2015 >
2029 >
2016 > Lower name should show only this message
2030 > Lower name should show only this message
2017 >
2031 >
2018 > subsequent section
2032 > subsequent section
2019 > ------------------
2033 > ------------------
2020 >
2034 >
2021 > This should be hidden at 'hg help ambiguous' with section name.
2035 > This should be hidden at 'hg help ambiguous' with section name.
2022 > '''
2036 > '''
2023 > """ % (escape(upper), escape(lower)))
2037 > """ % (escape(upper), escape(lower)))
2024 > EOF
2038 > EOF
2025
2039
2026 $ cat >> $HGRCPATH <<EOF
2040 $ cat >> $HGRCPATH <<EOF
2027 > [extensions]
2041 > [extensions]
2028 > ambiguous = ./ambiguous.py
2042 > ambiguous = ./ambiguous.py
2029 > EOF
2043 > EOF
2030
2044
2031 $ "$PYTHON" <<EOF | sh
2045 $ "$PYTHON" <<EOF | sh
2032 > from mercurial.utils import procutil
2046 > from mercurial.utils import procutil
2033 > upper = b"\x8bL\x98^"
2047 > upper = b"\x8bL\x98^"
2034 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
2048 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
2035 > EOF
2049 > EOF
2036 \x8bL\x98^ (esc)
2050 \x8bL\x98^ (esc)
2037 ----
2051 ----
2038
2052
2039 Upper name should show only this message
2053 Upper name should show only this message
2040
2054
2041
2055
2042 $ "$PYTHON" <<EOF | sh
2056 $ "$PYTHON" <<EOF | sh
2043 > from mercurial.utils import procutil
2057 > from mercurial.utils import procutil
2044 > lower = b"\x8bl\x98^"
2058 > lower = b"\x8bl\x98^"
2045 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
2059 > procutil.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
2046 > EOF
2060 > EOF
2047 \x8bl\x98^ (esc)
2061 \x8bl\x98^ (esc)
2048 ----
2062 ----
2049
2063
2050 Lower name should show only this message
2064 Lower name should show only this message
2051
2065
2052
2066
2053 $ cat >> $HGRCPATH <<EOF
2067 $ cat >> $HGRCPATH <<EOF
2054 > [extensions]
2068 > [extensions]
2055 > ambiguous = !
2069 > ambiguous = !
2056 > EOF
2070 > EOF
2057
2071
2058 Show help content of disabled extensions
2072 Show help content of disabled extensions
2059
2073
2060 $ cat >> $HGRCPATH <<EOF
2074 $ cat >> $HGRCPATH <<EOF
2061 > [extensions]
2075 > [extensions]
2062 > ambiguous = !./ambiguous.py
2076 > ambiguous = !./ambiguous.py
2063 > EOF
2077 > EOF
2064 $ hg help -e ambiguous
2078 $ hg help -e ambiguous
2065 ambiguous extension - (no help text available)
2079 ambiguous extension - (no help text available)
2066
2080
2067 (use 'hg help extensions' for information on enabling extensions)
2081 (use 'hg help extensions' for information on enabling extensions)
2068
2082
2069 Test dynamic list of merge tools only shows up once
2083 Test dynamic list of merge tools only shows up once
2070 $ hg help merge-tools
2084 $ hg help merge-tools
2071 Merge Tools
2085 Merge Tools
2072 """""""""""
2086 """""""""""
2073
2087
2074 To merge files Mercurial uses merge tools.
2088 To merge files Mercurial uses merge tools.
2075
2089
2076 A merge tool combines two different versions of a file into a merged file.
2090 A merge tool combines two different versions of a file into a merged file.
2077 Merge tools are given the two files and the greatest common ancestor of
2091 Merge tools are given the two files and the greatest common ancestor of
2078 the two file versions, so they can determine the changes made on both
2092 the two file versions, so they can determine the changes made on both
2079 branches.
2093 branches.
2080
2094
2081 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
2095 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
2082 backout' and in several extensions.
2096 backout' and in several extensions.
2083
2097
2084 Usually, the merge tool tries to automatically reconcile the files by
2098 Usually, the merge tool tries to automatically reconcile the files by
2085 combining all non-overlapping changes that occurred separately in the two
2099 combining all non-overlapping changes that occurred separately in the two
2086 different evolutions of the same initial base file. Furthermore, some
2100 different evolutions of the same initial base file. Furthermore, some
2087 interactive merge programs make it easier to manually resolve conflicting
2101 interactive merge programs make it easier to manually resolve conflicting
2088 merges, either in a graphical way, or by inserting some conflict markers.
2102 merges, either in a graphical way, or by inserting some conflict markers.
2089 Mercurial does not include any interactive merge programs but relies on
2103 Mercurial does not include any interactive merge programs but relies on
2090 external tools for that.
2104 external tools for that.
2091
2105
2092 Available merge tools
2106 Available merge tools
2093 =====================
2107 =====================
2094
2108
2095 External merge tools and their properties are configured in the merge-
2109 External merge tools and their properties are configured in the merge-
2096 tools configuration section - see hgrc(5) - but they can often just be
2110 tools configuration section - see hgrc(5) - but they can often just be
2097 named by their executable.
2111 named by their executable.
2098
2112
2099 A merge tool is generally usable if its executable can be found on the
2113 A merge tool is generally usable if its executable can be found on the
2100 system and if it can handle the merge. The executable is found if it is an
2114 system and if it can handle the merge. The executable is found if it is an
2101 absolute or relative executable path or the name of an application in the
2115 absolute or relative executable path or the name of an application in the
2102 executable search path. The tool is assumed to be able to handle the merge
2116 executable search path. The tool is assumed to be able to handle the merge
2103 if it can handle symlinks if the file is a symlink, if it can handle
2117 if it can handle symlinks if the file is a symlink, if it can handle
2104 binary files if the file is binary, and if a GUI is available if the tool
2118 binary files if the file is binary, and if a GUI is available if the tool
2105 requires a GUI.
2119 requires a GUI.
2106
2120
2107 There are some internal merge tools which can be used. The internal merge
2121 There are some internal merge tools which can be used. The internal merge
2108 tools are:
2122 tools are:
2109
2123
2110 ":dump"
2124 ":dump"
2111 Creates three versions of the files to merge, containing the contents of
2125 Creates three versions of the files to merge, containing the contents of
2112 local, other and base. These files can then be used to perform a merge
2126 local, other and base. These files can then be used to perform a merge
2113 manually. If the file to be merged is named "a.txt", these files will
2127 manually. If the file to be merged is named "a.txt", these files will
2114 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
2128 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
2115 they will be placed in the same directory as "a.txt".
2129 they will be placed in the same directory as "a.txt".
2116
2130
2117 This implies premerge. Therefore, files aren't dumped, if premerge runs
2131 This implies premerge. Therefore, files aren't dumped, if premerge runs
2118 successfully. Use :forcedump to forcibly write files out.
2132 successfully. Use :forcedump to forcibly write files out.
2119
2133
2120 (actual capabilities: binary, symlink)
2134 (actual capabilities: binary, symlink)
2121
2135
2122 ":fail"
2136 ":fail"
2123 Rather than attempting to merge files that were modified on both
2137 Rather than attempting to merge files that were modified on both
2124 branches, it marks them as unresolved. The resolve command must be used
2138 branches, it marks them as unresolved. The resolve command must be used
2125 to resolve these conflicts.
2139 to resolve these conflicts.
2126
2140
2127 (actual capabilities: binary, symlink)
2141 (actual capabilities: binary, symlink)
2128
2142
2129 ":forcedump"
2143 ":forcedump"
2130 Creates three versions of the files as same as :dump, but omits
2144 Creates three versions of the files as same as :dump, but omits
2131 premerge.
2145 premerge.
2132
2146
2133 (actual capabilities: binary, symlink)
2147 (actual capabilities: binary, symlink)
2134
2148
2135 ":local"
2149 ":local"
2136 Uses the local 'p1()' version of files as the merged version.
2150 Uses the local 'p1()' version of files as the merged version.
2137
2151
2138 (actual capabilities: binary, symlink)
2152 (actual capabilities: binary, symlink)
2139
2153
2140 ":merge"
2154 ":merge"
2141 Uses the internal non-interactive simple merge algorithm for merging
2155 Uses the internal non-interactive simple merge algorithm for merging
2142 files. It will fail if there are any conflicts and leave markers in the
2156 files. It will fail if there are any conflicts and leave markers in the
2143 partially merged file. Markers will have two sections, one for each side
2157 partially merged file. Markers will have two sections, one for each side
2144 of merge.
2158 of merge.
2145
2159
2146 ":merge-local"
2160 ":merge-local"
2147 Like :merge, but resolve all conflicts non-interactively in favor of the
2161 Like :merge, but resolve all conflicts non-interactively in favor of the
2148 local 'p1()' changes.
2162 local 'p1()' changes.
2149
2163
2150 ":merge-other"
2164 ":merge-other"
2151 Like :merge, but resolve all conflicts non-interactively in favor of the
2165 Like :merge, but resolve all conflicts non-interactively in favor of the
2152 other 'p2()' changes.
2166 other 'p2()' changes.
2153
2167
2154 ":merge3"
2168 ":merge3"
2155 Uses the internal non-interactive simple merge algorithm for merging
2169 Uses the internal non-interactive simple merge algorithm for merging
2156 files. It will fail if there are any conflicts and leave markers in the
2170 files. It will fail if there are any conflicts and leave markers in the
2157 partially merged file. Marker will have three sections, one from each
2171 partially merged file. Marker will have three sections, one from each
2158 side of the merge and one for the base content.
2172 side of the merge and one for the base content.
2159
2173
2160 ":mergediff"
2174 ":mergediff"
2161 Uses the internal non-interactive simple merge algorithm for merging
2175 Uses the internal non-interactive simple merge algorithm for merging
2162 files. It will fail if there are any conflicts and leave markers in the
2176 files. It will fail if there are any conflicts and leave markers in the
2163 partially merged file. The marker will have two sections, one with the
2177 partially merged file. The marker will have two sections, one with the
2164 content from one side of the merge, and one with a diff from the base
2178 content from one side of the merge, and one with a diff from the base
2165 content to the content on the other side. (experimental)
2179 content to the content on the other side. (experimental)
2166
2180
2167 ":other"
2181 ":other"
2168 Uses the other 'p2()' version of files as the merged version.
2182 Uses the other 'p2()' version of files as the merged version.
2169
2183
2170 (actual capabilities: binary, symlink)
2184 (actual capabilities: binary, symlink)
2171
2185
2172 ":prompt"
2186 ":prompt"
2173 Asks the user which of the local 'p1()' or the other 'p2()' version to
2187 Asks the user which of the local 'p1()' or the other 'p2()' version to
2174 keep as the merged version.
2188 keep as the merged version.
2175
2189
2176 (actual capabilities: binary, symlink)
2190 (actual capabilities: binary, symlink)
2177
2191
2178 ":tagmerge"
2192 ":tagmerge"
2179 Uses the internal tag merge algorithm (experimental).
2193 Uses the internal tag merge algorithm (experimental).
2180
2194
2181 ":union"
2195 ":union"
2182 Uses the internal non-interactive simple merge algorithm for merging
2196 Uses the internal non-interactive simple merge algorithm for merging
2183 files. It will use both local and other sides for conflict regions by
2197 files. It will use both local and other sides for conflict regions by
2184 adding local on top of other. No markers are inserted.
2198 adding local on top of other. No markers are inserted.
2185
2199
2186 ":union-other-first"
2200 ":union-other-first"
2187 Like :union, but add other on top of local.
2201 Like :union, but add other on top of local.
2188
2202
2189 Internal tools are always available and do not require a GUI but will by
2203 Internal tools are always available and do not require a GUI but will by
2190 default not handle symlinks or binary files. See next section for detail
2204 default not handle symlinks or binary files. See next section for detail
2191 about "actual capabilities" described above.
2205 about "actual capabilities" described above.
2192
2206
2193 Choosing a merge tool
2207 Choosing a merge tool
2194 =====================
2208 =====================
2195
2209
2196 Mercurial uses these rules when deciding which merge tool to use:
2210 Mercurial uses these rules when deciding which merge tool to use:
2197
2211
2198 1. If a tool has been specified with the --tool option to merge or
2212 1. If a tool has been specified with the --tool option to merge or
2199 resolve, it is used. If it is the name of a tool in the merge-tools
2213 resolve, it is used. If it is the name of a tool in the merge-tools
2200 configuration, its configuration is used. Otherwise the specified tool
2214 configuration, its configuration is used. Otherwise the specified tool
2201 must be executable by the shell.
2215 must be executable by the shell.
2202 2. If the "HGMERGE" environment variable is present, its value is used and
2216 2. If the "HGMERGE" environment variable is present, its value is used and
2203 must be executable by the shell.
2217 must be executable by the shell.
2204 3. If the filename of the file to be merged matches any of the patterns in
2218 3. If the filename of the file to be merged matches any of the patterns in
2205 the merge-patterns configuration section, the first usable merge tool
2219 the merge-patterns configuration section, the first usable merge tool
2206 corresponding to a matching pattern is used.
2220 corresponding to a matching pattern is used.
2207 4. If ui.merge is set it will be considered next. If the value is not the
2221 4. If ui.merge is set it will be considered next. If the value is not the
2208 name of a configured tool, the specified value is used and must be
2222 name of a configured tool, the specified value is used and must be
2209 executable by the shell. Otherwise the named tool is used if it is
2223 executable by the shell. Otherwise the named tool is used if it is
2210 usable.
2224 usable.
2211 5. If any usable merge tools are present in the merge-tools configuration
2225 5. If any usable merge tools are present in the merge-tools configuration
2212 section, the one with the highest priority is used.
2226 section, the one with the highest priority is used.
2213 6. If a program named "hgmerge" can be found on the system, it is used -
2227 6. If a program named "hgmerge" can be found on the system, it is used -
2214 but it will by default not be used for symlinks and binary files.
2228 but it will by default not be used for symlinks and binary files.
2215 7. If the file to be merged is not binary and is not a symlink, then
2229 7. If the file to be merged is not binary and is not a symlink, then
2216 internal ":merge" is used.
2230 internal ":merge" is used.
2217 8. Otherwise, ":prompt" is used.
2231 8. Otherwise, ":prompt" is used.
2218
2232
2219 For historical reason, Mercurial treats merge tools as below while
2233 For historical reason, Mercurial treats merge tools as below while
2220 examining rules above.
2234 examining rules above.
2221
2235
2222 step specified via binary symlink
2236 step specified via binary symlink
2223 ----------------------------------
2237 ----------------------------------
2224 1. --tool o/o o/o
2238 1. --tool o/o o/o
2225 2. HGMERGE o/o o/o
2239 2. HGMERGE o/o o/o
2226 3. merge-patterns o/o(*) x/?(*)
2240 3. merge-patterns o/o(*) x/?(*)
2227 4. ui.merge x/?(*) x/?(*)
2241 4. ui.merge x/?(*) x/?(*)
2228
2242
2229 Each capability column indicates Mercurial behavior for internal/external
2243 Each capability column indicates Mercurial behavior for internal/external
2230 merge tools at examining each rule.
2244 merge tools at examining each rule.
2231
2245
2232 - "o": "assume that a tool has capability"
2246 - "o": "assume that a tool has capability"
2233 - "x": "assume that a tool does not have capability"
2247 - "x": "assume that a tool does not have capability"
2234 - "?": "check actual capability of a tool"
2248 - "?": "check actual capability of a tool"
2235
2249
2236 If "merge.strict-capability-check" configuration is true, Mercurial checks
2250 If "merge.strict-capability-check" configuration is true, Mercurial checks
2237 capabilities of merge tools strictly in (*) cases above (= each capability
2251 capabilities of merge tools strictly in (*) cases above (= each capability
2238 column becomes "?/?"). It is false by default for backward compatibility.
2252 column becomes "?/?"). It is false by default for backward compatibility.
2239
2253
2240 Note:
2254 Note:
2241 After selecting a merge program, Mercurial will by default attempt to
2255 After selecting a merge program, Mercurial will by default attempt to
2242 merge the files using a simple merge algorithm first. Only if it
2256 merge the files using a simple merge algorithm first. Only if it
2243 doesn't succeed because of conflicting changes will Mercurial actually
2257 doesn't succeed because of conflicting changes will Mercurial actually
2244 execute the merge program. Whether to use the simple merge algorithm
2258 execute the merge program. Whether to use the simple merge algorithm
2245 first can be controlled by the premerge setting of the merge tool.
2259 first can be controlled by the premerge setting of the merge tool.
2246 Premerge is enabled by default unless the file is binary or a symlink.
2260 Premerge is enabled by default unless the file is binary or a symlink.
2247
2261
2248 See the merge-tools and ui sections of hgrc(5) for details on the
2262 See the merge-tools and ui sections of hgrc(5) for details on the
2249 configuration of merge tools.
2263 configuration of merge tools.
2250
2264
2251 Compression engines listed in `hg help bundlespec`
2265 Compression engines listed in `hg help bundlespec`
2252
2266
2253 $ hg help bundlespec | grep gzip
2267 $ hg help bundlespec | grep gzip
2254 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2268 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2255 An algorithm that produces smaller bundles than "gzip".
2269 An algorithm that produces smaller bundles than "gzip".
2256 This engine will likely produce smaller bundles than "gzip" but will be
2270 This engine will likely produce smaller bundles than "gzip" but will be
2257 "gzip"
2271 "gzip"
2258 better compression than "gzip". It also frequently yields better (?)
2272 better compression than "gzip". It also frequently yields better (?)
2259
2273
2260 Test usage of section marks in help documents
2274 Test usage of section marks in help documents
2261
2275
2262 $ cd "$TESTDIR"/../doc
2276 $ cd "$TESTDIR"/../doc
2263 $ "$PYTHON" check-seclevel.py
2277 $ "$PYTHON" check-seclevel.py
2264 $ cd $TESTTMP
2278 $ cd $TESTTMP
2265
2279
2266 #if serve
2280 #if serve
2267
2281
2268 Test the help pages in hgweb.
2282 Test the help pages in hgweb.
2269
2283
2270 Dish up an empty repo; serve it cold.
2284 Dish up an empty repo; serve it cold.
2271
2285
2272 $ hg init "$TESTTMP/test"
2286 $ hg init "$TESTTMP/test"
2273 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2287 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2274 $ cat hg.pid >> $DAEMON_PIDS
2288 $ cat hg.pid >> $DAEMON_PIDS
2275
2289
2276 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2290 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2277 200 Script output follows
2291 200 Script output follows
2278
2292
2279 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2293 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2280 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2294 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2281 <head>
2295 <head>
2282 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2296 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2283 <meta name="robots" content="index, nofollow" />
2297 <meta name="robots" content="index, nofollow" />
2284 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2298 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2285 <script type="text/javascript" src="/static/mercurial.js"></script>
2299 <script type="text/javascript" src="/static/mercurial.js"></script>
2286
2300
2287 <title>Help: Index</title>
2301 <title>Help: Index</title>
2288 </head>
2302 </head>
2289 <body>
2303 <body>
2290
2304
2291 <div class="container">
2305 <div class="container">
2292 <div class="menu">
2306 <div class="menu">
2293 <div class="logo">
2307 <div class="logo">
2294 <a href="https://mercurial-scm.org/">
2308 <a href="https://mercurial-scm.org/">
2295 <img src="/static/hglogo.png" alt="mercurial" /></a>
2309 <img src="/static/hglogo.png" alt="mercurial" /></a>
2296 </div>
2310 </div>
2297 <ul>
2311 <ul>
2298 <li><a href="/shortlog">log</a></li>
2312 <li><a href="/shortlog">log</a></li>
2299 <li><a href="/graph">graph</a></li>
2313 <li><a href="/graph">graph</a></li>
2300 <li><a href="/tags">tags</a></li>
2314 <li><a href="/tags">tags</a></li>
2301 <li><a href="/bookmarks">bookmarks</a></li>
2315 <li><a href="/bookmarks">bookmarks</a></li>
2302 <li><a href="/branches">branches</a></li>
2316 <li><a href="/branches">branches</a></li>
2303 </ul>
2317 </ul>
2304 <ul>
2318 <ul>
2305 <li class="active">help</li>
2319 <li class="active">help</li>
2306 </ul>
2320 </ul>
2307 </div>
2321 </div>
2308
2322
2309 <div class="main">
2323 <div class="main">
2310 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2324 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2311
2325
2312 <form class="search" action="/log">
2326 <form class="search" action="/log">
2313
2327
2314 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2328 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2315 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2329 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2316 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2330 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2317 </form>
2331 </form>
2318 <table class="bigtable">
2332 <table class="bigtable">
2319 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2333 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2320
2334
2321 <tr><td>
2335 <tr><td>
2322 <a href="/help/bundlespec">
2336 <a href="/help/bundlespec">
2323 bundlespec
2337 bundlespec
2324 </a>
2338 </a>
2325 </td><td>
2339 </td><td>
2326 Bundle File Formats
2340 Bundle File Formats
2327 </td></tr>
2341 </td></tr>
2328 <tr><td>
2342 <tr><td>
2329 <a href="/help/color">
2343 <a href="/help/color">
2330 color
2344 color
2331 </a>
2345 </a>
2332 </td><td>
2346 </td><td>
2333 Colorizing Outputs
2347 Colorizing Outputs
2334 </td></tr>
2348 </td></tr>
2335 <tr><td>
2349 <tr><td>
2336 <a href="/help/config">
2350 <a href="/help/config">
2337 config
2351 config
2338 </a>
2352 </a>
2339 </td><td>
2353 </td><td>
2340 Configuration Files
2354 Configuration Files
2341 </td></tr>
2355 </td></tr>
2342 <tr><td>
2356 <tr><td>
2343 <a href="/help/dates">
2357 <a href="/help/dates">
2344 dates
2358 dates
2345 </a>
2359 </a>
2346 </td><td>
2360 </td><td>
2347 Date Formats
2361 Date Formats
2348 </td></tr>
2362 </td></tr>
2349 <tr><td>
2363 <tr><td>
2350 <a href="/help/deprecated">
2364 <a href="/help/deprecated">
2351 deprecated
2365 deprecated
2352 </a>
2366 </a>
2353 </td><td>
2367 </td><td>
2354 Deprecated Features
2368 Deprecated Features
2355 </td></tr>
2369 </td></tr>
2356 <tr><td>
2370 <tr><td>
2357 <a href="/help/diffs">
2371 <a href="/help/diffs">
2358 diffs
2372 diffs
2359 </a>
2373 </a>
2360 </td><td>
2374 </td><td>
2361 Diff Formats
2375 Diff Formats
2362 </td></tr>
2376 </td></tr>
2363 <tr><td>
2377 <tr><td>
2364 <a href="/help/environment">
2378 <a href="/help/environment">
2365 environment
2379 environment
2366 </a>
2380 </a>
2367 </td><td>
2381 </td><td>
2368 Environment Variables
2382 Environment Variables
2369 </td></tr>
2383 </td></tr>
2370 <tr><td>
2384 <tr><td>
2371 <a href="/help/evolution">
2385 <a href="/help/evolution">
2372 evolution
2386 evolution
2373 </a>
2387 </a>
2374 </td><td>
2388 </td><td>
2375 Safely rewriting history (EXPERIMENTAL)
2389 Safely rewriting history (EXPERIMENTAL)
2376 </td></tr>
2390 </td></tr>
2377 <tr><td>
2391 <tr><td>
2378 <a href="/help/extensions">
2392 <a href="/help/extensions">
2379 extensions
2393 extensions
2380 </a>
2394 </a>
2381 </td><td>
2395 </td><td>
2382 Using Additional Features
2396 Using Additional Features
2383 </td></tr>
2397 </td></tr>
2384 <tr><td>
2398 <tr><td>
2385 <a href="/help/filesets">
2399 <a href="/help/filesets">
2386 filesets
2400 filesets
2387 </a>
2401 </a>
2388 </td><td>
2402 </td><td>
2389 Specifying File Sets
2403 Specifying File Sets
2390 </td></tr>
2404 </td></tr>
2391 <tr><td>
2405 <tr><td>
2392 <a href="/help/flags">
2406 <a href="/help/flags">
2393 flags
2407 flags
2394 </a>
2408 </a>
2395 </td><td>
2409 </td><td>
2396 Command-line flags
2410 Command-line flags
2397 </td></tr>
2411 </td></tr>
2398 <tr><td>
2412 <tr><td>
2399 <a href="/help/glossary">
2413 <a href="/help/glossary">
2400 glossary
2414 glossary
2401 </a>
2415 </a>
2402 </td><td>
2416 </td><td>
2403 Glossary
2417 Glossary
2404 </td></tr>
2418 </td></tr>
2405 <tr><td>
2419 <tr><td>
2406 <a href="/help/hgignore">
2420 <a href="/help/hgignore">
2407 hgignore
2421 hgignore
2408 </a>
2422 </a>
2409 </td><td>
2423 </td><td>
2410 Syntax for Mercurial Ignore Files
2424 Syntax for Mercurial Ignore Files
2411 </td></tr>
2425 </td></tr>
2412 <tr><td>
2426 <tr><td>
2413 <a href="/help/hgweb">
2427 <a href="/help/hgweb">
2414 hgweb
2428 hgweb
2415 </a>
2429 </a>
2416 </td><td>
2430 </td><td>
2417 Configuring hgweb
2431 Configuring hgweb
2418 </td></tr>
2432 </td></tr>
2419 <tr><td>
2433 <tr><td>
2420 <a href="/help/internals">
2434 <a href="/help/internals">
2421 internals
2435 internals
2422 </a>
2436 </a>
2423 </td><td>
2437 </td><td>
2424 Technical implementation topics
2438 Technical implementation topics
2425 </td></tr>
2439 </td></tr>
2426 <tr><td>
2440 <tr><td>
2427 <a href="/help/merge-tools">
2441 <a href="/help/merge-tools">
2428 merge-tools
2442 merge-tools
2429 </a>
2443 </a>
2430 </td><td>
2444 </td><td>
2431 Merge Tools
2445 Merge Tools
2432 </td></tr>
2446 </td></tr>
2433 <tr><td>
2447 <tr><td>
2434 <a href="/help/pager">
2448 <a href="/help/pager">
2435 pager
2449 pager
2436 </a>
2450 </a>
2437 </td><td>
2451 </td><td>
2438 Pager Support
2452 Pager Support
2439 </td></tr>
2453 </td></tr>
2440 <tr><td>
2454 <tr><td>
2441 <a href="/help/patterns">
2455 <a href="/help/patterns">
2442 patterns
2456 patterns
2443 </a>
2457 </a>
2444 </td><td>
2458 </td><td>
2445 File Name Patterns
2459 File Name Patterns
2446 </td></tr>
2460 </td></tr>
2447 <tr><td>
2461 <tr><td>
2448 <a href="/help/phases">
2462 <a href="/help/phases">
2449 phases
2463 phases
2450 </a>
2464 </a>
2451 </td><td>
2465 </td><td>
2452 Working with Phases
2466 Working with Phases
2453 </td></tr>
2467 </td></tr>
2454 <tr><td>
2468 <tr><td>
2455 <a href="/help/revisions">
2469 <a href="/help/revisions">
2456 revisions
2470 revisions
2457 </a>
2471 </a>
2458 </td><td>
2472 </td><td>
2459 Specifying Revisions
2473 Specifying Revisions
2460 </td></tr>
2474 </td></tr>
2461 <tr><td>
2475 <tr><td>
2462 <a href="/help/rust">
2476 <a href="/help/rust">
2463 rust
2477 rust
2464 </a>
2478 </a>
2465 </td><td>
2479 </td><td>
2466 Rust in Mercurial
2480 Rust in Mercurial
2467 </td></tr>
2481 </td></tr>
2468 <tr><td>
2482 <tr><td>
2469 <a href="/help/scripting">
2483 <a href="/help/scripting">
2470 scripting
2484 scripting
2471 </a>
2485 </a>
2472 </td><td>
2486 </td><td>
2473 Using Mercurial from scripts and automation
2487 Using Mercurial from scripts and automation
2474 </td></tr>
2488 </td></tr>
2475 <tr><td>
2489 <tr><td>
2476 <a href="/help/subrepos">
2490 <a href="/help/subrepos">
2477 subrepos
2491 subrepos
2478 </a>
2492 </a>
2479 </td><td>
2493 </td><td>
2480 Subrepositories
2494 Subrepositories
2481 </td></tr>
2495 </td></tr>
2482 <tr><td>
2496 <tr><td>
2483 <a href="/help/templating">
2497 <a href="/help/templating">
2484 templating
2498 templating
2485 </a>
2499 </a>
2486 </td><td>
2500 </td><td>
2487 Template Usage
2501 Template Usage
2488 </td></tr>
2502 </td></tr>
2489 <tr><td>
2503 <tr><td>
2490 <a href="/help/urls">
2504 <a href="/help/urls">
2491 urls
2505 urls
2492 </a>
2506 </a>
2493 </td><td>
2507 </td><td>
2494 URL Paths
2508 URL Paths
2495 </td></tr>
2509 </td></tr>
2496 <tr><td>
2510 <tr><td>
2497 <a href="/help/topic-containing-verbose">
2511 <a href="/help/topic-containing-verbose">
2498 topic-containing-verbose
2512 topic-containing-verbose
2499 </a>
2513 </a>
2500 </td><td>
2514 </td><td>
2501 This is the topic to test omit indicating.
2515 This is the topic to test omit indicating.
2502 </td></tr>
2516 </td></tr>
2503
2517
2504
2518
2505 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2519 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2506
2520
2507 <tr><td>
2521 <tr><td>
2508 <a href="/help/abort">
2522 <a href="/help/abort">
2509 abort
2523 abort
2510 </a>
2524 </a>
2511 </td><td>
2525 </td><td>
2512 abort an unfinished operation (EXPERIMENTAL)
2526 abort an unfinished operation (EXPERIMENTAL)
2513 </td></tr>
2527 </td></tr>
2514 <tr><td>
2528 <tr><td>
2515 <a href="/help/add">
2529 <a href="/help/add">
2516 add
2530 add
2517 </a>
2531 </a>
2518 </td><td>
2532 </td><td>
2519 add the specified files on the next commit
2533 add the specified files on the next commit
2520 </td></tr>
2534 </td></tr>
2521 <tr><td>
2535 <tr><td>
2522 <a href="/help/annotate">
2536 <a href="/help/annotate">
2523 annotate
2537 annotate
2524 </a>
2538 </a>
2525 </td><td>
2539 </td><td>
2526 show changeset information by line for each file
2540 show changeset information by line for each file
2527 </td></tr>
2541 </td></tr>
2528 <tr><td>
2542 <tr><td>
2529 <a href="/help/clone">
2543 <a href="/help/clone">
2530 clone
2544 clone
2531 </a>
2545 </a>
2532 </td><td>
2546 </td><td>
2533 make a copy of an existing repository
2547 make a copy of an existing repository
2534 </td></tr>
2548 </td></tr>
2535 <tr><td>
2549 <tr><td>
2536 <a href="/help/commit">
2550 <a href="/help/commit">
2537 commit
2551 commit
2538 </a>
2552 </a>
2539 </td><td>
2553 </td><td>
2540 commit the specified files or all outstanding changes
2554 commit the specified files or all outstanding changes
2541 </td></tr>
2555 </td></tr>
2542 <tr><td>
2556 <tr><td>
2543 <a href="/help/continue">
2557 <a href="/help/continue">
2544 continue
2558 continue
2545 </a>
2559 </a>
2546 </td><td>
2560 </td><td>
2547 resumes an interrupted operation (EXPERIMENTAL)
2561 resumes an interrupted operation (EXPERIMENTAL)
2548 </td></tr>
2562 </td></tr>
2549 <tr><td>
2563 <tr><td>
2550 <a href="/help/diff">
2564 <a href="/help/diff">
2551 diff
2565 diff
2552 </a>
2566 </a>
2553 </td><td>
2567 </td><td>
2554 diff repository (or selected files)
2568 diff repository (or selected files)
2555 </td></tr>
2569 </td></tr>
2556 <tr><td>
2570 <tr><td>
2557 <a href="/help/export">
2571 <a href="/help/export">
2558 export
2572 export
2559 </a>
2573 </a>
2560 </td><td>
2574 </td><td>
2561 dump the header and diffs for one or more changesets
2575 dump the header and diffs for one or more changesets
2562 </td></tr>
2576 </td></tr>
2563 <tr><td>
2577 <tr><td>
2564 <a href="/help/forget">
2578 <a href="/help/forget">
2565 forget
2579 forget
2566 </a>
2580 </a>
2567 </td><td>
2581 </td><td>
2568 forget the specified files on the next commit
2582 forget the specified files on the next commit
2569 </td></tr>
2583 </td></tr>
2570 <tr><td>
2584 <tr><td>
2571 <a href="/help/init">
2585 <a href="/help/init">
2572 init
2586 init
2573 </a>
2587 </a>
2574 </td><td>
2588 </td><td>
2575 create a new repository in the given directory
2589 create a new repository in the given directory
2576 </td></tr>
2590 </td></tr>
2577 <tr><td>
2591 <tr><td>
2578 <a href="/help/log">
2592 <a href="/help/log">
2579 log
2593 log
2580 </a>
2594 </a>
2581 </td><td>
2595 </td><td>
2582 show revision history of entire repository or files
2596 show revision history of entire repository or files
2583 </td></tr>
2597 </td></tr>
2584 <tr><td>
2598 <tr><td>
2585 <a href="/help/merge">
2599 <a href="/help/merge">
2586 merge
2600 merge
2587 </a>
2601 </a>
2588 </td><td>
2602 </td><td>
2589 merge another revision into working directory
2603 merge another revision into working directory
2590 </td></tr>
2604 </td></tr>
2591 <tr><td>
2605 <tr><td>
2592 <a href="/help/pull">
2606 <a href="/help/pull">
2593 pull
2607 pull
2594 </a>
2608 </a>
2595 </td><td>
2609 </td><td>
2596 pull changes from the specified source
2610 pull changes from the specified source
2597 </td></tr>
2611 </td></tr>
2598 <tr><td>
2612 <tr><td>
2599 <a href="/help/push">
2613 <a href="/help/push">
2600 push
2614 push
2601 </a>
2615 </a>
2602 </td><td>
2616 </td><td>
2603 push changes to the specified destination
2617 push changes to the specified destination
2604 </td></tr>
2618 </td></tr>
2605 <tr><td>
2619 <tr><td>
2606 <a href="/help/remove">
2620 <a href="/help/remove">
2607 remove
2621 remove
2608 </a>
2622 </a>
2609 </td><td>
2623 </td><td>
2610 remove the specified files on the next commit
2624 remove the specified files on the next commit
2611 </td></tr>
2625 </td></tr>
2612 <tr><td>
2626 <tr><td>
2613 <a href="/help/serve">
2627 <a href="/help/serve">
2614 serve
2628 serve
2615 </a>
2629 </a>
2616 </td><td>
2630 </td><td>
2617 start stand-alone webserver
2631 start stand-alone webserver
2618 </td></tr>
2632 </td></tr>
2619 <tr><td>
2633 <tr><td>
2620 <a href="/help/status">
2634 <a href="/help/status">
2621 status
2635 status
2622 </a>
2636 </a>
2623 </td><td>
2637 </td><td>
2624 show changed files in the working directory
2638 show changed files in the working directory
2625 </td></tr>
2639 </td></tr>
2626 <tr><td>
2640 <tr><td>
2627 <a href="/help/summary">
2641 <a href="/help/summary">
2628 summary
2642 summary
2629 </a>
2643 </a>
2630 </td><td>
2644 </td><td>
2631 summarize working directory state
2645 summarize working directory state
2632 </td></tr>
2646 </td></tr>
2633 <tr><td>
2647 <tr><td>
2634 <a href="/help/update">
2648 <a href="/help/update">
2635 update
2649 update
2636 </a>
2650 </a>
2637 </td><td>
2651 </td><td>
2638 update working directory (or switch revisions)
2652 update working directory (or switch revisions)
2639 </td></tr>
2653 </td></tr>
2640
2654
2641
2655
2642
2656
2643 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2657 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2644
2658
2645 <tr><td>
2659 <tr><td>
2646 <a href="/help/addremove">
2660 <a href="/help/addremove">
2647 addremove
2661 addremove
2648 </a>
2662 </a>
2649 </td><td>
2663 </td><td>
2650 add all new files, delete all missing files
2664 add all new files, delete all missing files
2651 </td></tr>
2665 </td></tr>
2652 <tr><td>
2666 <tr><td>
2667 <a href="/help/admin::verify">
2668 admin::verify
2669 </a>
2670 </td><td>
2671 verify the integrity of the repository
2672 </td></tr>
2673 <tr><td>
2653 <a href="/help/archive">
2674 <a href="/help/archive">
2654 archive
2675 archive
2655 </a>
2676 </a>
2656 </td><td>
2677 </td><td>
2657 create an unversioned archive of a repository revision
2678 create an unversioned archive of a repository revision
2658 </td></tr>
2679 </td></tr>
2659 <tr><td>
2680 <tr><td>
2660 <a href="/help/backout">
2681 <a href="/help/backout">
2661 backout
2682 backout
2662 </a>
2683 </a>
2663 </td><td>
2684 </td><td>
2664 reverse effect of earlier changeset
2685 reverse effect of earlier changeset
2665 </td></tr>
2686 </td></tr>
2666 <tr><td>
2687 <tr><td>
2667 <a href="/help/bisect">
2688 <a href="/help/bisect">
2668 bisect
2689 bisect
2669 </a>
2690 </a>
2670 </td><td>
2691 </td><td>
2671 subdivision search of changesets
2692 subdivision search of changesets
2672 </td></tr>
2693 </td></tr>
2673 <tr><td>
2694 <tr><td>
2674 <a href="/help/bookmarks">
2695 <a href="/help/bookmarks">
2675 bookmarks
2696 bookmarks
2676 </a>
2697 </a>
2677 </td><td>
2698 </td><td>
2678 create a new bookmark or list existing bookmarks
2699 create a new bookmark or list existing bookmarks
2679 </td></tr>
2700 </td></tr>
2680 <tr><td>
2701 <tr><td>
2681 <a href="/help/branch">
2702 <a href="/help/branch">
2682 branch
2703 branch
2683 </a>
2704 </a>
2684 </td><td>
2705 </td><td>
2685 set or show the current branch name
2706 set or show the current branch name
2686 </td></tr>
2707 </td></tr>
2687 <tr><td>
2708 <tr><td>
2688 <a href="/help/branches">
2709 <a href="/help/branches">
2689 branches
2710 branches
2690 </a>
2711 </a>
2691 </td><td>
2712 </td><td>
2692 list repository named branches
2713 list repository named branches
2693 </td></tr>
2714 </td></tr>
2694 <tr><td>
2715 <tr><td>
2695 <a href="/help/bundle">
2716 <a href="/help/bundle">
2696 bundle
2717 bundle
2697 </a>
2718 </a>
2698 </td><td>
2719 </td><td>
2699 create a bundle file
2720 create a bundle file
2700 </td></tr>
2721 </td></tr>
2701 <tr><td>
2722 <tr><td>
2702 <a href="/help/cat">
2723 <a href="/help/cat">
2703 cat
2724 cat
2704 </a>
2725 </a>
2705 </td><td>
2726 </td><td>
2706 output the current or given revision of files
2727 output the current or given revision of files
2707 </td></tr>
2728 </td></tr>
2708 <tr><td>
2729 <tr><td>
2709 <a href="/help/config">
2730 <a href="/help/config">
2710 config
2731 config
2711 </a>
2732 </a>
2712 </td><td>
2733 </td><td>
2713 show combined config settings from all hgrc files
2734 show combined config settings from all hgrc files
2714 </td></tr>
2735 </td></tr>
2715 <tr><td>
2736 <tr><td>
2716 <a href="/help/copy">
2737 <a href="/help/copy">
2717 copy
2738 copy
2718 </a>
2739 </a>
2719 </td><td>
2740 </td><td>
2720 mark files as copied for the next commit
2741 mark files as copied for the next commit
2721 </td></tr>
2742 </td></tr>
2722 <tr><td>
2743 <tr><td>
2723 <a href="/help/files">
2744 <a href="/help/files">
2724 files
2745 files
2725 </a>
2746 </a>
2726 </td><td>
2747 </td><td>
2727 list tracked files
2748 list tracked files
2728 </td></tr>
2749 </td></tr>
2729 <tr><td>
2750 <tr><td>
2730 <a href="/help/graft">
2751 <a href="/help/graft">
2731 graft
2752 graft
2732 </a>
2753 </a>
2733 </td><td>
2754 </td><td>
2734 copy changes from other branches onto the current branch
2755 copy changes from other branches onto the current branch
2735 </td></tr>
2756 </td></tr>
2736 <tr><td>
2757 <tr><td>
2737 <a href="/help/grep">
2758 <a href="/help/grep">
2738 grep
2759 grep
2739 </a>
2760 </a>
2740 </td><td>
2761 </td><td>
2741 search for a pattern in specified files
2762 search for a pattern in specified files
2742 </td></tr>
2763 </td></tr>
2743 <tr><td>
2764 <tr><td>
2744 <a href="/help/hashelp">
2765 <a href="/help/hashelp">
2745 hashelp
2766 hashelp
2746 </a>
2767 </a>
2747 </td><td>
2768 </td><td>
2748 Extension command's help
2769 Extension command's help
2749 </td></tr>
2770 </td></tr>
2750 <tr><td>
2771 <tr><td>
2751 <a href="/help/heads">
2772 <a href="/help/heads">
2752 heads
2773 heads
2753 </a>
2774 </a>
2754 </td><td>
2775 </td><td>
2755 show branch heads
2776 show branch heads
2756 </td></tr>
2777 </td></tr>
2757 <tr><td>
2778 <tr><td>
2758 <a href="/help/help">
2779 <a href="/help/help">
2759 help
2780 help
2760 </a>
2781 </a>
2761 </td><td>
2782 </td><td>
2762 show help for a given topic or a help overview
2783 show help for a given topic or a help overview
2763 </td></tr>
2784 </td></tr>
2764 <tr><td>
2785 <tr><td>
2765 <a href="/help/hgalias">
2786 <a href="/help/hgalias">
2766 hgalias
2787 hgalias
2767 </a>
2788 </a>
2768 </td><td>
2789 </td><td>
2769 My doc
2790 My doc
2770 </td></tr>
2791 </td></tr>
2771 <tr><td>
2792 <tr><td>
2772 <a href="/help/hgaliasnodoc">
2793 <a href="/help/hgaliasnodoc">
2773 hgaliasnodoc
2794 hgaliasnodoc
2774 </a>
2795 </a>
2775 </td><td>
2796 </td><td>
2776 summarize working directory state
2797 summarize working directory state
2777 </td></tr>
2798 </td></tr>
2778 <tr><td>
2799 <tr><td>
2779 <a href="/help/identify">
2800 <a href="/help/identify">
2780 identify
2801 identify
2781 </a>
2802 </a>
2782 </td><td>
2803 </td><td>
2783 identify the working directory or specified revision
2804 identify the working directory or specified revision
2784 </td></tr>
2805 </td></tr>
2785 <tr><td>
2806 <tr><td>
2786 <a href="/help/import">
2807 <a href="/help/import">
2787 import
2808 import
2788 </a>
2809 </a>
2789 </td><td>
2810 </td><td>
2790 import an ordered set of patches
2811 import an ordered set of patches
2791 </td></tr>
2812 </td></tr>
2792 <tr><td>
2813 <tr><td>
2793 <a href="/help/incoming">
2814 <a href="/help/incoming">
2794 incoming
2815 incoming
2795 </a>
2816 </a>
2796 </td><td>
2817 </td><td>
2797 show new changesets found in source
2818 show new changesets found in source
2798 </td></tr>
2819 </td></tr>
2799 <tr><td>
2820 <tr><td>
2800 <a href="/help/manifest">
2821 <a href="/help/manifest">
2801 manifest
2822 manifest
2802 </a>
2823 </a>
2803 </td><td>
2824 </td><td>
2804 output the current or given revision of the project manifest
2825 output the current or given revision of the project manifest
2805 </td></tr>
2826 </td></tr>
2806 <tr><td>
2827 <tr><td>
2807 <a href="/help/nohelp">
2828 <a href="/help/nohelp">
2808 nohelp
2829 nohelp
2809 </a>
2830 </a>
2810 </td><td>
2831 </td><td>
2811 (no help text available)
2832 (no help text available)
2812 </td></tr>
2833 </td></tr>
2813 <tr><td>
2834 <tr><td>
2814 <a href="/help/outgoing">
2835 <a href="/help/outgoing">
2815 outgoing
2836 outgoing
2816 </a>
2837 </a>
2817 </td><td>
2838 </td><td>
2818 show changesets not found in the destination
2839 show changesets not found in the destination
2819 </td></tr>
2840 </td></tr>
2820 <tr><td>
2841 <tr><td>
2821 <a href="/help/paths">
2842 <a href="/help/paths">
2822 paths
2843 paths
2823 </a>
2844 </a>
2824 </td><td>
2845 </td><td>
2825 show aliases for remote repositories
2846 show aliases for remote repositories
2826 </td></tr>
2847 </td></tr>
2827 <tr><td>
2848 <tr><td>
2828 <a href="/help/phase">
2849 <a href="/help/phase">
2829 phase
2850 phase
2830 </a>
2851 </a>
2831 </td><td>
2852 </td><td>
2832 set or show the current phase name
2853 set or show the current phase name
2833 </td></tr>
2854 </td></tr>
2834 <tr><td>
2855 <tr><td>
2835 <a href="/help/purge">
2856 <a href="/help/purge">
2836 purge
2857 purge
2837 </a>
2858 </a>
2838 </td><td>
2859 </td><td>
2839 removes files not tracked by Mercurial
2860 removes files not tracked by Mercurial
2840 </td></tr>
2861 </td></tr>
2841 <tr><td>
2862 <tr><td>
2842 <a href="/help/recover">
2863 <a href="/help/recover">
2843 recover
2864 recover
2844 </a>
2865 </a>
2845 </td><td>
2866 </td><td>
2846 roll back an interrupted transaction
2867 roll back an interrupted transaction
2847 </td></tr>
2868 </td></tr>
2848 <tr><td>
2869 <tr><td>
2849 <a href="/help/rename">
2870 <a href="/help/rename">
2850 rename
2871 rename
2851 </a>
2872 </a>
2852 </td><td>
2873 </td><td>
2853 rename files; equivalent of copy + remove
2874 rename files; equivalent of copy + remove
2854 </td></tr>
2875 </td></tr>
2855 <tr><td>
2876 <tr><td>
2856 <a href="/help/resolve">
2877 <a href="/help/resolve">
2857 resolve
2878 resolve
2858 </a>
2879 </a>
2859 </td><td>
2880 </td><td>
2860 redo merges or set/view the merge status of files
2881 redo merges or set/view the merge status of files
2861 </td></tr>
2882 </td></tr>
2862 <tr><td>
2883 <tr><td>
2863 <a href="/help/revert">
2884 <a href="/help/revert">
2864 revert
2885 revert
2865 </a>
2886 </a>
2866 </td><td>
2887 </td><td>
2867 restore files to their checkout state
2888 restore files to their checkout state
2868 </td></tr>
2889 </td></tr>
2869 <tr><td>
2890 <tr><td>
2870 <a href="/help/root">
2891 <a href="/help/root">
2871 root
2892 root
2872 </a>
2893 </a>
2873 </td><td>
2894 </td><td>
2874 print the root (top) of the current working directory
2895 print the root (top) of the current working directory
2875 </td></tr>
2896 </td></tr>
2876 <tr><td>
2897 <tr><td>
2877 <a href="/help/shellalias">
2898 <a href="/help/shellalias">
2878 shellalias
2899 shellalias
2879 </a>
2900 </a>
2880 </td><td>
2901 </td><td>
2881 (no help text available)
2902 (no help text available)
2882 </td></tr>
2903 </td></tr>
2883 <tr><td>
2904 <tr><td>
2884 <a href="/help/shelve">
2905 <a href="/help/shelve">
2885 shelve
2906 shelve
2886 </a>
2907 </a>
2887 </td><td>
2908 </td><td>
2888 save and set aside changes from the working directory
2909 save and set aside changes from the working directory
2889 </td></tr>
2910 </td></tr>
2890 <tr><td>
2911 <tr><td>
2891 <a href="/help/tag">
2912 <a href="/help/tag">
2892 tag
2913 tag
2893 </a>
2914 </a>
2894 </td><td>
2915 </td><td>
2895 add one or more tags for the current or given revision
2916 add one or more tags for the current or given revision
2896 </td></tr>
2917 </td></tr>
2897 <tr><td>
2918 <tr><td>
2898 <a href="/help/tags">
2919 <a href="/help/tags">
2899 tags
2920 tags
2900 </a>
2921 </a>
2901 </td><td>
2922 </td><td>
2902 list repository tags
2923 list repository tags
2903 </td></tr>
2924 </td></tr>
2904 <tr><td>
2925 <tr><td>
2905 <a href="/help/unbundle">
2926 <a href="/help/unbundle">
2906 unbundle
2927 unbundle
2907 </a>
2928 </a>
2908 </td><td>
2929 </td><td>
2909 apply one or more bundle files
2930 apply one or more bundle files
2910 </td></tr>
2931 </td></tr>
2911 <tr><td>
2932 <tr><td>
2912 <a href="/help/unshelve">
2933 <a href="/help/unshelve">
2913 unshelve
2934 unshelve
2914 </a>
2935 </a>
2915 </td><td>
2936 </td><td>
2916 restore a shelved change to the working directory
2937 restore a shelved change to the working directory
2917 </td></tr>
2938 </td></tr>
2918 <tr><td>
2939 <tr><td>
2919 <a href="/help/verify">
2940 <a href="/help/verify">
2920 verify
2941 verify
2921 </a>
2942 </a>
2922 </td><td>
2943 </td><td>
2923 verify the integrity of the repository
2944 verify the integrity of the repository
2924 </td></tr>
2945 </td></tr>
2925 <tr><td>
2946 <tr><td>
2926 <a href="/help/version">
2947 <a href="/help/version">
2927 version
2948 version
2928 </a>
2949 </a>
2929 </td><td>
2950 </td><td>
2930 output version and copyright information
2951 output version and copyright information
2931 </td></tr>
2952 </td></tr>
2932
2953
2933
2954
2934 </table>
2955 </table>
2935 </div>
2956 </div>
2936 </div>
2957 </div>
2937
2958
2938
2959
2939
2960
2940 </body>
2961 </body>
2941 </html>
2962 </html>
2942
2963
2943
2964
2944 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2965 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2945 200 Script output follows
2966 200 Script output follows
2946
2967
2947 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2968 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2948 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2969 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2949 <head>
2970 <head>
2950 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2971 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2951 <meta name="robots" content="index, nofollow" />
2972 <meta name="robots" content="index, nofollow" />
2952 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2973 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2953 <script type="text/javascript" src="/static/mercurial.js"></script>
2974 <script type="text/javascript" src="/static/mercurial.js"></script>
2954
2975
2955 <title>Help: add</title>
2976 <title>Help: add</title>
2956 </head>
2977 </head>
2957 <body>
2978 <body>
2958
2979
2959 <div class="container">
2980 <div class="container">
2960 <div class="menu">
2981 <div class="menu">
2961 <div class="logo">
2982 <div class="logo">
2962 <a href="https://mercurial-scm.org/">
2983 <a href="https://mercurial-scm.org/">
2963 <img src="/static/hglogo.png" alt="mercurial" /></a>
2984 <img src="/static/hglogo.png" alt="mercurial" /></a>
2964 </div>
2985 </div>
2965 <ul>
2986 <ul>
2966 <li><a href="/shortlog">log</a></li>
2987 <li><a href="/shortlog">log</a></li>
2967 <li><a href="/graph">graph</a></li>
2988 <li><a href="/graph">graph</a></li>
2968 <li><a href="/tags">tags</a></li>
2989 <li><a href="/tags">tags</a></li>
2969 <li><a href="/bookmarks">bookmarks</a></li>
2990 <li><a href="/bookmarks">bookmarks</a></li>
2970 <li><a href="/branches">branches</a></li>
2991 <li><a href="/branches">branches</a></li>
2971 </ul>
2992 </ul>
2972 <ul>
2993 <ul>
2973 <li class="active"><a href="/help">help</a></li>
2994 <li class="active"><a href="/help">help</a></li>
2974 </ul>
2995 </ul>
2975 </div>
2996 </div>
2976
2997
2977 <div class="main">
2998 <div class="main">
2978 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2999 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2979 <h3>Help: add</h3>
3000 <h3>Help: add</h3>
2980
3001
2981 <form class="search" action="/log">
3002 <form class="search" action="/log">
2982
3003
2983 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3004 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2984 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3005 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2985 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3006 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2986 </form>
3007 </form>
2987 <div id="doc">
3008 <div id="doc">
2988 <p>
3009 <p>
2989 hg add [OPTION]... [FILE]...
3010 hg add [OPTION]... [FILE]...
2990 </p>
3011 </p>
2991 <p>
3012 <p>
2992 add the specified files on the next commit
3013 add the specified files on the next commit
2993 </p>
3014 </p>
2994 <p>
3015 <p>
2995 Schedule files to be version controlled and added to the
3016 Schedule files to be version controlled and added to the
2996 repository.
3017 repository.
2997 </p>
3018 </p>
2998 <p>
3019 <p>
2999 The files will be added to the repository at the next commit. To
3020 The files will be added to the repository at the next commit. To
3000 undo an add before that, see 'hg forget'.
3021 undo an add before that, see 'hg forget'.
3001 </p>
3022 </p>
3002 <p>
3023 <p>
3003 If no names are given, add all files to the repository (except
3024 If no names are given, add all files to the repository (except
3004 files matching &quot;.hgignore&quot;).
3025 files matching &quot;.hgignore&quot;).
3005 </p>
3026 </p>
3006 <p>
3027 <p>
3007 Examples:
3028 Examples:
3008 </p>
3029 </p>
3009 <ul>
3030 <ul>
3010 <li> New (unknown) files are added automatically by 'hg add':
3031 <li> New (unknown) files are added automatically by 'hg add':
3011 <pre>
3032 <pre>
3012 \$ ls (re)
3033 \$ ls (re)
3013 foo.c
3034 foo.c
3014 \$ hg status (re)
3035 \$ hg status (re)
3015 ? foo.c
3036 ? foo.c
3016 \$ hg add (re)
3037 \$ hg add (re)
3017 adding foo.c
3038 adding foo.c
3018 \$ hg status (re)
3039 \$ hg status (re)
3019 A foo.c
3040 A foo.c
3020 </pre>
3041 </pre>
3021 <li> Specific files to be added can be specified:
3042 <li> Specific files to be added can be specified:
3022 <pre>
3043 <pre>
3023 \$ ls (re)
3044 \$ ls (re)
3024 bar.c foo.c
3045 bar.c foo.c
3025 \$ hg status (re)
3046 \$ hg status (re)
3026 ? bar.c
3047 ? bar.c
3027 ? foo.c
3048 ? foo.c
3028 \$ hg add bar.c (re)
3049 \$ hg add bar.c (re)
3029 \$ hg status (re)
3050 \$ hg status (re)
3030 A bar.c
3051 A bar.c
3031 ? foo.c
3052 ? foo.c
3032 </pre>
3053 </pre>
3033 </ul>
3054 </ul>
3034 <p>
3055 <p>
3035 Returns 0 if all files are successfully added.
3056 Returns 0 if all files are successfully added.
3036 </p>
3057 </p>
3037 <p>
3058 <p>
3038 options ([+] can be repeated):
3059 options ([+] can be repeated):
3039 </p>
3060 </p>
3040 <table>
3061 <table>
3041 <tr><td>-I</td>
3062 <tr><td>-I</td>
3042 <td>--include PATTERN [+]</td>
3063 <td>--include PATTERN [+]</td>
3043 <td>include names matching the given patterns</td></tr>
3064 <td>include names matching the given patterns</td></tr>
3044 <tr><td>-X</td>
3065 <tr><td>-X</td>
3045 <td>--exclude PATTERN [+]</td>
3066 <td>--exclude PATTERN [+]</td>
3046 <td>exclude names matching the given patterns</td></tr>
3067 <td>exclude names matching the given patterns</td></tr>
3047 <tr><td>-S</td>
3068 <tr><td>-S</td>
3048 <td>--subrepos</td>
3069 <td>--subrepos</td>
3049 <td>recurse into subrepositories</td></tr>
3070 <td>recurse into subrepositories</td></tr>
3050 <tr><td>-n</td>
3071 <tr><td>-n</td>
3051 <td>--dry-run</td>
3072 <td>--dry-run</td>
3052 <td>do not perform actions, just print output</td></tr>
3073 <td>do not perform actions, just print output</td></tr>
3053 </table>
3074 </table>
3054 <p>
3075 <p>
3055 global options ([+] can be repeated):
3076 global options ([+] can be repeated):
3056 </p>
3077 </p>
3057 <table>
3078 <table>
3058 <tr><td>-R</td>
3079 <tr><td>-R</td>
3059 <td>--repository REPO</td>
3080 <td>--repository REPO</td>
3060 <td>repository root directory or name of overlay bundle file</td></tr>
3081 <td>repository root directory or name of overlay bundle file</td></tr>
3061 <tr><td></td>
3082 <tr><td></td>
3062 <td>--cwd DIR</td>
3083 <td>--cwd DIR</td>
3063 <td>change working directory</td></tr>
3084 <td>change working directory</td></tr>
3064 <tr><td>-y</td>
3085 <tr><td>-y</td>
3065 <td>--noninteractive</td>
3086 <td>--noninteractive</td>
3066 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3087 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3067 <tr><td>-q</td>
3088 <tr><td>-q</td>
3068 <td>--quiet</td>
3089 <td>--quiet</td>
3069 <td>suppress output</td></tr>
3090 <td>suppress output</td></tr>
3070 <tr><td>-v</td>
3091 <tr><td>-v</td>
3071 <td>--verbose</td>
3092 <td>--verbose</td>
3072 <td>enable additional output</td></tr>
3093 <td>enable additional output</td></tr>
3073 <tr><td></td>
3094 <tr><td></td>
3074 <td>--color TYPE</td>
3095 <td>--color TYPE</td>
3075 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3096 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3076 <tr><td></td>
3097 <tr><td></td>
3077 <td>--config CONFIG [+]</td>
3098 <td>--config CONFIG [+]</td>
3078 <td>set/override config option (use 'section.name=value')</td></tr>
3099 <td>set/override config option (use 'section.name=value')</td></tr>
3079 <tr><td></td>
3100 <tr><td></td>
3080 <td>--debug</td>
3101 <td>--debug</td>
3081 <td>enable debugging output</td></tr>
3102 <td>enable debugging output</td></tr>
3082 <tr><td></td>
3103 <tr><td></td>
3083 <td>--debugger</td>
3104 <td>--debugger</td>
3084 <td>start debugger</td></tr>
3105 <td>start debugger</td></tr>
3085 <tr><td></td>
3106 <tr><td></td>
3086 <td>--encoding ENCODE</td>
3107 <td>--encoding ENCODE</td>
3087 <td>set the charset encoding (default: ascii)</td></tr>
3108 <td>set the charset encoding (default: ascii)</td></tr>
3088 <tr><td></td>
3109 <tr><td></td>
3089 <td>--encodingmode MODE</td>
3110 <td>--encodingmode MODE</td>
3090 <td>set the charset encoding mode (default: strict)</td></tr>
3111 <td>set the charset encoding mode (default: strict)</td></tr>
3091 <tr><td></td>
3112 <tr><td></td>
3092 <td>--traceback</td>
3113 <td>--traceback</td>
3093 <td>always print a traceback on exception</td></tr>
3114 <td>always print a traceback on exception</td></tr>
3094 <tr><td></td>
3115 <tr><td></td>
3095 <td>--time</td>
3116 <td>--time</td>
3096 <td>time how long the command takes</td></tr>
3117 <td>time how long the command takes</td></tr>
3097 <tr><td></td>
3118 <tr><td></td>
3098 <td>--profile</td>
3119 <td>--profile</td>
3099 <td>print command execution profile</td></tr>
3120 <td>print command execution profile</td></tr>
3100 <tr><td></td>
3121 <tr><td></td>
3101 <td>--version</td>
3122 <td>--version</td>
3102 <td>output version information and exit</td></tr>
3123 <td>output version information and exit</td></tr>
3103 <tr><td>-h</td>
3124 <tr><td>-h</td>
3104 <td>--help</td>
3125 <td>--help</td>
3105 <td>display help and exit</td></tr>
3126 <td>display help and exit</td></tr>
3106 <tr><td></td>
3127 <tr><td></td>
3107 <td>--hidden</td>
3128 <td>--hidden</td>
3108 <td>consider hidden changesets</td></tr>
3129 <td>consider hidden changesets</td></tr>
3109 <tr><td></td>
3130 <tr><td></td>
3110 <td>--pager TYPE</td>
3131 <td>--pager TYPE</td>
3111 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3132 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3112 </table>
3133 </table>
3113
3134
3114 </div>
3135 </div>
3115 </div>
3136 </div>
3116 </div>
3137 </div>
3117
3138
3118
3139
3119
3140
3120 </body>
3141 </body>
3121 </html>
3142 </html>
3122
3143
3123
3144
3124 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
3145 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
3125 200 Script output follows
3146 200 Script output follows
3126
3147
3127 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3148 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3128 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3149 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3129 <head>
3150 <head>
3130 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3151 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3131 <meta name="robots" content="index, nofollow" />
3152 <meta name="robots" content="index, nofollow" />
3132 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3153 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3133 <script type="text/javascript" src="/static/mercurial.js"></script>
3154 <script type="text/javascript" src="/static/mercurial.js"></script>
3134
3155
3135 <title>Help: remove</title>
3156 <title>Help: remove</title>
3136 </head>
3157 </head>
3137 <body>
3158 <body>
3138
3159
3139 <div class="container">
3160 <div class="container">
3140 <div class="menu">
3161 <div class="menu">
3141 <div class="logo">
3162 <div class="logo">
3142 <a href="https://mercurial-scm.org/">
3163 <a href="https://mercurial-scm.org/">
3143 <img src="/static/hglogo.png" alt="mercurial" /></a>
3164 <img src="/static/hglogo.png" alt="mercurial" /></a>
3144 </div>
3165 </div>
3145 <ul>
3166 <ul>
3146 <li><a href="/shortlog">log</a></li>
3167 <li><a href="/shortlog">log</a></li>
3147 <li><a href="/graph">graph</a></li>
3168 <li><a href="/graph">graph</a></li>
3148 <li><a href="/tags">tags</a></li>
3169 <li><a href="/tags">tags</a></li>
3149 <li><a href="/bookmarks">bookmarks</a></li>
3170 <li><a href="/bookmarks">bookmarks</a></li>
3150 <li><a href="/branches">branches</a></li>
3171 <li><a href="/branches">branches</a></li>
3151 </ul>
3172 </ul>
3152 <ul>
3173 <ul>
3153 <li class="active"><a href="/help">help</a></li>
3174 <li class="active"><a href="/help">help</a></li>
3154 </ul>
3175 </ul>
3155 </div>
3176 </div>
3156
3177
3157 <div class="main">
3178 <div class="main">
3158 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3179 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3159 <h3>Help: remove</h3>
3180 <h3>Help: remove</h3>
3160
3181
3161 <form class="search" action="/log">
3182 <form class="search" action="/log">
3162
3183
3163 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3184 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3164 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3185 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3165 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3186 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3166 </form>
3187 </form>
3167 <div id="doc">
3188 <div id="doc">
3168 <p>
3189 <p>
3169 hg remove [OPTION]... FILE...
3190 hg remove [OPTION]... FILE...
3170 </p>
3191 </p>
3171 <p>
3192 <p>
3172 aliases: rm
3193 aliases: rm
3173 </p>
3194 </p>
3174 <p>
3195 <p>
3175 remove the specified files on the next commit
3196 remove the specified files on the next commit
3176 </p>
3197 </p>
3177 <p>
3198 <p>
3178 Schedule the indicated files for removal from the current branch.
3199 Schedule the indicated files for removal from the current branch.
3179 </p>
3200 </p>
3180 <p>
3201 <p>
3181 This command schedules the files to be removed at the next commit.
3202 This command schedules the files to be removed at the next commit.
3182 To undo a remove before that, see 'hg revert'. To undo added
3203 To undo a remove before that, see 'hg revert'. To undo added
3183 files, see 'hg forget'.
3204 files, see 'hg forget'.
3184 </p>
3205 </p>
3185 <p>
3206 <p>
3186 -A/--after can be used to remove only files that have already
3207 -A/--after can be used to remove only files that have already
3187 been deleted, -f/--force can be used to force deletion, and -Af
3208 been deleted, -f/--force can be used to force deletion, and -Af
3188 can be used to remove files from the next revision without
3209 can be used to remove files from the next revision without
3189 deleting them from the working directory.
3210 deleting them from the working directory.
3190 </p>
3211 </p>
3191 <p>
3212 <p>
3192 The following table details the behavior of remove for different
3213 The following table details the behavior of remove for different
3193 file states (columns) and option combinations (rows). The file
3214 file states (columns) and option combinations (rows). The file
3194 states are Added [A], Clean [C], Modified [M] and Missing [!]
3215 states are Added [A], Clean [C], Modified [M] and Missing [!]
3195 (as reported by 'hg status'). The actions are Warn, Remove
3216 (as reported by 'hg status'). The actions are Warn, Remove
3196 (from branch) and Delete (from disk):
3217 (from branch) and Delete (from disk):
3197 </p>
3218 </p>
3198 <table>
3219 <table>
3199 <tr><td>opt/state</td>
3220 <tr><td>opt/state</td>
3200 <td>A</td>
3221 <td>A</td>
3201 <td>C</td>
3222 <td>C</td>
3202 <td>M</td>
3223 <td>M</td>
3203 <td>!</td></tr>
3224 <td>!</td></tr>
3204 <tr><td>none</td>
3225 <tr><td>none</td>
3205 <td>W</td>
3226 <td>W</td>
3206 <td>RD</td>
3227 <td>RD</td>
3207 <td>W</td>
3228 <td>W</td>
3208 <td>R</td></tr>
3229 <td>R</td></tr>
3209 <tr><td>-f</td>
3230 <tr><td>-f</td>
3210 <td>R</td>
3231 <td>R</td>
3211 <td>RD</td>
3232 <td>RD</td>
3212 <td>RD</td>
3233 <td>RD</td>
3213 <td>R</td></tr>
3234 <td>R</td></tr>
3214 <tr><td>-A</td>
3235 <tr><td>-A</td>
3215 <td>W</td>
3236 <td>W</td>
3216 <td>W</td>
3237 <td>W</td>
3217 <td>W</td>
3238 <td>W</td>
3218 <td>R</td></tr>
3239 <td>R</td></tr>
3219 <tr><td>-Af</td>
3240 <tr><td>-Af</td>
3220 <td>R</td>
3241 <td>R</td>
3221 <td>R</td>
3242 <td>R</td>
3222 <td>R</td>
3243 <td>R</td>
3223 <td>R</td></tr>
3244 <td>R</td></tr>
3224 </table>
3245 </table>
3225 <p>
3246 <p>
3226 <b>Note:</b>
3247 <b>Note:</b>
3227 </p>
3248 </p>
3228 <p>
3249 <p>
3229 'hg remove' never deletes files in Added [A] state from the
3250 'hg remove' never deletes files in Added [A] state from the
3230 working directory, not even if &quot;--force&quot; is specified.
3251 working directory, not even if &quot;--force&quot; is specified.
3231 </p>
3252 </p>
3232 <p>
3253 <p>
3233 Returns 0 on success, 1 if any warnings encountered.
3254 Returns 0 on success, 1 if any warnings encountered.
3234 </p>
3255 </p>
3235 <p>
3256 <p>
3236 options ([+] can be repeated):
3257 options ([+] can be repeated):
3237 </p>
3258 </p>
3238 <table>
3259 <table>
3239 <tr><td>-A</td>
3260 <tr><td>-A</td>
3240 <td>--after</td>
3261 <td>--after</td>
3241 <td>record delete for missing files</td></tr>
3262 <td>record delete for missing files</td></tr>
3242 <tr><td>-f</td>
3263 <tr><td>-f</td>
3243 <td>--force</td>
3264 <td>--force</td>
3244 <td>forget added files, delete modified files</td></tr>
3265 <td>forget added files, delete modified files</td></tr>
3245 <tr><td>-S</td>
3266 <tr><td>-S</td>
3246 <td>--subrepos</td>
3267 <td>--subrepos</td>
3247 <td>recurse into subrepositories</td></tr>
3268 <td>recurse into subrepositories</td></tr>
3248 <tr><td>-I</td>
3269 <tr><td>-I</td>
3249 <td>--include PATTERN [+]</td>
3270 <td>--include PATTERN [+]</td>
3250 <td>include names matching the given patterns</td></tr>
3271 <td>include names matching the given patterns</td></tr>
3251 <tr><td>-X</td>
3272 <tr><td>-X</td>
3252 <td>--exclude PATTERN [+]</td>
3273 <td>--exclude PATTERN [+]</td>
3253 <td>exclude names matching the given patterns</td></tr>
3274 <td>exclude names matching the given patterns</td></tr>
3254 <tr><td>-n</td>
3275 <tr><td>-n</td>
3255 <td>--dry-run</td>
3276 <td>--dry-run</td>
3256 <td>do not perform actions, just print output</td></tr>
3277 <td>do not perform actions, just print output</td></tr>
3257 </table>
3278 </table>
3258 <p>
3279 <p>
3259 global options ([+] can be repeated):
3280 global options ([+] can be repeated):
3260 </p>
3281 </p>
3261 <table>
3282 <table>
3262 <tr><td>-R</td>
3283 <tr><td>-R</td>
3263 <td>--repository REPO</td>
3284 <td>--repository REPO</td>
3264 <td>repository root directory or name of overlay bundle file</td></tr>
3285 <td>repository root directory or name of overlay bundle file</td></tr>
3265 <tr><td></td>
3286 <tr><td></td>
3266 <td>--cwd DIR</td>
3287 <td>--cwd DIR</td>
3267 <td>change working directory</td></tr>
3288 <td>change working directory</td></tr>
3268 <tr><td>-y</td>
3289 <tr><td>-y</td>
3269 <td>--noninteractive</td>
3290 <td>--noninteractive</td>
3270 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3291 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3271 <tr><td>-q</td>
3292 <tr><td>-q</td>
3272 <td>--quiet</td>
3293 <td>--quiet</td>
3273 <td>suppress output</td></tr>
3294 <td>suppress output</td></tr>
3274 <tr><td>-v</td>
3295 <tr><td>-v</td>
3275 <td>--verbose</td>
3296 <td>--verbose</td>
3276 <td>enable additional output</td></tr>
3297 <td>enable additional output</td></tr>
3277 <tr><td></td>
3298 <tr><td></td>
3278 <td>--color TYPE</td>
3299 <td>--color TYPE</td>
3279 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3300 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3280 <tr><td></td>
3301 <tr><td></td>
3281 <td>--config CONFIG [+]</td>
3302 <td>--config CONFIG [+]</td>
3282 <td>set/override config option (use 'section.name=value')</td></tr>
3303 <td>set/override config option (use 'section.name=value')</td></tr>
3283 <tr><td></td>
3304 <tr><td></td>
3284 <td>--debug</td>
3305 <td>--debug</td>
3285 <td>enable debugging output</td></tr>
3306 <td>enable debugging output</td></tr>
3286 <tr><td></td>
3307 <tr><td></td>
3287 <td>--debugger</td>
3308 <td>--debugger</td>
3288 <td>start debugger</td></tr>
3309 <td>start debugger</td></tr>
3289 <tr><td></td>
3310 <tr><td></td>
3290 <td>--encoding ENCODE</td>
3311 <td>--encoding ENCODE</td>
3291 <td>set the charset encoding (default: ascii)</td></tr>
3312 <td>set the charset encoding (default: ascii)</td></tr>
3292 <tr><td></td>
3313 <tr><td></td>
3293 <td>--encodingmode MODE</td>
3314 <td>--encodingmode MODE</td>
3294 <td>set the charset encoding mode (default: strict)</td></tr>
3315 <td>set the charset encoding mode (default: strict)</td></tr>
3295 <tr><td></td>
3316 <tr><td></td>
3296 <td>--traceback</td>
3317 <td>--traceback</td>
3297 <td>always print a traceback on exception</td></tr>
3318 <td>always print a traceback on exception</td></tr>
3298 <tr><td></td>
3319 <tr><td></td>
3299 <td>--time</td>
3320 <td>--time</td>
3300 <td>time how long the command takes</td></tr>
3321 <td>time how long the command takes</td></tr>
3301 <tr><td></td>
3322 <tr><td></td>
3302 <td>--profile</td>
3323 <td>--profile</td>
3303 <td>print command execution profile</td></tr>
3324 <td>print command execution profile</td></tr>
3304 <tr><td></td>
3325 <tr><td></td>
3305 <td>--version</td>
3326 <td>--version</td>
3306 <td>output version information and exit</td></tr>
3327 <td>output version information and exit</td></tr>
3307 <tr><td>-h</td>
3328 <tr><td>-h</td>
3308 <td>--help</td>
3329 <td>--help</td>
3309 <td>display help and exit</td></tr>
3330 <td>display help and exit</td></tr>
3310 <tr><td></td>
3331 <tr><td></td>
3311 <td>--hidden</td>
3332 <td>--hidden</td>
3312 <td>consider hidden changesets</td></tr>
3333 <td>consider hidden changesets</td></tr>
3313 <tr><td></td>
3334 <tr><td></td>
3314 <td>--pager TYPE</td>
3335 <td>--pager TYPE</td>
3315 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3336 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3316 </table>
3337 </table>
3317
3338
3318 </div>
3339 </div>
3319 </div>
3340 </div>
3320 </div>
3341 </div>
3321
3342
3322
3343
3323
3344
3324 </body>
3345 </body>
3325 </html>
3346 </html>
3326
3347
3327
3348
3328 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3349 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3329 200 Script output follows
3350 200 Script output follows
3330
3351
3331 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3352 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3332 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3353 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3333 <head>
3354 <head>
3334 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3355 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3335 <meta name="robots" content="index, nofollow" />
3356 <meta name="robots" content="index, nofollow" />
3336 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3357 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3337 <script type="text/javascript" src="/static/mercurial.js"></script>
3358 <script type="text/javascript" src="/static/mercurial.js"></script>
3338
3359
3339 <title>Help: dates</title>
3360 <title>Help: dates</title>
3340 </head>
3361 </head>
3341 <body>
3362 <body>
3342
3363
3343 <div class="container">
3364 <div class="container">
3344 <div class="menu">
3365 <div class="menu">
3345 <div class="logo">
3366 <div class="logo">
3346 <a href="https://mercurial-scm.org/">
3367 <a href="https://mercurial-scm.org/">
3347 <img src="/static/hglogo.png" alt="mercurial" /></a>
3368 <img src="/static/hglogo.png" alt="mercurial" /></a>
3348 </div>
3369 </div>
3349 <ul>
3370 <ul>
3350 <li><a href="/shortlog">log</a></li>
3371 <li><a href="/shortlog">log</a></li>
3351 <li><a href="/graph">graph</a></li>
3372 <li><a href="/graph">graph</a></li>
3352 <li><a href="/tags">tags</a></li>
3373 <li><a href="/tags">tags</a></li>
3353 <li><a href="/bookmarks">bookmarks</a></li>
3374 <li><a href="/bookmarks">bookmarks</a></li>
3354 <li><a href="/branches">branches</a></li>
3375 <li><a href="/branches">branches</a></li>
3355 </ul>
3376 </ul>
3356 <ul>
3377 <ul>
3357 <li class="active"><a href="/help">help</a></li>
3378 <li class="active"><a href="/help">help</a></li>
3358 </ul>
3379 </ul>
3359 </div>
3380 </div>
3360
3381
3361 <div class="main">
3382 <div class="main">
3362 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3383 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3363 <h3>Help: dates</h3>
3384 <h3>Help: dates</h3>
3364
3385
3365 <form class="search" action="/log">
3386 <form class="search" action="/log">
3366
3387
3367 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3388 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3368 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3389 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3369 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3390 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3370 </form>
3391 </form>
3371 <div id="doc">
3392 <div id="doc">
3372 <h1>Date Formats</h1>
3393 <h1>Date Formats</h1>
3373 <p>
3394 <p>
3374 Some commands allow the user to specify a date, e.g.:
3395 Some commands allow the user to specify a date, e.g.:
3375 </p>
3396 </p>
3376 <ul>
3397 <ul>
3377 <li> backout, commit, import, tag: Specify the commit date.
3398 <li> backout, commit, import, tag: Specify the commit date.
3378 <li> log, revert, update: Select revision(s) by date.
3399 <li> log, revert, update: Select revision(s) by date.
3379 </ul>
3400 </ul>
3380 <p>
3401 <p>
3381 Many date formats are valid. Here are some examples:
3402 Many date formats are valid. Here are some examples:
3382 </p>
3403 </p>
3383 <ul>
3404 <ul>
3384 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3405 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3385 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3406 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3386 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3407 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3387 <li> &quot;Dec 6&quot; (midnight)
3408 <li> &quot;Dec 6&quot; (midnight)
3388 <li> &quot;13:18&quot; (today assumed)
3409 <li> &quot;13:18&quot; (today assumed)
3389 <li> &quot;3:39&quot; (3:39AM assumed)
3410 <li> &quot;3:39&quot; (3:39AM assumed)
3390 <li> &quot;3:39pm&quot; (15:39)
3411 <li> &quot;3:39pm&quot; (15:39)
3391 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3412 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3392 <li> &quot;2006-12-6 13:18&quot;
3413 <li> &quot;2006-12-6 13:18&quot;
3393 <li> &quot;2006-12-6&quot;
3414 <li> &quot;2006-12-6&quot;
3394 <li> &quot;12-6&quot;
3415 <li> &quot;12-6&quot;
3395 <li> &quot;12/6&quot;
3416 <li> &quot;12/6&quot;
3396 <li> &quot;12/6/6&quot; (Dec 6 2006)
3417 <li> &quot;12/6/6&quot; (Dec 6 2006)
3397 <li> &quot;today&quot; (midnight)
3418 <li> &quot;today&quot; (midnight)
3398 <li> &quot;yesterday&quot; (midnight)
3419 <li> &quot;yesterday&quot; (midnight)
3399 <li> &quot;now&quot; - right now
3420 <li> &quot;now&quot; - right now
3400 </ul>
3421 </ul>
3401 <p>
3422 <p>
3402 Lastly, there is Mercurial's internal format:
3423 Lastly, there is Mercurial's internal format:
3403 </p>
3424 </p>
3404 <ul>
3425 <ul>
3405 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3426 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3406 </ul>
3427 </ul>
3407 <p>
3428 <p>
3408 This is the internal representation format for dates. The first number
3429 This is the internal representation format for dates. The first number
3409 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3430 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3410 second is the offset of the local timezone, in seconds west of UTC
3431 second is the offset of the local timezone, in seconds west of UTC
3411 (negative if the timezone is east of UTC).
3432 (negative if the timezone is east of UTC).
3412 </p>
3433 </p>
3413 <p>
3434 <p>
3414 The log command also accepts date ranges:
3435 The log command also accepts date ranges:
3415 </p>
3436 </p>
3416 <ul>
3437 <ul>
3417 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3438 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3418 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3439 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3419 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3440 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3420 <li> &quot;-DAYS&quot; - within a given number of days from today
3441 <li> &quot;-DAYS&quot; - within a given number of days from today
3421 </ul>
3442 </ul>
3422
3443
3423 </div>
3444 </div>
3424 </div>
3445 </div>
3425 </div>
3446 </div>
3426
3447
3427
3448
3428
3449
3429 </body>
3450 </body>
3430 </html>
3451 </html>
3431
3452
3432
3453
3433 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3454 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3434 200 Script output follows
3455 200 Script output follows
3435
3456
3436 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3457 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3437 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3458 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3438 <head>
3459 <head>
3439 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3460 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3440 <meta name="robots" content="index, nofollow" />
3461 <meta name="robots" content="index, nofollow" />
3441 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3462 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3442 <script type="text/javascript" src="/static/mercurial.js"></script>
3463 <script type="text/javascript" src="/static/mercurial.js"></script>
3443
3464
3444 <title>Help: pager</title>
3465 <title>Help: pager</title>
3445 </head>
3466 </head>
3446 <body>
3467 <body>
3447
3468
3448 <div class="container">
3469 <div class="container">
3449 <div class="menu">
3470 <div class="menu">
3450 <div class="logo">
3471 <div class="logo">
3451 <a href="https://mercurial-scm.org/">
3472 <a href="https://mercurial-scm.org/">
3452 <img src="/static/hglogo.png" alt="mercurial" /></a>
3473 <img src="/static/hglogo.png" alt="mercurial" /></a>
3453 </div>
3474 </div>
3454 <ul>
3475 <ul>
3455 <li><a href="/shortlog">log</a></li>
3476 <li><a href="/shortlog">log</a></li>
3456 <li><a href="/graph">graph</a></li>
3477 <li><a href="/graph">graph</a></li>
3457 <li><a href="/tags">tags</a></li>
3478 <li><a href="/tags">tags</a></li>
3458 <li><a href="/bookmarks">bookmarks</a></li>
3479 <li><a href="/bookmarks">bookmarks</a></li>
3459 <li><a href="/branches">branches</a></li>
3480 <li><a href="/branches">branches</a></li>
3460 </ul>
3481 </ul>
3461 <ul>
3482 <ul>
3462 <li class="active"><a href="/help">help</a></li>
3483 <li class="active"><a href="/help">help</a></li>
3463 </ul>
3484 </ul>
3464 </div>
3485 </div>
3465
3486
3466 <div class="main">
3487 <div class="main">
3467 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3488 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3468 <h3>Help: pager</h3>
3489 <h3>Help: pager</h3>
3469
3490
3470 <form class="search" action="/log">
3491 <form class="search" action="/log">
3471
3492
3472 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3493 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3473 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3494 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3474 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3495 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3475 </form>
3496 </form>
3476 <div id="doc">
3497 <div id="doc">
3477 <h1>Pager Support</h1>
3498 <h1>Pager Support</h1>
3478 <p>
3499 <p>
3479 Some Mercurial commands can produce a lot of output, and Mercurial will
3500 Some Mercurial commands can produce a lot of output, and Mercurial will
3480 attempt to use a pager to make those commands more pleasant.
3501 attempt to use a pager to make those commands more pleasant.
3481 </p>
3502 </p>
3482 <p>
3503 <p>
3483 To set the pager that should be used, set the application variable:
3504 To set the pager that should be used, set the application variable:
3484 </p>
3505 </p>
3485 <pre>
3506 <pre>
3486 [pager]
3507 [pager]
3487 pager = less -FRX
3508 pager = less -FRX
3488 </pre>
3509 </pre>
3489 <p>
3510 <p>
3490 If no pager is set in the user or repository configuration, Mercurial uses the
3511 If no pager is set in the user or repository configuration, Mercurial uses the
3491 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3512 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3492 or system configuration is used. If none of these are set, a default pager will
3513 or system configuration is used. If none of these are set, a default pager will
3493 be used, typically 'less' on Unix and 'more' on Windows.
3514 be used, typically 'less' on Unix and 'more' on Windows.
3494 </p>
3515 </p>
3495 <p>
3516 <p>
3496 You can disable the pager for certain commands by adding them to the
3517 You can disable the pager for certain commands by adding them to the
3497 pager.ignore list:
3518 pager.ignore list:
3498 </p>
3519 </p>
3499 <pre>
3520 <pre>
3500 [pager]
3521 [pager]
3501 ignore = version, help, update
3522 ignore = version, help, update
3502 </pre>
3523 </pre>
3503 <p>
3524 <p>
3504 To ignore global commands like 'hg version' or 'hg help', you have
3525 To ignore global commands like 'hg version' or 'hg help', you have
3505 to specify them in your user configuration file.
3526 to specify them in your user configuration file.
3506 </p>
3527 </p>
3507 <p>
3528 <p>
3508 To control whether the pager is used at all for an individual command,
3529 To control whether the pager is used at all for an individual command,
3509 you can use --pager=&lt;value&gt;:
3530 you can use --pager=&lt;value&gt;:
3510 </p>
3531 </p>
3511 <ul>
3532 <ul>
3512 <li> use as needed: 'auto'.
3533 <li> use as needed: 'auto'.
3513 <li> require the pager: 'yes' or 'on'.
3534 <li> require the pager: 'yes' or 'on'.
3514 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3535 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3515 </ul>
3536 </ul>
3516 <p>
3537 <p>
3517 To globally turn off all attempts to use a pager, set:
3538 To globally turn off all attempts to use a pager, set:
3518 </p>
3539 </p>
3519 <pre>
3540 <pre>
3520 [ui]
3541 [ui]
3521 paginate = never
3542 paginate = never
3522 </pre>
3543 </pre>
3523 <p>
3544 <p>
3524 which will prevent the pager from running.
3545 which will prevent the pager from running.
3525 </p>
3546 </p>
3526
3547
3527 </div>
3548 </div>
3528 </div>
3549 </div>
3529 </div>
3550 </div>
3530
3551
3531
3552
3532
3553
3533 </body>
3554 </body>
3534 </html>
3555 </html>
3535
3556
3536
3557
3537 Sub-topic indexes rendered properly
3558 Sub-topic indexes rendered properly
3538
3559
3539 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3560 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3540 200 Script output follows
3561 200 Script output follows
3541
3562
3542 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3563 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3543 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3564 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3544 <head>
3565 <head>
3545 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3566 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3546 <meta name="robots" content="index, nofollow" />
3567 <meta name="robots" content="index, nofollow" />
3547 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3568 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3548 <script type="text/javascript" src="/static/mercurial.js"></script>
3569 <script type="text/javascript" src="/static/mercurial.js"></script>
3549
3570
3550 <title>Help: internals</title>
3571 <title>Help: internals</title>
3551 </head>
3572 </head>
3552 <body>
3573 <body>
3553
3574
3554 <div class="container">
3575 <div class="container">
3555 <div class="menu">
3576 <div class="menu">
3556 <div class="logo">
3577 <div class="logo">
3557 <a href="https://mercurial-scm.org/">
3578 <a href="https://mercurial-scm.org/">
3558 <img src="/static/hglogo.png" alt="mercurial" /></a>
3579 <img src="/static/hglogo.png" alt="mercurial" /></a>
3559 </div>
3580 </div>
3560 <ul>
3581 <ul>
3561 <li><a href="/shortlog">log</a></li>
3582 <li><a href="/shortlog">log</a></li>
3562 <li><a href="/graph">graph</a></li>
3583 <li><a href="/graph">graph</a></li>
3563 <li><a href="/tags">tags</a></li>
3584 <li><a href="/tags">tags</a></li>
3564 <li><a href="/bookmarks">bookmarks</a></li>
3585 <li><a href="/bookmarks">bookmarks</a></li>
3565 <li><a href="/branches">branches</a></li>
3586 <li><a href="/branches">branches</a></li>
3566 </ul>
3587 </ul>
3567 <ul>
3588 <ul>
3568 <li><a href="/help">help</a></li>
3589 <li><a href="/help">help</a></li>
3569 </ul>
3590 </ul>
3570 </div>
3591 </div>
3571
3592
3572 <div class="main">
3593 <div class="main">
3573 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3594 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3574
3595
3575 <form class="search" action="/log">
3596 <form class="search" action="/log">
3576
3597
3577 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3598 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3578 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3599 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3579 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3600 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3580 </form>
3601 </form>
3581 <table class="bigtable">
3602 <table class="bigtable">
3582 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3603 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3583
3604
3584 <tr><td>
3605 <tr><td>
3585 <a href="/help/internals.bid-merge">
3606 <a href="/help/internals.bid-merge">
3586 bid-merge
3607 bid-merge
3587 </a>
3608 </a>
3588 </td><td>
3609 </td><td>
3589 Bid Merge Algorithm
3610 Bid Merge Algorithm
3590 </td></tr>
3611 </td></tr>
3591 <tr><td>
3612 <tr><td>
3592 <a href="/help/internals.bundle2">
3613 <a href="/help/internals.bundle2">
3593 bundle2
3614 bundle2
3594 </a>
3615 </a>
3595 </td><td>
3616 </td><td>
3596 Bundle2
3617 Bundle2
3597 </td></tr>
3618 </td></tr>
3598 <tr><td>
3619 <tr><td>
3599 <a href="/help/internals.bundles">
3620 <a href="/help/internals.bundles">
3600 bundles
3621 bundles
3601 </a>
3622 </a>
3602 </td><td>
3623 </td><td>
3603 Bundles
3624 Bundles
3604 </td></tr>
3625 </td></tr>
3605 <tr><td>
3626 <tr><td>
3606 <a href="/help/internals.cbor">
3627 <a href="/help/internals.cbor">
3607 cbor
3628 cbor
3608 </a>
3629 </a>
3609 </td><td>
3630 </td><td>
3610 CBOR
3631 CBOR
3611 </td></tr>
3632 </td></tr>
3612 <tr><td>
3633 <tr><td>
3613 <a href="/help/internals.censor">
3634 <a href="/help/internals.censor">
3614 censor
3635 censor
3615 </a>
3636 </a>
3616 </td><td>
3637 </td><td>
3617 Censor
3638 Censor
3618 </td></tr>
3639 </td></tr>
3619 <tr><td>
3640 <tr><td>
3620 <a href="/help/internals.changegroups">
3641 <a href="/help/internals.changegroups">
3621 changegroups
3642 changegroups
3622 </a>
3643 </a>
3623 </td><td>
3644 </td><td>
3624 Changegroups
3645 Changegroups
3625 </td></tr>
3646 </td></tr>
3626 <tr><td>
3647 <tr><td>
3627 <a href="/help/internals.config">
3648 <a href="/help/internals.config">
3628 config
3649 config
3629 </a>
3650 </a>
3630 </td><td>
3651 </td><td>
3631 Config Registrar
3652 Config Registrar
3632 </td></tr>
3653 </td></tr>
3633 <tr><td>
3654 <tr><td>
3634 <a href="/help/internals.dirstate-v2">
3655 <a href="/help/internals.dirstate-v2">
3635 dirstate-v2
3656 dirstate-v2
3636 </a>
3657 </a>
3637 </td><td>
3658 </td><td>
3638 dirstate-v2 file format
3659 dirstate-v2 file format
3639 </td></tr>
3660 </td></tr>
3640 <tr><td>
3661 <tr><td>
3641 <a href="/help/internals.extensions">
3662 <a href="/help/internals.extensions">
3642 extensions
3663 extensions
3643 </a>
3664 </a>
3644 </td><td>
3665 </td><td>
3645 Extension API
3666 Extension API
3646 </td></tr>
3667 </td></tr>
3647 <tr><td>
3668 <tr><td>
3648 <a href="/help/internals.mergestate">
3669 <a href="/help/internals.mergestate">
3649 mergestate
3670 mergestate
3650 </a>
3671 </a>
3651 </td><td>
3672 </td><td>
3652 Mergestate
3673 Mergestate
3653 </td></tr>
3674 </td></tr>
3654 <tr><td>
3675 <tr><td>
3655 <a href="/help/internals.requirements">
3676 <a href="/help/internals.requirements">
3656 requirements
3677 requirements
3657 </a>
3678 </a>
3658 </td><td>
3679 </td><td>
3659 Repository Requirements
3680 Repository Requirements
3660 </td></tr>
3681 </td></tr>
3661 <tr><td>
3682 <tr><td>
3662 <a href="/help/internals.revlogs">
3683 <a href="/help/internals.revlogs">
3663 revlogs
3684 revlogs
3664 </a>
3685 </a>
3665 </td><td>
3686 </td><td>
3666 Revision Logs
3687 Revision Logs
3667 </td></tr>
3688 </td></tr>
3668 <tr><td>
3689 <tr><td>
3669 <a href="/help/internals.wireprotocol">
3690 <a href="/help/internals.wireprotocol">
3670 wireprotocol
3691 wireprotocol
3671 </a>
3692 </a>
3672 </td><td>
3693 </td><td>
3673 Wire Protocol
3694 Wire Protocol
3674 </td></tr>
3695 </td></tr>
3675 <tr><td>
3696 <tr><td>
3676 <a href="/help/internals.wireprotocolrpc">
3697 <a href="/help/internals.wireprotocolrpc">
3677 wireprotocolrpc
3698 wireprotocolrpc
3678 </a>
3699 </a>
3679 </td><td>
3700 </td><td>
3680 Wire Protocol RPC
3701 Wire Protocol RPC
3681 </td></tr>
3702 </td></tr>
3682 <tr><td>
3703 <tr><td>
3683 <a href="/help/internals.wireprotocolv2">
3704 <a href="/help/internals.wireprotocolv2">
3684 wireprotocolv2
3705 wireprotocolv2
3685 </a>
3706 </a>
3686 </td><td>
3707 </td><td>
3687 Wire Protocol Version 2
3708 Wire Protocol Version 2
3688 </td></tr>
3709 </td></tr>
3689
3710
3690
3711
3691
3712
3692
3713
3693
3714
3694 </table>
3715 </table>
3695 </div>
3716 </div>
3696 </div>
3717 </div>
3697
3718
3698
3719
3699
3720
3700 </body>
3721 </body>
3701 </html>
3722 </html>
3702
3723
3703
3724
3704 Sub-topic topics rendered properly
3725 Sub-topic topics rendered properly
3705
3726
3706 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3727 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3707 200 Script output follows
3728 200 Script output follows
3708
3729
3709 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3730 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3710 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3731 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3711 <head>
3732 <head>
3712 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3733 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3713 <meta name="robots" content="index, nofollow" />
3734 <meta name="robots" content="index, nofollow" />
3714 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3735 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3715 <script type="text/javascript" src="/static/mercurial.js"></script>
3736 <script type="text/javascript" src="/static/mercurial.js"></script>
3716
3737
3717 <title>Help: internals.changegroups</title>
3738 <title>Help: internals.changegroups</title>
3718 </head>
3739 </head>
3719 <body>
3740 <body>
3720
3741
3721 <div class="container">
3742 <div class="container">
3722 <div class="menu">
3743 <div class="menu">
3723 <div class="logo">
3744 <div class="logo">
3724 <a href="https://mercurial-scm.org/">
3745 <a href="https://mercurial-scm.org/">
3725 <img src="/static/hglogo.png" alt="mercurial" /></a>
3746 <img src="/static/hglogo.png" alt="mercurial" /></a>
3726 </div>
3747 </div>
3727 <ul>
3748 <ul>
3728 <li><a href="/shortlog">log</a></li>
3749 <li><a href="/shortlog">log</a></li>
3729 <li><a href="/graph">graph</a></li>
3750 <li><a href="/graph">graph</a></li>
3730 <li><a href="/tags">tags</a></li>
3751 <li><a href="/tags">tags</a></li>
3731 <li><a href="/bookmarks">bookmarks</a></li>
3752 <li><a href="/bookmarks">bookmarks</a></li>
3732 <li><a href="/branches">branches</a></li>
3753 <li><a href="/branches">branches</a></li>
3733 </ul>
3754 </ul>
3734 <ul>
3755 <ul>
3735 <li class="active"><a href="/help">help</a></li>
3756 <li class="active"><a href="/help">help</a></li>
3736 </ul>
3757 </ul>
3737 </div>
3758 </div>
3738
3759
3739 <div class="main">
3760 <div class="main">
3740 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3761 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3741 <h3>Help: internals.changegroups</h3>
3762 <h3>Help: internals.changegroups</h3>
3742
3763
3743 <form class="search" action="/log">
3764 <form class="search" action="/log">
3744
3765
3745 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3766 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3746 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3767 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3747 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3768 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3748 </form>
3769 </form>
3749 <div id="doc">
3770 <div id="doc">
3750 <h1>Changegroups</h1>
3771 <h1>Changegroups</h1>
3751 <p>
3772 <p>
3752 Changegroups are representations of repository revlog data, specifically
3773 Changegroups are representations of repository revlog data, specifically
3753 the changelog data, root/flat manifest data, treemanifest data, and
3774 the changelog data, root/flat manifest data, treemanifest data, and
3754 filelogs.
3775 filelogs.
3755 </p>
3776 </p>
3756 <p>
3777 <p>
3757 There are 4 versions of changegroups: &quot;1&quot;, &quot;2&quot;, &quot;3&quot; and &quot;4&quot;. From a
3778 There are 4 versions of changegroups: &quot;1&quot;, &quot;2&quot;, &quot;3&quot; and &quot;4&quot;. From a
3758 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3779 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3759 only difference being an additional item in the *delta header*. Version
3780 only difference being an additional item in the *delta header*. Version
3760 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3781 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3761 exchanging treemanifests (enabled by setting an option on the
3782 exchanging treemanifests (enabled by setting an option on the
3762 &quot;changegroup&quot; part in the bundle2). Version &quot;4&quot; adds support for exchanging
3783 &quot;changegroup&quot; part in the bundle2). Version &quot;4&quot; adds support for exchanging
3763 sidedata (additional revision metadata not part of the digest).
3784 sidedata (additional revision metadata not part of the digest).
3764 </p>
3785 </p>
3765 <p>
3786 <p>
3766 Changegroups when not exchanging treemanifests consist of 3 logical
3787 Changegroups when not exchanging treemanifests consist of 3 logical
3767 segments:
3788 segments:
3768 </p>
3789 </p>
3769 <pre>
3790 <pre>
3770 +---------------------------------+
3791 +---------------------------------+
3771 | | | |
3792 | | | |
3772 | changeset | manifest | filelogs |
3793 | changeset | manifest | filelogs |
3773 | | | |
3794 | | | |
3774 | | | |
3795 | | | |
3775 +---------------------------------+
3796 +---------------------------------+
3776 </pre>
3797 </pre>
3777 <p>
3798 <p>
3778 When exchanging treemanifests, there are 4 logical segments:
3799 When exchanging treemanifests, there are 4 logical segments:
3779 </p>
3800 </p>
3780 <pre>
3801 <pre>
3781 +-------------------------------------------------+
3802 +-------------------------------------------------+
3782 | | | | |
3803 | | | | |
3783 | changeset | root | treemanifests | filelogs |
3804 | changeset | root | treemanifests | filelogs |
3784 | | manifest | | |
3805 | | manifest | | |
3785 | | | | |
3806 | | | | |
3786 +-------------------------------------------------+
3807 +-------------------------------------------------+
3787 </pre>
3808 </pre>
3788 <p>
3809 <p>
3789 The principle building block of each segment is a *chunk*. A *chunk*
3810 The principle building block of each segment is a *chunk*. A *chunk*
3790 is a framed piece of data:
3811 is a framed piece of data:
3791 </p>
3812 </p>
3792 <pre>
3813 <pre>
3793 +---------------------------------------+
3814 +---------------------------------------+
3794 | | |
3815 | | |
3795 | length | data |
3816 | length | data |
3796 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3817 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3797 | | |
3818 | | |
3798 +---------------------------------------+
3819 +---------------------------------------+
3799 </pre>
3820 </pre>
3800 <p>
3821 <p>
3801 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3822 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3802 integer indicating the length of the entire chunk (including the length field
3823 integer indicating the length of the entire chunk (including the length field
3803 itself).
3824 itself).
3804 </p>
3825 </p>
3805 <p>
3826 <p>
3806 There is a special case chunk that has a value of 0 for the length
3827 There is a special case chunk that has a value of 0 for the length
3807 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3828 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3808 </p>
3829 </p>
3809 <h2>Delta Groups</h2>
3830 <h2>Delta Groups</h2>
3810 <p>
3831 <p>
3811 A *delta group* expresses the content of a revlog as a series of deltas,
3832 A *delta group* expresses the content of a revlog as a series of deltas,
3812 or patches against previous revisions.
3833 or patches against previous revisions.
3813 </p>
3834 </p>
3814 <p>
3835 <p>
3815 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3836 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3816 to signal the end of the delta group:
3837 to signal the end of the delta group:
3817 </p>
3838 </p>
3818 <pre>
3839 <pre>
3819 +------------------------------------------------------------------------+
3840 +------------------------------------------------------------------------+
3820 | | | | | |
3841 | | | | | |
3821 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3842 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3822 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3843 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3823 | | | | | |
3844 | | | | | |
3824 +------------------------------------------------------------------------+
3845 +------------------------------------------------------------------------+
3825 </pre>
3846 </pre>
3826 <p>
3847 <p>
3827 Each *chunk*'s data consists of the following:
3848 Each *chunk*'s data consists of the following:
3828 </p>
3849 </p>
3829 <pre>
3850 <pre>
3830 +---------------------------------------+
3851 +---------------------------------------+
3831 | | |
3852 | | |
3832 | delta header | delta data |
3853 | delta header | delta data |
3833 | (various by version) | (various) |
3854 | (various by version) | (various) |
3834 | | |
3855 | | |
3835 +---------------------------------------+
3856 +---------------------------------------+
3836 </pre>
3857 </pre>
3837 <p>
3858 <p>
3838 The *delta data* is a series of *delta*s that describe a diff from an existing
3859 The *delta data* is a series of *delta*s that describe a diff from an existing
3839 entry (either that the recipient already has, or previously specified in the
3860 entry (either that the recipient already has, or previously specified in the
3840 bundle/changegroup).
3861 bundle/changegroup).
3841 </p>
3862 </p>
3842 <p>
3863 <p>
3843 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, &quot;3&quot; and &quot;4&quot;
3864 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, &quot;3&quot; and &quot;4&quot;
3844 of the changegroup format.
3865 of the changegroup format.
3845 </p>
3866 </p>
3846 <p>
3867 <p>
3847 Version 1 (headerlen=80):
3868 Version 1 (headerlen=80):
3848 </p>
3869 </p>
3849 <pre>
3870 <pre>
3850 +------------------------------------------------------+
3871 +------------------------------------------------------+
3851 | | | | |
3872 | | | | |
3852 | node | p1 node | p2 node | link node |
3873 | node | p1 node | p2 node | link node |
3853 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3874 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3854 | | | | |
3875 | | | | |
3855 +------------------------------------------------------+
3876 +------------------------------------------------------+
3856 </pre>
3877 </pre>
3857 <p>
3878 <p>
3858 Version 2 (headerlen=100):
3879 Version 2 (headerlen=100):
3859 </p>
3880 </p>
3860 <pre>
3881 <pre>
3861 +------------------------------------------------------------------+
3882 +------------------------------------------------------------------+
3862 | | | | | |
3883 | | | | | |
3863 | node | p1 node | p2 node | base node | link node |
3884 | node | p1 node | p2 node | base node | link node |
3864 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3885 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3865 | | | | | |
3886 | | | | | |
3866 +------------------------------------------------------------------+
3887 +------------------------------------------------------------------+
3867 </pre>
3888 </pre>
3868 <p>
3889 <p>
3869 Version 3 (headerlen=102):
3890 Version 3 (headerlen=102):
3870 </p>
3891 </p>
3871 <pre>
3892 <pre>
3872 +------------------------------------------------------------------------------+
3893 +------------------------------------------------------------------------------+
3873 | | | | | | |
3894 | | | | | | |
3874 | node | p1 node | p2 node | base node | link node | flags |
3895 | node | p1 node | p2 node | base node | link node | flags |
3875 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3896 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3876 | | | | | | |
3897 | | | | | | |
3877 +------------------------------------------------------------------------------+
3898 +------------------------------------------------------------------------------+
3878 </pre>
3899 </pre>
3879 <p>
3900 <p>
3880 Version 4 (headerlen=103):
3901 Version 4 (headerlen=103):
3881 </p>
3902 </p>
3882 <pre>
3903 <pre>
3883 +------------------------------------------------------------------------------+----------+
3904 +------------------------------------------------------------------------------+----------+
3884 | | | | | | | |
3905 | | | | | | | |
3885 | node | p1 node | p2 node | base node | link node | flags | pflags |
3906 | node | p1 node | p2 node | base node | link node | flags | pflags |
3886 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) | (1 byte) |
3907 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) | (1 byte) |
3887 | | | | | | | |
3908 | | | | | | | |
3888 +------------------------------------------------------------------------------+----------+
3909 +------------------------------------------------------------------------------+----------+
3889 </pre>
3910 </pre>
3890 <p>
3911 <p>
3891 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3912 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3892 series of *delta*s, densely packed (no separators). These deltas describe a diff
3913 series of *delta*s, densely packed (no separators). These deltas describe a diff
3893 from an existing entry (either that the recipient already has, or previously
3914 from an existing entry (either that the recipient already has, or previously
3894 specified in the bundle/changegroup). The format is described more fully in
3915 specified in the bundle/changegroup). The format is described more fully in
3895 &quot;hg help internals.bdiff&quot;, but briefly:
3916 &quot;hg help internals.bdiff&quot;, but briefly:
3896 </p>
3917 </p>
3897 <pre>
3918 <pre>
3898 +---------------------------------------------------------------+
3919 +---------------------------------------------------------------+
3899 | | | | |
3920 | | | | |
3900 | start offset | end offset | new length | content |
3921 | start offset | end offset | new length | content |
3901 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3922 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3902 | | | | |
3923 | | | | |
3903 +---------------------------------------------------------------+
3924 +---------------------------------------------------------------+
3904 </pre>
3925 </pre>
3905 <p>
3926 <p>
3906 Please note that the length field in the delta data does *not* include itself.
3927 Please note that the length field in the delta data does *not* include itself.
3907 </p>
3928 </p>
3908 <p>
3929 <p>
3909 In version 1, the delta is always applied against the previous node from
3930 In version 1, the delta is always applied against the previous node from
3910 the changegroup or the first parent if this is the first entry in the
3931 the changegroup or the first parent if this is the first entry in the
3911 changegroup.
3932 changegroup.
3912 </p>
3933 </p>
3913 <p>
3934 <p>
3914 In version 2 and up, the delta base node is encoded in the entry in the
3935 In version 2 and up, the delta base node is encoded in the entry in the
3915 changegroup. This allows the delta to be expressed against any parent,
3936 changegroup. This allows the delta to be expressed against any parent,
3916 which can result in smaller deltas and more efficient encoding of data.
3937 which can result in smaller deltas and more efficient encoding of data.
3917 </p>
3938 </p>
3918 <p>
3939 <p>
3919 The *flags* field holds bitwise flags affecting the processing of revision
3940 The *flags* field holds bitwise flags affecting the processing of revision
3920 data. The following flags are defined:
3941 data. The following flags are defined:
3921 </p>
3942 </p>
3922 <dl>
3943 <dl>
3923 <dt>32768
3944 <dt>32768
3924 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3945 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3925 <dt>16384
3946 <dt>16384
3926 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3947 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3927 <dt>8192
3948 <dt>8192
3928 <dd>Externally stored. The revision fulltext contains &quot;key:value&quot; &quot;\n&quot; delimited metadata defining an object stored elsewhere. Used by the LFS extension.
3949 <dd>Externally stored. The revision fulltext contains &quot;key:value&quot; &quot;\n&quot; delimited metadata defining an object stored elsewhere. Used by the LFS extension.
3929 <dt>4096
3950 <dt>4096
3930 <dd>Contains copy information. This revision changes files in a way that could affect copy tracing. This does *not* affect changegroup handling, but is relevant for other parts of Mercurial.
3951 <dd>Contains copy information. This revision changes files in a way that could affect copy tracing. This does *not* affect changegroup handling, but is relevant for other parts of Mercurial.
3931 </dl>
3952 </dl>
3932 <p>
3953 <p>
3933 For historical reasons, the integer values are identical to revlog version 1
3954 For historical reasons, the integer values are identical to revlog version 1
3934 per-revision storage flags and correspond to bits being set in this 2-byte
3955 per-revision storage flags and correspond to bits being set in this 2-byte
3935 field. Bits were allocated starting from the most-significant bit, hence the
3956 field. Bits were allocated starting from the most-significant bit, hence the
3936 reverse ordering and allocation of these flags.
3957 reverse ordering and allocation of these flags.
3937 </p>
3958 </p>
3938 <p>
3959 <p>
3939 The *pflags* (protocol flags) field holds bitwise flags affecting the protocol
3960 The *pflags* (protocol flags) field holds bitwise flags affecting the protocol
3940 itself. They are first in the header since they may affect the handling of the
3961 itself. They are first in the header since they may affect the handling of the
3941 rest of the fields in a future version. They are defined as such:
3962 rest of the fields in a future version. They are defined as such:
3942 </p>
3963 </p>
3943 <dl>
3964 <dl>
3944 <dt>1 indicates whether to read a chunk of sidedata (of variable length) right
3965 <dt>1 indicates whether to read a chunk of sidedata (of variable length) right
3945 <dd>after the revision flags.
3966 <dd>after the revision flags.
3946 </dl>
3967 </dl>
3947 <h2>Changeset Segment</h2>
3968 <h2>Changeset Segment</h2>
3948 <p>
3969 <p>
3949 The *changeset segment* consists of a single *delta group* holding
3970 The *changeset segment* consists of a single *delta group* holding
3950 changelog data. The *empty chunk* at the end of the *delta group* denotes
3971 changelog data. The *empty chunk* at the end of the *delta group* denotes
3951 the boundary to the *manifest segment*.
3972 the boundary to the *manifest segment*.
3952 </p>
3973 </p>
3953 <h2>Manifest Segment</h2>
3974 <h2>Manifest Segment</h2>
3954 <p>
3975 <p>
3955 The *manifest segment* consists of a single *delta group* holding manifest
3976 The *manifest segment* consists of a single *delta group* holding manifest
3956 data. If treemanifests are in use, it contains only the manifest for the
3977 data. If treemanifests are in use, it contains only the manifest for the
3957 root directory of the repository. Otherwise, it contains the entire
3978 root directory of the repository. Otherwise, it contains the entire
3958 manifest data. The *empty chunk* at the end of the *delta group* denotes
3979 manifest data. The *empty chunk* at the end of the *delta group* denotes
3959 the boundary to the next segment (either the *treemanifests segment* or the
3980 the boundary to the next segment (either the *treemanifests segment* or the
3960 *filelogs segment*, depending on version and the request options).
3981 *filelogs segment*, depending on version and the request options).
3961 </p>
3982 </p>
3962 <h3>Treemanifests Segment</h3>
3983 <h3>Treemanifests Segment</h3>
3963 <p>
3984 <p>
3964 The *treemanifests segment* only exists in changegroup version &quot;3&quot; and &quot;4&quot;,
3985 The *treemanifests segment* only exists in changegroup version &quot;3&quot; and &quot;4&quot;,
3965 and only if the 'treemanifest' param is part of the bundle2 changegroup part
3986 and only if the 'treemanifest' param is part of the bundle2 changegroup part
3966 (it is not possible to use changegroup version 3 or 4 outside of bundle2).
3987 (it is not possible to use changegroup version 3 or 4 outside of bundle2).
3967 Aside from the filenames in the *treemanifests segment* containing a
3988 Aside from the filenames in the *treemanifests segment* containing a
3968 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3989 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3969 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3990 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3970 a sub-segment with filename size 0). This denotes the boundary to the
3991 a sub-segment with filename size 0). This denotes the boundary to the
3971 *filelogs segment*.
3992 *filelogs segment*.
3972 </p>
3993 </p>
3973 <h2>Filelogs Segment</h2>
3994 <h2>Filelogs Segment</h2>
3974 <p>
3995 <p>
3975 The *filelogs segment* consists of multiple sub-segments, each
3996 The *filelogs segment* consists of multiple sub-segments, each
3976 corresponding to an individual file whose data is being described:
3997 corresponding to an individual file whose data is being described:
3977 </p>
3998 </p>
3978 <pre>
3999 <pre>
3979 +--------------------------------------------------+
4000 +--------------------------------------------------+
3980 | | | | | |
4001 | | | | | |
3981 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
4002 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3982 | | | | | (4 bytes) |
4003 | | | | | (4 bytes) |
3983 | | | | | |
4004 | | | | | |
3984 +--------------------------------------------------+
4005 +--------------------------------------------------+
3985 </pre>
4006 </pre>
3986 <p>
4007 <p>
3987 The final filelog sub-segment is followed by an *empty chunk* (logically,
4008 The final filelog sub-segment is followed by an *empty chunk* (logically,
3988 a sub-segment with filename size 0). This denotes the end of the segment
4009 a sub-segment with filename size 0). This denotes the end of the segment
3989 and of the overall changegroup.
4010 and of the overall changegroup.
3990 </p>
4011 </p>
3991 <p>
4012 <p>
3992 Each filelog sub-segment consists of the following:
4013 Each filelog sub-segment consists of the following:
3993 </p>
4014 </p>
3994 <pre>
4015 <pre>
3995 +------------------------------------------------------+
4016 +------------------------------------------------------+
3996 | | | |
4017 | | | |
3997 | filename length | filename | delta group |
4018 | filename length | filename | delta group |
3998 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
4019 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3999 | | | |
4020 | | | |
4000 +------------------------------------------------------+
4021 +------------------------------------------------------+
4001 </pre>
4022 </pre>
4002 <p>
4023 <p>
4003 That is, a *chunk* consisting of the filename (not terminated or padded)
4024 That is, a *chunk* consisting of the filename (not terminated or padded)
4004 followed by N chunks constituting the *delta group* for this file. The
4025 followed by N chunks constituting the *delta group* for this file. The
4005 *empty chunk* at the end of each *delta group* denotes the boundary to the
4026 *empty chunk* at the end of each *delta group* denotes the boundary to the
4006 next filelog sub-segment.
4027 next filelog sub-segment.
4007 </p>
4028 </p>
4008
4029
4009 </div>
4030 </div>
4010 </div>
4031 </div>
4011 </div>
4032 </div>
4012
4033
4013
4034
4014
4035
4015 </body>
4036 </body>
4016 </html>
4037 </html>
4017
4038
4018
4039
4019 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
4040 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
4020 404 Not Found
4041 404 Not Found
4021
4042
4022 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4043 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4023 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
4044 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
4024 <head>
4045 <head>
4025 <link rel="icon" href="/static/hgicon.png" type="image/png" />
4046 <link rel="icon" href="/static/hgicon.png" type="image/png" />
4026 <meta name="robots" content="index, nofollow" />
4047 <meta name="robots" content="index, nofollow" />
4027 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
4048 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
4028 <script type="text/javascript" src="/static/mercurial.js"></script>
4049 <script type="text/javascript" src="/static/mercurial.js"></script>
4029
4050
4030 <title>test: error</title>
4051 <title>test: error</title>
4031 </head>
4052 </head>
4032 <body>
4053 <body>
4033
4054
4034 <div class="container">
4055 <div class="container">
4035 <div class="menu">
4056 <div class="menu">
4036 <div class="logo">
4057 <div class="logo">
4037 <a href="https://mercurial-scm.org/">
4058 <a href="https://mercurial-scm.org/">
4038 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
4059 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
4039 </div>
4060 </div>
4040 <ul>
4061 <ul>
4041 <li><a href="/shortlog">log</a></li>
4062 <li><a href="/shortlog">log</a></li>
4042 <li><a href="/graph">graph</a></li>
4063 <li><a href="/graph">graph</a></li>
4043 <li><a href="/tags">tags</a></li>
4064 <li><a href="/tags">tags</a></li>
4044 <li><a href="/bookmarks">bookmarks</a></li>
4065 <li><a href="/bookmarks">bookmarks</a></li>
4045 <li><a href="/branches">branches</a></li>
4066 <li><a href="/branches">branches</a></li>
4046 </ul>
4067 </ul>
4047 <ul>
4068 <ul>
4048 <li><a href="/help">help</a></li>
4069 <li><a href="/help">help</a></li>
4049 </ul>
4070 </ul>
4050 </div>
4071 </div>
4051
4072
4052 <div class="main">
4073 <div class="main">
4053
4074
4054 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
4075 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
4055 <h3>error</h3>
4076 <h3>error</h3>
4056
4077
4057
4078
4058 <form class="search" action="/log">
4079 <form class="search" action="/log">
4059
4080
4060 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
4081 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
4061 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
4082 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
4062 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
4083 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
4063 </form>
4084 </form>
4064
4085
4065 <div class="description">
4086 <div class="description">
4066 <p>
4087 <p>
4067 An error occurred while processing your request:
4088 An error occurred while processing your request:
4068 </p>
4089 </p>
4069 <p>
4090 <p>
4070 Not Found
4091 Not Found
4071 </p>
4092 </p>
4072 </div>
4093 </div>
4073 </div>
4094 </div>
4074 </div>
4095 </div>
4075
4096
4076
4097
4077
4098
4078 </body>
4099 </body>
4079 </html>
4100 </html>
4080
4101
4081 [1]
4102 [1]
4082
4103
4083 $ killdaemons.py
4104 $ killdaemons.py
4084
4105
4085 #endif
4106 #endif
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now